psake 5.x spike: assess breakage under psake 5.0.4 (clean bump, no extras) #155
Description
Part of #120 (Phase 2 — psake 5.x bump).
Question
What actually breaks under psake 5.x, and does the damage stay inside this repository or reach consumers?
Two psake files are in play and they carry very different risk:
psakeFile.ps1at the repo root — this repo's own build. Breakage here is ours to fix.PowerShellBuild/psakeFile.ps1— the consumer-facing task definitions that every downstreambuild.ps1dot-sources. Breakage here is a breaking change for everyone.
Scope
Keep this spike clean. requirements.psd1 currently pins psake = '4.9.0'; PSGallery is at 5.0.4. Bump the pin, run the build, record what happens.
Explicitly out of scope for the spike — these are what sank the previous attempt (#117, closed): task caching via Inputs/Outputs, LLM-mode Pester output, external PesterConfiguration file support, and the new public Format-PSBuildResult function. Those are 1.1.0 features, not a dependency bump.
Known reproducer
psake 5.0.4 installed side by side with the pinned 4.9.0 already shadows it on at least one maintainer machine and fails Manifest.tests.ps1. That failure is a starting point, not necessarily the whole story — confirm whether it is a genuine 5.x incompatibility or an artifact of two psake versions being visible at once.
Abort criterion (agreed before the spike, deliberately)
- Migrate if the consumer-facing
PowerShellBuild/psakeFile.ps1survives 5.x with only mechanical changes. - Cut psake 5.x to 1.1.0 and ship 1.0.0 on psake 4.9.0 if 5.x forces a change to the task names or the
$PSBPreferencecontract that consumers'build.ps1files depend on.
This criterion is fixed in advance so the call is made on the findings rather than on sunk cost. Record which side the spike landed on, with evidence, as the resolution comment.
Done when
The findings are posted here and the migrate/cut call is made. Migration PR(s) are then created as follow-ups — their number and shape depend on what this spike finds, so they are deliberately not charted yet.
Activity
tablackburn commentedon Aug 20, 2026
Spike result: MIGRATE
Ran the clean bump (no #117 extras). Under the abort criterion agreed before the spike, the
consumer-facing
PowerShellBuild/psakeFile.ps1survives psake 5.0.4 with zero changes —no task renames, no
$PSBPreferencechange. So psake 5.x stays in v1.0.0.Method
requirements.psd1pinspsake = '4.9.0'; PSGallery is at 5.0.4. Rather than swap the pin(which leaves the other version visible and shadowing), each run used an isolated module root
prepended to
PSModulePath, so exactly one psake version was resolvable — verified for theparent session and for
Start-Jobchildren, which matters becausebuild.tests.ps1andIBTasks.tests.ps1spawn child builds.Checked against the official guide
psake/psake docs/migration-v4-to-v5.mdlists four breaking changes. None apply here:
default.ps1no longer auto-detected — we pass-buildFile ./psakeFile.ps1explicitlypsake.ps1/psake.cmdremoved — we already useImport-Module psake+Invoke-psakeFrameworkcalls anywhere$frameworkglobal removed — not usedThe only
$framework/config_defaultmatches in the repo are a local function parameter anda string literal inside
Build/Convert-PSAke.ps1, an unrelated psake→Invoke-Build converter.OutputHandler/ColoredOutput/psake-config.ps1are likewise unused.The guide also confirms two things the spike measured directly:
$psake.build_successisexplicitly still supported, and
Invoke-psakenow returns aPsakeBuildResult.API surface: a superset, no removals we touch
Taskkeeps every v4 parameter and addsDefinition;PropertiesaddsHashtable;FormatTaskName,Get-PSakeScriptTasks -BuildFile, andInvoke-Psake's-BuildFile/-TaskList/-NoLogo/-Parametersare unchanged. Verified working under 5.0.4:$psake.context.currentTaskName— used atPowerShellBuild/psakeFile.ps1lines 178, 201, 213$psake.context.Peek().Tasks.Keys— line 381$psake.build_success—build.ps1, andtests/TestModule/build.ps1(the consumer simulation)Renamed but unused by this repo:
Exec→Execute,-notr→-NoTimeReport, andInclude'sfileNamePathToInclude→Path/LiteralPath. (TheInclude = ...hits inpsakeFile.ps1andBuild-PSBuildModule.ps1areCopy-Itemhashtable keys, not the psakekeyword.)
The 12 failures: one latent bug in our own test file
All 12 came from a single container,
tests/Manifest.tests.ps1, failing with:Root cause, isolated to a two-file reproducer:
Set-BuildEnvironment -ForceinBeforeAll.BuildHelpers'
Get-BuildVariableusesbreakinsideswitchblocks; called from a PesterBeforeAll, that break unwinds out of the block. psake 4.9.x's call structure absorbs it,psake 5.0.4's (
Invoke-BuildPlan.ps1,& $task.Action) does not, so Pester fails the container.This is not documented in the upstream migration guide — worth reporting to BuildHelpers,
and worth knowing for any consumer whose Pester tests call
Set-BuildEnvironment.Fix is one line —
build.ps1already callsSet-BuildEnvironment -ForcebeforeInvoke-psake,so the call inside
BeforeAllis redundant during a build:A dummy enclosing loop (
foreach ($once in 1) { ... }) does not absorb it — tested andrejected. Committed on
spike/psake-5x(
5ec9a01) for the migration PR to pick up. StandaloneInvoke-Pesterwith a clearedenvironment still passes 10/0, so the guard does not break out-of-build runs.
One consumer-visible behavior change
Invoke-psakenow emits aPsakeBuildResultto the pipeline (Success,Duration,Tasks,ErrorMessage, ...) where v4 emitted nothing. Any consumer whosebuild.ps1assigns or pipesthe result of
Invoke-psakegets an object that was not there before. Ours ignores it, so thisis a migration-guide entry, not a code change.
Not attempted, by design
Task caching (
Inputs/Outputs), LLM Pester output, externalPesterConfigurationfilesupport, and
Format-PSBuildResult— the #117 extras. They stay out of v1.0.0.Follow-up
Migration work is now specifiable and is filed as #161. Given the consumer-facing psakeFile
needs no changes, it is a single small PR, not a chain.
tablackburn commentedon Aug 20, 2026
Resolved: MIGRATE. psake 5.x stays in v1.0.0 — the consumer-facing psakeFile needs no changes. Findings and evidence in the resolution comment above; migration work filed as #161.
docs: Drop the changelog and migration-guide entries for the psake bump
chore: Move the build toolchain to psake 5.0.4 (#162)