Uh oh!
There was an error while loading. Please reload this page.
[1.0.0-alpha1] Upgrade to psake 5.0.0 with task caching and LLM output - #117
[1.0.0-alpha1] Upgrade to psake 5.0.0 with task caching and LLM output#117HeyItsGilbert wants to merge 3 commits into
Conversation
Breaking changes: - Minimum PowerShell raised from 3.0 to 5.1 - psake dependency raised from 4.9.0 to 5.0.0 - Invoke-psake now returns PsakeBuildResult (replaces $psake.build_success) New features: - Content-addressed task caching via Inputs/Outputs on cacheable tasks (StageFiles, Analyze, Pester, GenerateMarkdown, GenerateMAML, GenerateUpdatableHelp) - LLM-optimized test output mode ($PSBPreference.Test.OutputMode = 'LLM') emits structured JSON with only failure details - External PesterConfiguration file support via $PSBPreference.Test.PesterConfigurationPath - Direct PesterConfiguration object passthrough via -Configuration parameter - Format-PSBuildResult function for Human/JSON/GitHubActions build result formatting - All psakeFile.ps1 tasks rewritten to declarative hashtable syntax - Invoke-Build IB.tasks.ps1 updated with matching Inputs/Outputs caching - Windows PowerShell 5.1 CI matrix entry added Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Updated the GitHub Actions workflow to specify 'main' branch for push events, enabled fail-fast strategy, and added a separate job for testing with PowerShell on Windows. Signed-off-by: Gilbert Sanchez <me@gilbertsanchez.com>
Signed-off-by: Gilbert Sanchez <me@gilbertsanchez.com>
| name: Test | ||
| runs-on: windows-latest | ||
| strategy: | ||
| fail-fast: true | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Test | ||
| shell: powershell | ||
| env: | ||
| DEBUG: ${{ runner.debug == '1' }} | ||
| run: | | ||
| if($env:DEBUG -eq 'true' -or $env:DEBUG -eq '1') { | ||
| $DebugPreference = 'Continue' | ||
| } | ||
| ./build.ps1 -Task Test -Bootstrap |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium test
Show autofix suggestionHide autofix suggestion
Copilot Autofix
AI 5 months ago
To fix the problem, explicitly declare the GITHUB_TOKEN permissions in the workflow using the permissions key, granting only the minimal scopes required. Since these jobs just check out code and run tests/build via build.ps1 and do not interact with issues, pull requests, or modify repository contents, they can typically operate with contents: read only.
The best way to fix this without changing existing functionality is to add a top-level permissions block to .github/workflows/test.yml (so it applies to all jobs) with contents: read. This documents the workflow’s intent and ensures least-privilege defaults if org or repo settings change later. Concretely, insert:
permissions:
contents: readbetween the on: block and the jobs: block (i.e., after line 6 and before line 7). No additional imports or methods are needed, as this is purely a YAML configuration change within the workflow file.
| @@ -4,6 +4,8 @@ | ||
| branches: [ main ] | ||
| pull_request: | ||
| workflow_dispatch: | ||
| permissions: | ||
| contents: read | ||
| jobs: | ||
| test: | ||
| name: Test |
## Summary - Move this repository's build toolchain from psake 4.9.0 to **5.0.4** in `requirements.psd1` - Guard the `Set-BuildEnvironment` call in `tests/Manifest.tests.ps1`, without which psake 5.x fails the whole test container and the suite silently loses 12 tests - Deliberately **no** changelog or migration-guide entry — nothing here is user-facing Two files, +7 −2. Scope and shape come from the #155 spike, which found this is a single small PR rather than a chain. Closes#161. ## What did *not* change, deliberately **The manifest's `RequiredModules` floor stays at `psake` 4.9.0.** PowerShellBuild's task definitions are unchanged and run on both majors — task names, task dependencies, and the `$PSBPreference` contract are identical under 5.0.4 — so raising the floor would force an upgrade on consumers for no functional gain. This mirrors the Pester decision recorded in #120 (`RequiredModules` stayed at 5.6.1 for the same reason). **No changelog or migration-guide entry.** `requirements.psd1` is this repository's own build toolchain, not anything a consumer touches, and because the manifest floor is unchanged, upgrading PowerShellBuild 0.8.x → 1.0.0 does not move anyone to psake 5.x. The psake 5.x behavior differences are triggered by upgrading *psake*, and [psake's own v4 → v5 guide](https://github.com/psake/psake/blob/main/docs/migration-v4-to-v5.md) is their proper home. If a later change raises the manifest floor to psake 5.x, that change adds the migration entry, where it will be correct. (Recorded as the "Changelog and guide scope" decision on #120.) Also out of scope, per #155: psake 5.x's `Version 5` declaration and `Properties @{}` hashtable syntax are available but not adopted here, and none of the #117 extras (task caching, LLM output, `Format-PSBuildResult`) come along. ## The test guard `tests/Manifest.tests.ps1` called `Set-BuildEnvironment -Force` in `BeforeAll`. BuildHelpers' `Get-BuildVariable` uses `break` inside `switch` blocks, and that `break` can unwind out of the block. psake 4.9.x's task invocation absorbs it; **psake 5.x's does not**, so Pester fails the entire container ([pester/Pester#2669](pester/Pester#2669)) and the suite silently drops from 428 to 418 passing. `build.ps1` calls `Set-BuildEnvironment -Force` unconditionally before `Invoke-psake` (`build.ps1:56`), so by the time this `BeforeAll` runs the variables are already set and the second call is redundant. Guarding on that makes it short-circuit during a build, so the escaping `break` never fires. The complete change to `tests/Manifest.tests.ps1`: ```powershell BeforeAll { # Only call Set-BuildEnvironment when the build variables are not already present. # build.ps1 sets them before Invoke-psake, so inside a build this is a no-op; standalone # Pester runs still get them. Calling it unconditionally lets an escaping 'break' from # BuildHelpers' Get-BuildVariable switch blocks unwind out of this BeforeAll, which # psake 4.9.x absorbs but psake 5.x does not -- Pester then fails the whole container. if (-not $env:BHProjectName) { Set-BuildEnvironment -Force } ... ``` `build.ps1` itself is **not** modified by this PR. A dummy enclosing loop does *not* absorb the break — tested and rejected. This interaction is **not documented upstream**. It stays recorded where it is actionable: the comment above, and the full spike findings in #155. Worth reporting to BuildHelpers separately. ## Test Plan - [x] Full suite under psake **5.0.4** — 428 passed / 0 failed - [x] Full suite under psake **4.9.1** — 428 passed / 0 failed (backs the "consumers are not forced to upgrade" claim; the manifest still allows 4.9.x) - [x] Standalone `Invoke-Pester` on `tests/Manifest.tests.ps1` with a cleared environment — 10 passed / 0 failed, so the guard does not break out-of-build runs - [x] CI green on all legs, including **`CI / Run Tests (Windows PowerShell 5.1)`** — the one thing that could not be verified locally, since the spike ran on pwsh 7.6.5/Windows only and 5.1 is a supported v1.0.0 floor - [x] All four breaking changes in psake's v4 → v5 guide checked against this repo; none apply (`default.ps1` auto-detection — we pass `-buildFile` explicitly; the `psake.ps1`/`psake.cmd` launchers — we use `Import-Module` + `Invoke-psake`; .NET Framework < 4.0 and the `$framework` global — unused) Each local run used an isolated module root prepended to `PSModulePath` so exactly one psake version was resolvable — verified for `Start-Job` children too, since `build.tests.ps1` and `IBTasks.tests.ps1` spawn child builds. To reproduce the failure this fixes, revert `tests/Manifest.tests.ps1` and run the suite under psake 5.x: `Manifest.tests.ps1` fails as a container and the count drops to 418. ## Breaking Changes None. The consumer-facing surface — `RequiredModules`, task names, task dependencies, and the `$PSBPreference` contract — is untouched. ## Reviewer notes - **Please squash-merge.** The branch has three commits including a docs entry that was added and then removed once we settled that this change is not user-facing. The net diff is the two files above; the intermediate history is not worth keeping. - **Known coverage gap:** the manifest claims psake ≥ 4.9.0 support, but CI now exercises only 5.0.4. The psake-4 result above was measured locally, not in CI. Continuously testing that claim needs a side-by-side matrix like `requirements.pester-matrix.psd1`. Not added here — it is scope beyond #161, and it is raised on #120 as open fog rather than decided inside this PR. Spike evidence: #155. Part of #120.
Summary
PsakeBuildResultoutputOutputModesetting (Detailed/Minimal/LLM) whereLLMmode emits structured JSON with only failure details, suppressing verbose console noise$PSBPreference.Test.PesterConfigurationPathloads a.psd1as the base config with explicit overrides layered on topStageFiles,Analyze,Pester,GenerateMarkdown,GenerateMAML,GenerateUpdatableHelpall declareInputs/Outputsfor incremental build skippingFormat-PSBuildResult— new public function formattingPsakeBuildResultfor Human, JSON, or GitHubActions consumersIB.tasks.ps1updated with matchingInputs/Outputscaching and new Pester parameter passthroughBreaking Changes
./build.ps1 -Bootstrapwill installInvoke-psakereturnsPsakeBuildResultobject$psake.build_successwith$result.SuccessNew
$PSBPreferenceKeysBuild.EnableTaskCaching$trueTest.OutputMode'Detailed'Detailed/Minimal/LLMoutput modesTest.PesterConfigurationPath$null.psd1PesterConfigurationFiles Changed (20)
New files (5):
ConvertTo-PSBuildLLMOutput.ps1,Format-PSBuildResult.ps1,LLMOutput.tests.ps1,PesterConfig.tests.ps1,FormatBuildResult.tests.ps1Major rewrites (1):
PowerShellBuild/psakeFile.ps1— all 16 tasks converted to declarative hashtable syntax withInputs/OutputscachingModified (14): manifest, requirements, build.ps1, root psakeFile, build.properties, Test-PSBuildPester, IB.tasks, Messages.psd1, PowerShellBuild.psm1, CI workflow, CHANGELOG, CLAUDE.md, Manifest.tests, TestModule psakeFile
Known Risks
PreConditionin declarative syntax — psake 5.0.0's hashtableTasksyntax support forPreConditionkey is inferred from the commit, not confirmed by docs. If it fails, mitigation is to move precondition logic into guard clauses at the top ofActionscriptblocks.$psake.context.Peek().Tasks.Keys— used by the?task; may need updating if psake 5.0.0 changes this internal API.Test plan
./build.ps1 -Bootstrapinstalls psake 5.0.0 successfully./build.ps1 -Task Buildcompiles with declarative task syntax./build.ps1 -Task Testpasses all existing + new tests./build.ps1 -Task Buildskips cached tasksPesterConfigurationPathloads external configFormat-PSBuildResult -Format JSONproduces valid structured output🤖 Generated with Claude Code