Skip to content

Capabilities

Capabilities

Every custom operation on the four builders, every Input combinator, and the Cmd argument helpers — one line each. Use it to find the name; the API reference has the full signature and remarks for each, and Composing reusable blocks has worked examples.

How settings resolve

A stage setting is answered by walking upward: the stage itself, then its parent stage, then the parent's parent, then the pipeline. The first level that set the thing wins, so workingDir on a pipeline covers every stage under it and a nested stage overrides it for itself and its own children. This applies to workingDir, envVars, the timeouts, acceptExitCodes, the output sink, noPrefixForStep, noStdRedirectForStep and verbosity.

Conditions are the exception. when', whenEnvVar, whenBranch and the platform operations conjoin: a second condition on the same stage narrows it to the logical AND of both. Use whenAny { } to widen.

A command's copies of the pipeline settings are defaults, not overrides: they reach every pipeline the command runs, but only where that pipeline left the setting alone, whichever order the two were written in. noPrefixForStep and noStdRedirectForStep are plain bools with no unset state: a pipeline setting either one to the same value PipelineContext.create already gives it reads back identically to a pipeline that never touched it, so the command default overwrites it in that case too.

Timeouts

Three names, and their meaning shifts with the builder they sit on.

BuildertimeouttimeoutForStagetimeoutForStep
stagethis stage as a wholeeach step of this stage
pipelinethe whole pipeline runeach stage's defaulteach step's default
command / rootCommandpipeline default for the whole runpipeline default for each stagepipeline default for each step

All three accept int<second>, float seconds, or a TimeSpan, except on command, which takes int seconds or a TimeSpan.

Stage operations

Available inside stage, and inside whenStage, which accepts everything stage does.

OperationWhat it does
runAdds a step. Takes a literal command line, a Cmd, or a function of the StageContext returning unit, int, Result<unit, string>, a Cmd, an Async<_> or a Task<_> of any of those, optionally wrapped in option
runSensitiveAdds a step from an interpolated command line with every hole masked as *** wherever the library prints it
runHttpHealthCheckAdds a step that polls a URL until it answers or the stage is cancelled
echoAdds a step that prints a message through the stage's output sink
when'Runs the stage only when a bool holds, or only when a given StageContext succeeds
whenEnvVarRuns the stage only when an environment variable is set, or set to a given value; also takes an EnvArg
whenBranch / whenBranchesRuns the stage only on the named git branch. Reads git branch --show-current in the stage's working directory; a missing git evaluates false rather than throwing
whenWindows / whenLinux / whenOSXRuns the stage only on that platform. Pass false to invert
whenPlatformThe same over an OSPlatform value
workingDirThe directory this stage's child processes start in. Takes a string or a DirectoryInfo
envVarsEnvironment variables for this stage's child processes. Applied to ProcessStartInfo, so the host process's own environment is untouched
timeoutCancels the stage after the given duration
timeoutForStepCancels any one step of the stage after the given duration
retryRuns the stage's steps again after a failing attempt, up to the given count. timeout remains the budget for the whole stage, retries included
parallel'Runs the stage's steps concurrently. true/0/-1 unbounded, 1/false sequential, n throttled to exactly n in flight; also takes a StageContext -> _ condition
acceptExitCodesThe exit codes that count as success. Replaces the default [0]
failIfIgnoredFails the pipeline when this stage is inactive, instead of skipping it
failIfNoActiveSubStageFails the pipeline when none of this stage's sub-stages is active
continueStepsOnFailureRuns the remaining steps after one fails
continueStageOnFailureRuns the remaining stages after this one fails
continueOnStepFailureBoth of the above at once
outputToSends this stage's step output to a StageOutputConsole, Silent, Captured or Redirect
silentOutputDrops this stage's step output. A failure still reports its exit code
captureOutputHolds this stage's step output back and lifts it into the error message when a step fails. Takes an optional OutputCapture to keep the lines either way
redirectOutputHands each line to StdStream -> string -> unit as it arrives, from both streams' reader threads
noPrefixForStepStops each step's output being prefixed with its stage and step index
noStdRedirectForStepStops redirecting the child's stdout/stderr — the mechanism every output operation above depends on — and overrides all of them
shuffleExecuteSequenceRandomises step order at each run
verbosityHow much of the pipeline's own log this stage prints. Takes Verbosity.Quiet, Normal or Verbose
verbose / quietverbosity Verbose and verbosity Quiet

A stage nested inside another stage is one step of its parent. Stages nest to any depth, and a block is just a value that a stage, a pipeline or a command can yield.

Pipeline operations

Available inside pipeline "name" { } and inside Command.pipeline { }, which takes the name and description of the command that runs it.

OperationWhat it does
descriptionThe pipeline's description. Discarded in Command.pipeline { }, which always takes the command's own name and description instead
timeoutCancels the whole pipeline after the given duration
timeoutForStageThe default timeout of each stage
timeoutForStepThe default timeoutForStep of each stage
workingDirThe default working directory of every stage. Takes a string or a DirectoryInfo
envVarsEnvironment variables every stage inherits. Appends to the pipeline's map rather than replacing it
acceptExitCodesThe exit codes that count as success. Replaces the default [0]
outputToThe default output sink of every stage
silentOutputDrops every stage's step output
captureOutputHolds every stage's step output back, lifting it into the error message on failure
redirectOutputHands every line of step output to StdStream -> string -> unit
noPrefixForStepStops step output being prefixed with the stage and step index
noStdRedirectForStepStops redirecting child stdout/stderr
runBeforeEachStageA StageContext -> unit hook run before each stage. Replaces the previous hook
runAfterEachStageA StageContext -> unit hook run after each stage. Replaces the previous hook
postThe stages that run after the main stages whether or not the pipeline succeeded — the teardown slot. Replaces any post stages already declared
verbosityHow much the pipeline prints. Takes Verbosity.Quiet, Normal or Verbose
verbose / quietverbosity Verbose and verbosity Quiet

Command operations

Available inside command "name" { } and rootCommand argv { } / rootCommandOfScript { }, except for the three marked as root-only.

OperationWhat it does
descriptionThe command's description, shown in help
alias / aliasesAlternative names for the command. These accumulate
hiddenKeeps the command out of help output
addCommand / addCommandsAdds subcommands. Yielding a Command value does the same
addInput / addInputsRegisters an option or argument no pipeline asks for. Options a stage binds are registered already
timeoutPipeline default: the whole run. Takes int seconds or a TimeSpan
timeoutForStagePipeline default: each stage. Takes int seconds or a TimeSpan
timeoutForStepPipeline default: each step. Takes int seconds or a TimeSpan
workingDirPipeline default: the directory commands run in
envVarsPipeline default, per key: a pipeline that sets one of these keys itself keeps its own value and the rest still apply
acceptExitCodesPipeline default: the exit codes that count as success
outputTo / silentOutput / captureOutput / redirectOutputPipeline default: where step output goes
noPrefixForStep / noStdRedirectForStepPipeline default: prefixing and child stream redirection
runBeforeEachStage / runAfterEachStagePipeline default: the per-stage hooks
postPipeline default: the teardown stages
verbosity / verbose / quietPipeline default: how much the pipeline prints
nameRoot only. What the root command calls itself in help and usage. Defaults to the script's filename
parserConfigurationRoot only. A System.CommandLine ParserConfiguration
invocationConfigurationRoot only. A System.CommandLine InvocationConfiguration

A command yields stages directly — command "test" { Stages.restore; Stages.test } — and consecutive stages become one implicit pipeline carrying the command's name and description. Command.pipeline { } is the same pipeline written out, for when it needs the pipeline-level settings; pipeline "name" { } is for when several pipelines run under one command, or when one needs a name of its own.

Condition builders

whenAll { }, whenAny { } and whenNot { } take these; each yields a single condition to a stage. An empty whenAll/whenNot is always active, an empty whenAny never is.

OperationWhat it does
when'A bool, or a StageContext that must succeed
envVarAn environment variable by name, by name and value, or as an EnvArg
branch / branchesThe current git branch
platformWindows / platformLinux / platformOSXThe running platform. Pass false to invert
platformThe same over an OSPlatform value

whenEnv { } describes one environment variable in place of a wall of overloads, with name, description, value, acceptValues and optional. whenStage "name" { } runs a stage for its result — everything stage accepts is accepted there, and the stage runs for real, side effects included.

whenSome value build and whenOk value build are functions rather than operations. Each returns a StageContext list: the stage built from the bound value, or []. The absent case is an empty list, not an inactive stage requiring a name. build receives the value already unwrapped, inside the condition that guards it.

Input combinators

Declaring functions:

FunctionWhat it makes
Input.option<'T> "--name"An option bound as 'T
Input.optionMaybe<'T> "--name"An option bound as 'T option, None when absent
Input.argument<'T> "name"A positional argument bound as 'T
Input.argumentMaybe<'T> "name"A positional argument bound as 'T option
Input.contextInjects the ActionContext — the ParseResult and a cancellation token
Input.inject valueInjects a value that is not parsed from the command line
Input.ofOption / Input.ofArgumentLifts a raw System.CommandLine Option<'T> / Argument<'T>

Shaping combinators, all ActionInput<'T> -> ActionInput<'T> and all pipeable:

FunctionWhat it does
Input.alias / Input.aliasesAdds alternative names. Options only
Input.description, Input.descThe help text
Input.helpNameThe value placeholder in help — <Debug\|Release>
Input.defaultValue, Input.defThe value used when the token is absent
Input.defaultValueFactoryThe same, computed from the ArgumentResult
Input.arityHow many values are accepted: ExactlyOne, OneOrMore, Zero, ZeroOrMore, ZeroOrOne, or ArgumentArity (min, max)
Input.requiredMarks an option required
Input.recursiveApplies the option to the command and, recursively, its subcommands
Input.hiddenKeeps it out of help output
Input.allowMultipleArgumentsPerTokenLets one identifier token carry several values
Input.acceptOnlyFromAmongRestricts to a set of legal strings, ordinally
Input.mapFromAmong<'T> [ "key", value ]An option over a known set, each key bound to a typed value
Input.mapFromAmongWith<'T> comparermapFromAmong under an explicit StringComparer
Input.mapFromMany / mapFromManyWithThe repeatable forms, binding 'T list
Input.acceptLegalFileNamesOnly / Input.acceptLegalFilePathsOnlyRestricts to legal file names / paths
Input.validateA 'T -> Result<unit, string> check; Error becomes a CLI validation message
Input.validateFileExists / Input.validateDirectoryExistsThe two common cases, over FileInfo / DirectoryInfo
Input.addValidatorA raw SymbolResult -> unit validator
Input.customParserAn ArgumentResult -> 'T parser
Input.tryParseAn ArgumentResult -> Result<'T, string> parser; Error becomes a parse diagnostic instead of an exception
Input.editOption / Input.editArgumentReaches the underlying Option<'T> / Argument<'T> for anything not covered above

InputSpec<'T>

InputSpec<'T> is public at Partas.Build. A stage factory parameterised by an option needs no open Partas.Build.Internal:

let build (projects: InputSpec<string list>) = input {
    let! projects = projects
    and! config = Options.config
    ...
}
FunctionWhat it does
InputSpec.ofInputLifts an ActionInput<'T> into a spec
InputSpec.retA spec that reads nothing and returns a constant
InputSpec.mapReshapes the value a spec reads
InputSpec.map2Combines two specs, unioning their inputs
InputSpec.sequenceA list of specs into one spec of a list
InputSpec.traversesequence over the results of a mapping
InputSpec.unionConcatenates input lists, keeping the first occurrence of each

The input { let! … and! … return … } CE is the usual way to build one. It is applicative: bind every source in a single let!/and! group. A sequential second let! is a compile error (FS0708) because the input set has to be readable before anything is parsed. An input { } nested inside another's return produces an InputSpec<InputSpec<_>>, which nothing accepts — pass the source in as an InputSpec instead.

Cmd

A Cmd keeps the executable and its arguments apart all the way to ProcessStartInfo.ArgumentList, so the platform does the escaping.

FunctionWhat it does
cmd $"dotnet build {project}"Each hole becomes exactly one argument, whatever it contains. run $"..." binds to the string overload and flattens the holes, so interpolate through cmd
Cmd.ofStringSplits a whole command line, honouring " and '
Cmd.create exe argsThe executable exactly as given, plus an argument string split as ofString does
Cmd.ofList exe argsBoth exactly as given
Cmd.arg / Cmd.argsAppends arguments exactly as given
Cmd.argIf cond valuesAppends only when cond holds — one line instead of two whole command lines under an if
Cmd.argWhenSome value renderAppends the arguments rendered from a Some, and nothing from a None
Cmd.secretArgAppends one argument whose value is masked wherever the command is printed
Cmd.secretOption flag valueAppends a visible flag and a masked value: -k ***
Cmd.secretOptionWhenSome flag valueThe same when the value exists, appending nothing otherwise
Cmd.secret / Cmd.sensitiveMarks a string unprintable before it goes into a cmd hole
Cmd.ofFormattable secretThe interpolation reader behind cmd and runSensitive
Cmd.toLogStringHow the command prints: secrets masked, whitespace-carrying arguments quoted

Args

The arguments a script was given, as distinct from the ones its host was given.

FunctionWhat it answers
Args.script ()The running script's own arguments. rootCommandOfScript { } is rootCommand (Args.script ()) { }
Args.scriptName ()The running script's filename, when it was launched as one
Args.afterScript argvEverything after the .fsx in argv, or after argv[0] when there is none. A leading -- is dropped
Args.take argvEverything after the first --
Args.nameOf argvThe filename of the first .fsx in argv

dotnet fsi build.fsx -- test --quick does not reach the process with its -- intact: the dotnet driver consumes one before fsi sees the command line. Args.script locates the script's own filename instead of splitting on a separator.

Baked

Ready-made declarations for the options every build CLI ends up wanting. Baked.Input.* are options, Baked.Argument.* the positional equivalents.

ValueWhat it declares
Baked.Input.NuGet.apiKey--nuget-key (alias --nuget) as string option
Baked.Input.NuGet.apiKeyOrEnvThe same, defaulting to the NUGET_API_KEY environment variable
Baked.Input.DotNet.config--configuration (alias -c) as Configuration option, restricted to Debug/Release
Baked.Input.DotNet.configStringThe same as string option
Baked.Input.Versioning.bump--bump as Bump option, over major\|minor\|patch\|alpha\|beta\|rc\|preview\|<SEMVER>, defaulting to Patch
Baked.Input.Project.target targets--project (alias -p) as string list, restricted to targets
Baked.Input.CI.isCI--ci, defaulting to true when any of the usual CI environment variables is set
FunctionWhat it does
Baked.Version.apply bump versionSemantic version arithmetic over a Bump
Baked.Version.assembly versionThe assembly version that goes with a package version: its major, and nothing else
Baked.IO.writeVersion / Baked.IO.setVersionRewrites <Version> and <AssemblyVersion> in a project file
Baked.IO.bumpVersion projPath bumpApplies a bump to a project file in place, answering the versions before and after
Baked.Pipelines.bumpArgument allProjects projectsA bump stage taking the bump kind as a positional argument
Baked.Pipelines.bumpOption allProjects projectsThe same with the bump kind as --bump

Reference

Edit this page