From 695f4590f82664303a35d06f395d1213430e8513 Mon Sep 17 00:00:00 2001 From: Chris Muench Date: Mon, 20 Jul 2026 08:21:27 +0100 Subject: [PATCH 1/2] fix(appliance): make the Pester Copy-Item mock satisfy the script's copy guard Four of the six Hyper-V import tests have failed on every run since they were written - main, v0.5.0 and every dependabot PR since 2026-07-09. Both the test and the guard it trips over landed in the same commit (91f4cc2), so this suite has never been green. The script verifies the VHDX copy actually landed before handing the path to New-VM: Copy-Item -LiteralPath $VhdxPath -Destination $destVhdx -Force if (-not (Test-Path -LiteralPath $destVhdx -PathType Leaf)) { throw "VHDX copy failed..." } That guard is worth keeping - a silently failed copy would otherwise produce a VM pointed at a disk that is not there. The test mocked Copy-Item to a no-op, so the destination never appeared and the guard threw on every test that reached it. The two that passed were the two that fail during validation, before the copy. The mock now creates the destination file, which is what a real copy does. The existing assertion on Copy-Item's Destination parameter still holds. These tests need Windows identity APIs (WindowsIdentity::GetCurrent) and cannot run off Windows, so this is verified by the Scripts workflow rather than locally. Co-Authored-By: Claude Opus 4.8 (1M context) --- appliance/Import-DispatchAppliance.Tests.ps1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/appliance/Import-DispatchAppliance.Tests.ps1 b/appliance/Import-DispatchAppliance.Tests.ps1 index 09fad4d..1adddf4 100644 --- a/appliance/Import-DispatchAppliance.Tests.ps1 +++ b/appliance/Import-DispatchAppliance.Tests.ps1 @@ -33,7 +33,12 @@ Describe 'Import-DispatchAppliance (unattended)' { Mock Set-VMMemory {} Mock Set-VMNetworkAdapterVlan {} Mock Start-VM {} - Mock Copy-Item {} + # Create the destination, rather than mocking the copy away to nothing. The script verifies the + # copy landed (Test-Path -PathType Leaf) before handing the path to New-VM - a real guard, since a + # silently failed copy would otherwise produce a VM pointed at a missing disk. A no-op mock made + # that guard throw on every test that got as far as the copy, which is why four of the six here have + # failed since they were written. + Mock Copy-Item { New-Item -ItemType File -Path $Destination -Force | Out-Null } } It 'keeps VM config + disk together under \' { From a4208da63b8dd9225cb1a82bf30d6cec61e3ce0d Mon Sep 17 00:00:00 2001 From: Chris Muench Date: Mon, 20 Jul 2026 17:52:52 +0100 Subject: [PATCH 2/2] ci: register PSGallery if the runner has not, before trusting it Both jobs in scripts.yml start with `Set-PSRepository PSGallery -InstallationPolicy Trusted`, which fails hard when PSGallery is not registered yet: Set-PSRepository: No repository with the name 'PSGallery' was found. That is an intermittent runner-image state, not a code problem - it flaked this workflow on a run where the actual test change was correct. Register-if-missing first, so a runner that has not registered the default gallery does not fail the job before a single test runs. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/scripts.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/scripts.yml b/.github/workflows/scripts.yml index 46b93a5..13946bd 100644 --- a/.github/workflows/scripts.yml +++ b/.github/workflows/scripts.yml @@ -21,6 +21,10 @@ jobs: - name: Parse + analyze PowerShell shell: pwsh run: | + # Register the gallery if the runner image has not, then trust it. Set-PSRepository fails hard when + # PSGallery is not registered yet - an intermittent runner-image state that has flaked this job - + # so register-if-missing rather than assume it is there. + if (-not (Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue)) { Register-PSRepository -Default } Set-PSRepository PSGallery -InstallationPolicy Trusted Install-Module PSScriptAnalyzer -Force -Scope CurrentUser $dirs = 'appliance', 'installer/windows' @@ -51,6 +55,7 @@ jobs: - name: Pester (Hyper-V import logic, cmdlets mocked) shell: pwsh run: | + if (-not (Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue)) { Register-PSRepository -Default } Set-PSRepository PSGallery -InstallationPolicy Trusted Install-Module Pester -MinimumVersion 5.5.0 -Force -Scope CurrentUser -SkipPublisherCheck Import-Module Pester