test: Make the psake/Invoke-Build task drift guard able to fail, in both directions - #224
Open
tablackburn wants to merge 2 commits into
Open
test: Make the psake/Invoke-Build task drift guard able to fail, in both directions#224tablackburn wants to merge 2 commits into
tablackburn wants to merge 2 commits into
Conversation
Test Results 4 files ±0 889 suites ±0 2m 6s ⏱️ -21s Results for commit a28ac72. ± Comparison against base commit 3ea9e82. This pull request removes 1 and adds 1 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
The 'Contains all the tasks that were in the Psake file' test has never compared a task name. Three defects cancelled out: - $IBTasksResult was assigned in a different It block, so it was $null in the block that read it. The Invoke-Build job now runs in the Describe's BeforeAll and both It blocks read the same $script: variable. - Invoke-PSake -docs writes a formatted table, so format records with no Name property crossed the job boundary and every psake task name was $null. Get-PSakeScriptTasks returns task objects, and the job projects the names to strings before they are serialized. - $IBTasksResult.All is an ordered dictionary keyed by task name, so .Name looked up a key that does not exist rather than enumerating the names. The job returns .All.Keys. Renaming Task Sign in IB.tasks.ps1 now fails the test with "but got 'Sign'"; before this change the whole suite stayed green. Closes #215 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011GYJrhbrDzqufaeMqD9QjT
A task defined in IB.tasks.ps1 and forgotten in psakeFile.ps1 leaves psake consumers without it, which is the same defect as #178 and #193 with the files swapped, and nothing else in the suite catches it. The guard now asserts both directions with a Because of its own, matching the shape the signing comparison in this file already uses, and the It is renamed to say what it does. Each runner's own entry point is excluded on its own side: psake answers to 'default' and '?', Invoke-Build to '.'. Nothing else is excluded. Measured: appending Task ExtraInvokeBuildTask to IB.tasks.ps1 fails with "but got 'ExtraInvokeBuildTask'", and renaming Task Sign there still fails with "but got 'Sign'". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011GYJrhbrDzqufaeMqD9QjT
tablackburn
force-pushed
the
fix/215-ib-drift-guard
branch
from
August 28, 2026 22:21
e7f9a2c to
a28ac72
Compare
This was referenced Sep 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #215. The
Invoke-Build Tasksdrift guard has never once compared a task name, and now compares them in both directions.Three defects had to be fixed, not the two the issue describes. Each on its own was enough to make the comparison vacuous, and they cancelled out into a passing test:
$IBTasksResultwas$nullin theItthat read it. It was assigned in a differentIt; theDescribe-level$IBTasksResult = $nullruns at discovery only, and Pester 5 does not carry a variable from oneItinto the next. The Invoke-Build job now runs inBeforeAlland bothItblocks read$script:invokeBuildTaskName.Invoke-PSake -docspiped throughReceive-Jobreturns format records, which have noNameproperty, so every psake task name was$null. Replaced withGet-PSakeScriptTasks, projected to strings inside the job before they cross the serialization boundary.$IBTasksResult.Allis anOrderedDictionarykeyed by task name, so.All.Namewas a lookup for a key calledNamerather than an enumeration. Fixing only the two documented defects would still have compared psake's tasks against an empty list. The job now returns.All.Keys.$null -notin $nullisFalse, so thethrownever fired, and an array of nulls satisfiedShould -Not -BeNullOrEmpty.The comparison is now bidirectional. A task defined in
IB.tasks.ps1and forgotten inpsakeFile.ps1leaves psake consumers without it — the same defect as #178 and #193 with the files swapped, and nothing else in the suite catches it. This matches the shape the signing comparison in this same file already uses. Each runner's own entry point is excluded on its own side: psake answers todefaultand?, Invoke-Build to.. Nothing else is excluded.Test plan
./build.ps1 -Task Test— green. Both directions were proved able to fail, not assumed:Task Signrenamed inIB.tasks.ps1but got 'Sign'Task ExtraInvokeBuildTaskappended toIB.tasks.ps1but got 'ExtraInvokeBuildTask'Exactly one test fails in each case, so the neighbouring blocks are undisturbed.
The three other
Describeblocks in this file — the settings comparison and README table checks from #178, and the signing settings comparison from #193 — are untouched.Breaking changes
None. Test suite only.
No
CHANGELOG.mdentry:instructions/repository-specific.instructions.mdscopes the changelog to user-facing changes to the shipped module and excludes the test suite. Nothing underPowerShellBuild/changed.Local variable names in the block being rewritten were expanded per
shorthand.instructions.md($outputModVerDirbecame$outputModuleVersionPath, and similar).