-
-
Notifications
You must be signed in to change notification settings - Fork 59
Persistent Builds
Long running or interactive workflows with expected interruptions can be automated with persistent builds which allow resuming after interruptions.
In order to make a build persistent use the parameter Checkpoint
with a path
to the checkpoint file. The file is written after each completed task and
removed after not interrupted builds.
For example, this command starts a persistent build with the default initial task and the default script:
Invoke-Build -Checkpoint checkpoint.clixml
In order to resume an interrupted build use the same parameter Checkpoint
with an existing file which was created by a previously interrupted build and
specify the switch Resume
. In fact, the switch simply can be added to the
command that started this build. The initial tasks, the script and its
parameters, if any, are all ignored, their values are restored from the
checkpoint file.
For example, this command resumes a build from the checkpoint file:
Invoke-Build -Checkpoint checkpoint.clixml -Resume
If a persistent build fails and it is not going to be resumed then the created checkpoint file, if any, should be removed manually. Otherwise, there is a little chance that it can be eventually used for resuming unintentionally.
Example. A persistent build fails at the very first task. In this case resuming does not make much sense, the build should be simply invoked again. Thus, the checkpoint file is not written. As far as it is not written, it cannot be used for resuming by mistake, it does not exist ... unless it was created by an old build and not removed, as recommended.
Scripts which do not set data shared between tasks, like script variables, global variables, etc. are ready for persistent builds unless they deal with something that may change between stopping and resuming in a way not suitable for resuming.
Scripts which deal only with script scope variables set by tasks and used by other tasks may make these variables persistent simply by declaring them as script parameters, even if they are not actually used as parameters. Script parameters are persistent because the engine takes care of this.
If nothing of the above is applicable then a script should define the functions
Export-Build
and Import-Build
which maintain persistence of required states.
Export-Build
is called after each task of a persistent build. It outputs data
to be exported to a checkpoint file. Import-Build
is called once on resuming.
Its single argument contains the original data imported from a checkpoint file.
It is called in the script scope, so that for restoring script scope variables
it does not have to use the prefix script
.
For example, a script uses two variables $Version
and $Archive
which are
calculated by the task SetVariables:
# It is a good idea to declare them always, for Set-StrictMode or to hide
# existing in parent scopes and avoid export/import of irrelevant data
$Version = $null
$Archive = $null
task SetVariables {
$script:Version = ...
$script:Archive = ...
}
Other tasks reference this task and use these variables assuming they are set.
If a persistent build is interrupted after SetVariables then on resuming the
build the variables will not be set for those tasks. Export-Build
and
Import-Build
solve this problem:
function Export-Build {
$Version
$Archive
}
function Import-Build {
$Version, $Archive = $args[0]
}
As mentioned before, in this particular case it is possible and perhaps better
to make $Version
and $Archive
persistent by declaring them as parameters:
param(
# really used parameters
$Platform,
...
# just for persistence
$Version,
$Archive
)
This is it, if there is nothing else to persist then custom export and import functions are not needed, persistence of parameters is performed by the engine.
- Think carefully of what the persistent build state is.
- Some data are not suitable for persistence in clixml files.
- Changes in stopped build scripts may cause incorrect resuming.
- Checkpoint files must not be used with different engine versions.
- Concepts
- Script Tutorial
- Incremental Tasks
- Partial Incremental Tasks
- How Build Works
- Special Variables
- Build Failures
- Build Analysis
- Parallel Builds
- Persistent Builds
- Portable Build Scripts
- Using for Test Automation
- Debugging Tips
- VSCode Tips
Helpers
- Invoke Task from VSCode
- Generate VSCode Tasks
- Invoke Task from ISE
- Resolve MSBuild
- Show Build Trees
- Show Build Graph
- Argument Completers
- Invoke-Build.template
Appendix