Some checks failed
Build SilverMetal Enhanced - Windows ISO / build (pull_request) Failing after 34s
Implement build.ps1 (M2): mount/extract the base ISO, offline-service install.wim (inject GPD drivers if staged, debloat appx, bake SetupComplete.cmd + hardening modules into \Windows\Setup\Scripts), inject autounattend.xml, oscdimg UEFI repack, emit SHA-256 + SBOM. Elevation + oscdimg guarded. Add .gitea/workflows/build-iso-windows.yaml: runs on the self-hosted silverlabs-runner-win (windows-latest), ensures ADK Deployment Tools, acquires the base ISO from repo var SILVERMETAL_BASE_ISO_URL or a pre-staged path, builds, validates the baked payload offline, uploads SBOM/SHA (+ISO on dispatch/tag), attaches to a Gitea release on win-v* tags. Mirrors build-iso-linux.yaml. Add tests/Assert-IsoStructure.ps1: the no-nested-virt CI gate - mounts the built ISO + install.wim read-only and asserts autounattend.xml, SetupComplete.cmd, and the hardening modules are correctly baked. Full QEMU boot+Verify is a follow-on. Switch autounattend to Windows' native SetupComplete.cmd auto-run (SYSTEM, end of setup) instead of a duplicate FirstLogonCommands call. Untested until first runner execution (dev box is ARM64). All PS parse-clean; autounattend XML + workflow YAML valid. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
2.3 KiB
PowerShell
45 lines
2.3 KiB
PowerShell
#Requires -Version 5.1
|
|
<# SilverMetal Enhanced - Windows | Offline ISO structure assertions.
|
|
The reliable CI gate that needs NO nested virtualization: proves the built
|
|
ISO baked the answer file + hardening payload correctly. Full boot-and-Verify
|
|
(QEMU + OVMF + swtpm) is a follow-on stage that needs nested virt.
|
|
Exit 0 = all assertions pass; non-zero = failures.
|
|
#>
|
|
[CmdletBinding()] param([Parameter(Mandatory)][string]$IsoPath)
|
|
Set-StrictMode -Version Latest; $ErrorActionPreference = 'Stop'
|
|
|
|
$fail = 0
|
|
function Assert { param([string]$Name,[bool]$Cond)
|
|
if ($Cond) { Write-Host "[PASS] $Name" -ForegroundColor Green }
|
|
else { Write-Host "[FAIL] $Name" -ForegroundColor Red; $script:fail++ }
|
|
}
|
|
|
|
if (-not (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
|
|
[Security.Principal.WindowsBuiltInRole]::Administrator))) { throw 'must run elevated (WIM mount).' }
|
|
|
|
$img = Mount-DiskImage -ImagePath $IsoPath -PassThru
|
|
$mount = Join-Path $env:TEMP 'sm-assert-wim'
|
|
$null = New-Item -ItemType Directory -Force $mount
|
|
try {
|
|
$drive = ($img | Get-Volume).DriveLetter + ':'
|
|
Assert 'autounattend.xml at ISO root' (Test-Path "$drive\autounattend.xml")
|
|
$wim = "$drive\sources\install.wim"
|
|
Assert 'sources\install.wim present' (Test-Path $wim)
|
|
|
|
if (Test-Path $wim) {
|
|
$idx = (Get-WindowsImage -ImagePath $wim | Where-Object ImageName -match 'IoT Enterprise LTSC' | Select-Object -First 1).ImageIndex
|
|
if (-not $idx) { $idx = 1 }
|
|
Mount-WindowsImage -ImagePath $wim -Index $idx -Path $mount -ReadOnly | Out-Null
|
|
try {
|
|
$sc = Join-Path $mount 'Windows\Setup\Scripts\SetupComplete.cmd'
|
|
Assert 'SetupComplete.cmd baked into WIM' (Test-Path $sc)
|
|
$mods = Get-ChildItem (Join-Path $mount 'Windows\Setup\Scripts\hardening') -Filter *.ps1 -EA SilentlyContinue
|
|
Assert 'hardening modules baked (>=9 .ps1)' ($mods.Count -ge 9)
|
|
Assert 'Verify script baked' (Test-Path (Join-Path $mount 'Windows\Setup\Scripts\hardening\Verify-SilverMetalWindows.ps1'))
|
|
} finally { Dismount-WindowsImage -Path $mount -Discard | Out-Null }
|
|
}
|
|
} finally { Dismount-DiskImage -ImagePath $IsoPath | Out-Null }
|
|
|
|
Write-Host "`n$($fail) assertion(s) failed."
|
|
exit $fail
|