diff --git a/scripts/Sign-TestMSIX.ps1 b/scripts/Sign-TestMSIX.ps1 index 6e0d1162..fa1d19f9 100644 --- a/scripts/Sign-TestMSIX.ps1 +++ b/scripts/Sign-TestMSIX.ps1 @@ -29,6 +29,24 @@ if ([string]::IsNullOrWhiteSpace($publisher)) { throw 'The Gateway MSIX release policy publisher is missing.' } +$architectures = @('x64', 'arm64') +$architectureDirectories = @( + $architectures | + ForEach-Object { + $sourceDirectory = Join-Path $resolvedArtifactsDirectory $_ + if (Test-Path -LiteralPath $sourceDirectory -PathType Container) { + $sourceDirectory + } + } +) +if ($architectureDirectories.Count -eq 0) { + throw ( + "No architecture directories were found under " + + "'$resolvedArtifactsDirectory'. Expected at least one of: " + + ($architectures -join ', ') + '.' + ) +} + $signtool = Get-ChildItem ` -LiteralPath "${env:ProgramFiles(x86)}\Windows Kits\10\bin" ` -Filter 'signtool.exe' ` @@ -75,7 +93,7 @@ try { -Password $password | Out-Null - foreach ($architecture in @('x64', 'arm64')) { + foreach ($architecture in $architectures) { $sourceDirectory = Join-Path $resolvedArtifactsDirectory $architecture if (-not (Test-Path -LiteralPath $sourceDirectory -PathType Container)) { continue diff --git a/scripts/Test-Sign-TestMSIX.Tests.ps1 b/scripts/Test-Sign-TestMSIX.Tests.ps1 new file mode 100644 index 00000000..88338e1c --- /dev/null +++ b/scripts/Test-Sign-TestMSIX.Tests.ps1 @@ -0,0 +1,63 @@ +[CmdletBinding()] +param() + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +if (-not $IsWindows) { + throw 'Test MSIX signing tests require Windows.' +} + +$scriptPath = Join-Path $PSScriptRoot 'Sign-TestMSIX.ps1' +$testRoot = Join-Path $env:TEMP ( + "openclaw-sign-testmsix-$([guid]::NewGuid().ToString('N'))" +) +$artifactsDirectory = Join-Path $testRoot 'artifacts' +$outputDirectory = Join-Path $testRoot 'signed' +$publisher = 'CN=OpenClaw Foundation, O=OpenClaw Foundation, L=Mill Valley, S=California, C=US' +$thumbprintsBefore = @( + Get-ChildItem -Path 'Cert:\CurrentUser\My' | + Where-Object Subject -eq $publisher | + Select-Object -ExpandProperty Thumbprint +) + +try { + New-Item -Path $artifactsDirectory -ItemType Directory -Force | Out-Null + + $output = @( + & pwsh -NoProfile -File $scriptPath ` + -ArtifactsDirectory $artifactsDirectory ` + -OutputDirectory $outputDirectory 2>&1 + ) + $exitCode = $LASTEXITCODE + $message = $output -join [Environment]::NewLine + + if ($exitCode -eq 0) { + throw 'Signing unexpectedly succeeded without an architecture directory.' + } + if ($message -notmatch 'No architecture directories were found') { + throw "Signing failure did not identify the missing architecture directories. Output: $message" + } + if (Test-Path -LiteralPath $outputDirectory) { + throw 'Signing created an output directory despite finding no architecture directory.' + } + + $thumbprintsAfter = @( + Get-ChildItem -Path 'Cert:\CurrentUser\My' | + Where-Object Subject -eq $publisher | + Select-Object -ExpandProperty Thumbprint + ) + $newThumbprints = Compare-Object ` + -ReferenceObject $thumbprintsBefore ` + -DifferenceObject $thumbprintsAfter ` + -PassThru | + Where-Object SideIndicator -eq '=>' + if ($null -ne $newThumbprints) { + throw 'Signing created a publisher certificate on the no-op failure path.' + } + + Write-Host 'Test MSIX no-op signing regression test passed.' +} +finally { + Remove-Item -LiteralPath $testRoot -Recurse -Force -ErrorAction SilentlyContinue +}