Skip to content

[1.0.0-alpha1] Upgrade to psake 5.0.0 with task caching and LLM output - #117

Closed
HeyItsGilbert wants to merge 3 commits into
mainfrom
feature/psake5-alpha1
Closed

[1.0.0-alpha1] Upgrade to psake 5.0.0 with task caching and LLM output#117
HeyItsGilbert wants to merge 3 commits into
mainfrom
feature/psake5-alpha1

Conversation

@HeyItsGilbert

Copy link
Copy Markdown
Member

Summary

  • Upgrade to psake 5.0.0 with declarative task syntax, content-addressed caching, and structured PsakeBuildResult output
  • LLM-optimized Pester output — new OutputMode setting (Detailed/Minimal/LLM) where LLM mode emits structured JSON with only failure details, suppressing verbose console noise
  • External PesterConfiguration file support$PSBPreference.Test.PesterConfigurationPath loads a .psd1 as the base config with explicit overrides layered on top
  • Task cachingStageFiles, Analyze, Pester, GenerateMarkdown, GenerateMAML, GenerateUpdatableHelp all declare Inputs/Outputs for incremental build skipping
  • Format-PSBuildResult — new public function formatting PsakeBuildResult for Human, JSON, or GitHubActions consumers
  • Invoke-Build parityIB.tasks.ps1 updated with matching Inputs/Outputs caching and new Pester parameter passthrough

Breaking Changes

ChangeMigration
Minimum PowerShell raised from 3.0 to 5.1Ensure PS 5.1+ runtime
psake dependency raised from 4.9.0 to 5.0.0./build.ps1 -Bootstrap will install
Invoke-psake returns PsakeBuildResult objectReplace $psake.build_success with $result.Success

New $PSBPreference Keys

KeyDefaultPurpose
Build.EnableTaskCaching$trueToggle psake 5 content-addressed caching
Test.OutputMode'Detailed'Detailed / Minimal / LLM output modes
Test.PesterConfigurationPath$nullPath to external .psd1 PesterConfiguration

Files Changed (20)

New files (5):ConvertTo-PSBuildLLMOutput.ps1, Format-PSBuildResult.ps1, LLMOutput.tests.ps1, PesterConfig.tests.ps1, FormatBuildResult.tests.ps1

Major rewrites (1):PowerShellBuild/psakeFile.ps1 — all 16 tasks converted to declarative hashtable syntax with Inputs/Outputs caching

Modified (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

  • PreCondition in declarative syntax — psake 5.0.0's hashtable Task syntax support for PreCondition key is inferred from the commit, not confirmed by docs. If it fails, mitigation is to move precondition logic into guard clauses at the top of Action scriptblocks.
  • $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 -Bootstrap installs psake 5.0.0 successfully
  • ./build.ps1 -Task Build compiles with declarative task syntax
  • ./build.ps1 -Task Test passes all existing + new tests
  • Verify task caching: second ./build.ps1 -Task Build skips cached tasks
  • Verify LLM output mode produces valid JSON with failure schema
  • Verify PesterConfigurationPath loads external config
  • Verify Format-PSBuildResult -Format JSON produces valid structured output
  • Cross-platform CI green (ubuntu, windows pwsh, windows PS 5.1, macOS)
  • TestModule builds with both psake and Invoke-Build

🤖 Generated with Claude Code

HeyItsGilbertand others added 3 commits March 22, 2026 12:34
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>
Comment on lines +27 to +41
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

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

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: read

between 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.

Suggested changeset 1
.github/workflows/test.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -4,6 +4,8 @@
branches: [ main ]
pull_request:
workflow_dispatch:
+permissions:
+ contents: read
jobs:
test:
name: Test
EOF
@@ -4,6 +4,8 @@
branches: [ main ]
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs:
test:
name: Test
Copilot is powered by AI and may make mistakes. Always verify output.
tablackburn added a commit that referenced this pull request Aug 22, 2026
## 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.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@HeyItsGilbert@github-advanced-security