Github
PSGallery
Dependency update canaries for PSDepend, PowerShellBuild, and psake projects.
PSDependencyCanary is an add-on for PowerShell module projects built with PSDepend, PowerShellBuild, and psake. It supplies a shared psake Canary task that first runs the project's current Test task as a baseline. Only a passing baseline proceeds to update the declarations, bootstrap the complete candidate environment, and run the same test task again before retaining any dependency changes.
Those tools are the supported project model, not optional adapters. PSDependencyCanary intentionally standardizes dependency declaration, bootstrap, build, and test orchestration around that ecosystem instead of abstracting arbitrary build systems.
requirements.psd1 defines the complete build and test environment. Every module listed in the shipped manifest's RequiredModules must also be present in requirements.psd1, allowing the canary to install and test a reproducible environment. Runtime dependency updates are written to both files at the same validated version.
Candidate file edits preserve the layout of requirements.psd1 and the module manifest. A failed baseline makes no candidate edits. A failed candidate bootstrap or test restores the original files. -WhatIf reports available updates without bootstrapping, testing, or editing.
Build-only dependency updates change only requirements.psd1. They do not change the shipped module version. An update to RequiredModules changes the source manifest, patch-bumps ModuleVersion, and adds the corresponding changelog release.
Install-PSResource -Name PSDependencyCanaryFor Windows PowerShell 5.1:
Install-Module -Name PSDependencyCanaryThe supported project contract is:
build.ps1accepts-Task <name>and-Bootstrap.- PowerShellBuild provides the project's
Testtask and returns a failing exit code when the build, analysis, or tests fail. -Bootstrapinstalls and imports the exact versions inrequirements.psd1.- The source manifest is at
src/<ModuleName>/<ModuleName>.psd1. For another layout, set the shared task'sPSDependencyCanaryModuleManifestPathproperty. - Every module in the manifest's
RequiredModulesis also pinned inrequirements.psd1.
Add PSDependencyCanary to the existing requirements.psd1:
@{
PSDepend = @{ Version = '0.4.1' }
PowerShellBuild = @{ Version = '0.8.2' }
PSDependencyCanary = @{ Version = '1.1.0' }
# Existing build, test, and runtime dependencies belong here too.
Pester = @{ Version = '6.0.1' }
PSDependOptions = @{ Target = 'CurrentUser' }
}Add the shared task to the existing psakeFile.ps1:
Task Test -FromModule PowerShellBuild -MinimumVersion '0.8.2'
Task Canary -FromModule PSDependencyCanary -MinimumVersion '1.1.0'The shared task exposes paths and optional output features through psake properties:
| Property | Default | Purpose |
|---|---|---|
PSDependencyCanaryProjectRoot |
BHProjectPath, then the current directory |
Project containing the build entry point. |
PSDependencyCanaryModuleManifestPath |
Auto-discovered under src |
Source module manifest. |
PSDependencyCanaryRequirementsPath |
requirements.psd1 |
Complete PSDepend environment. |
PSDependencyCanaryChangelogPath |
CHANGELOG.md |
Changelog updated for runtime dependency changes. |
PSDependencyCanaryResultPath |
out/dependency-canary.json |
Structured task result for CI. |
PSDependencyCanarySkipChangelog |
$false |
Patch-bump runtime updates without requiring or changing a changelog. |
PSDependencyCanarySkipResult |
$false |
Return the task result without writing a JSON result file. |
The changelog is required only when a runtime dependency changes and changelog updates are enabled. Configure a different location or explicitly disable that feature:
$properties = @{
PSDependencyCanaryChangelogPath = './docs/CHANGE_LOG.md'
}
./build.ps1 -Task Canary -Properties $properties
# Or patch-bump runtime updates without a changelog:
$properties = @{
PSDependencyCanarySkipChangelog = $true
}
./build.ps1 -Task Canary -Properties $propertiesThen schedule these commands in CI:
# Run in a dedicated process or CI step. The command removes all installed
# versions of the project's declared dependencies and this temporary module,
# while preserving Pester 3.x.
Install-Module PSDependencyCanary -MinimumVersion 1.1.0 -Scope CurrentUser -Force
Import-Module PSDependencyCanary -MinimumVersion 1.1.0 -Force
PSDependencyCanary\Clear-PSDependencyCanaryEnvironment -ProjectRoot . -Confirm:$false
# Run in a fresh process or CI step and install the currently committed pins.
./build.ps1 -Task Init -Bootstrap
# Baseline-test, stage updates, rebootstrap, and test the candidate.
./build.ps1 -Task CanaryThe shared task writes out/dependency-canary.json by default. A CI promotion step should require BaselineTested, Tested, and Applied before committing a changed candidate:
$result = Get-Content -Raw out/dependency-canary.json | ConvertFrom-Json
if ($result.Changed -and (-not $result.BaselineTested -or -not $result.Tested -or -not $result.Applied)) {
throw 'The unchanged project and dependency candidate were not both validated.'
}Clear-PSDependencyCanaryEnvironment is intended for disposable CI runners; use
-WhatIf before running it in a persistent development environment. Copyable pipeline examples are available for:
- GitHub Actions, which can be copied to
.github/workflows/canary.ymland includes automatic pull-request creation - GitLab CI, producing a validated patch artifact
- Azure Pipelines, producing a validated patch artifact
The patch-artifact examples leave repository writes to a separate protected job. Applying the generated dependency-canary.patch reproduces the exact candidate that passed Canary.