Skip to content

test: Make the psake/Invoke-Build task drift guard able to fail, in both directions - #224

Open
tablackburn wants to merge 2 commits into
mainfrom
fix/215-ib-drift-guard
Open

test: Make the psake/Invoke-Build task drift guard able to fail, in both directions#224
tablackburn wants to merge 2 commits into
mainfrom
fix/215-ib-drift-guard

Conversation

@tablackburn

@tablackburn tablackburn commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Summary

The three defects

  1. $IBTasksResult was assigned in one It and read in the next. Each It runs in its own
    scope, and the $IBTasksResult = $null at the Describe level runs at discovery only, so
    the reader saw $null. The Invoke-Build job now runs once in the Describe's BeforeAll
    and both It blocks read $script:invokeBuildTaskName.
  2. Invoke-PSake -docs writes a formatted table, so format records crossed the job
    boundary, not task objects. They have no Name property, so every psake name was $null.
    Get-PSakeScriptTasks -buildFile returns task objects, and the job projects the names to
    strings before they are serialized.
  3. Not in the issue: $IBTasksResult.All is an OrderedDictionary keyed by task name, so
    .All.Name is a lookup for a key called Name, not an enumeration of the names. It is
    empty in-process and after serialization alike, so fixing only the scoping defect would
    still have compared psake's tasks against an empty list. The job returns .All.Keys.

$null -notin $null is False, so the old throw never fired, and the closing
Should -Not -BeNullOrEmpty passed on an array of 21 nulls.

Both directions

A task defined in IB.tasks.ps1 and forgotten in psakeFile.ps1 leaves psake consumers
without it — the same defect as #178 and #193 with the files swapped — and nothing else in the
suite catches it. The It is renamed to defines the same tasks in both task files and
asserts $missingFromInvokeBuild and $missingFromPsake separately, each with its own
-Because, matching the Signing settings referenced by the task files block in this file.

Each runner's own entry point is excluded on its own side, with the reason in a comment: psake
answers to default and ?, Invoke-Build to .. Nothing else is excluded.

Test plan

./build.ps1 -Task Test on Windows 11, PowerShell 7.6.5, Pester 6.1.0, psake 5.0.4,
InvokeBuild 5.14.23. Each run was checked against the rebuilt files in Output/ to confirm the
probe was present or absent as intended.

Red, psake task missing from Invoke-BuildTask Sign SignModule, SignCatalog renamed to
Task RenamedSignTask ... in PowerShellBuild/IB.tasks.ps1:

  [-] defines the same tasks in both task files
   Expected $null or empty, because IB.tasks.ps1 must define every task psakeFile.ps1
   defines, but got 'Sign'.
Tests Passed: 590, Failed: 1, Skipped: 3

Red, Invoke-Build task missing from psakeTask ExtraInvokeBuildTask {} appended to
PowerShellBuild/IB.tasks.ps1. An addition is the only probe that isolates this direction,
since a rename diverges both at once:

  [-] defines the same tasks in both task files
   Expected $null or empty, because psakeFile.ps1 must define every task IB.tasks.ps1
   defines, but got 'ExtraInvokeBuildTask'.
Tests Passed: 590, Failed: 1, Skipped: 3

Before this change, neither divergence failed anything — the measurement in #215.

Green — both probes reverted, neither name present in the built task files:

  [+] IB.tasks.ps1 exists
  [+] Parseable by invoke-build
  [+] defines the same tasks in both task files
Tests Passed: 591, Failed: 0, Skipped: 3

Both runners report the same 16 tasks.

Notes

  • Local variable names in the BeforeAll lost their abbreviations ($outputModVerDir became
    $outputModuleVersionPath) while those lines were being edited, per the shorthand
    instructions.
  • No CHANGELOG.md entry: a test-suite repair with no change to the shipped module, and
    repository-specific.instructions.md scopes the changelog to user-facing changes.

Closes #215

Copilot AI lite review requested due to automatic review settings August 28, 2026 21:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

Test Results

    4 files  ±0    889 suites  ±0   2m 6s ⏱️ -21s
  596 tests ±0    593 ✅ ±0   3 💤 ±0  0 ❌ ±0 
2 367 runs  ±0  2 295 ✅ ±0  72 💤 ±0  0 ❌ ±0 

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.
Invoke-Build Tasks.Contains all the tasks that were in the Psake file
Invoke-Build Tasks.defines the same tasks in both task files

♻️ This comment has been updated with latest results.

tablackburn and others added 2 commits August 28, 2026 18:04
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
tablackburn force-pushed the fix/215-ib-drift-guard branch from e7f9a2c to a28ac72 Compare August 28, 2026 22:21
@tablackburn tablackburn changed the title test: Make the psake/Invoke-Build task drift guard able to fail test: Make the psake/Invoke-Build task drift guard able to fail, in both directions Aug 28, 2026
Sign up for free to 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.

The psake/Invoke-Build task drift guard compares nothing against nothing

2 participants