#Requires -Version 5.1 <# .SYNOPSIS Smoke test for the CI pipeline. Validates the full lifecycle end-to-end using a trivial no-op build. .DESCRIPTION Invokes Invoke-CIJob.ps1 with a minimal build command (write a marker file) and checks that the pipeline completes successfully: - Invoke-CIJob.ps1 exits 0 - Artifact directory is created: F:\CI\Artifacts\\ - invoke-ci.jsonl contains a job-success event This script can be run directly on the CI host without act_runner. It is also invoked by gitea/workflows/self-test.yml via the composite action. .PARAMETER GuestOS Guest OS template to use. Windows (default) or Linux. .PARAMETER TemplatePath Override the VMX template path. Defaults to the standard template for the chosen GuestOS. .PARAMETER SnapshotName Snapshot to clone from. Default: BaseClean (Windows) or BaseClean-Linux (Linux). .PARAMETER JobId Job ID for this test run. Default: smoke-. .PARAMETER VmrunPath Path to vmrun.exe. Default: C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe .EXAMPLE # Test Windows template .\Test-Smoke.ps1 .EXAMPLE # Test Linux template .\Test-Smoke.ps1 -GuestOS Linux #> [CmdletBinding()] param( [ValidateSet('Windows', 'Linux')] [string] $GuestOS = 'Windows', [string] $TemplatePath, [string] $SnapshotName, [string] $JobId = "smoke-$(Get-Date -Format 'yyyyMMdd-HHmmss')", [string] $VmrunPath = 'C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe', [string] $ArtifactBaseDir = 'F:\CI\Artifacts', [string] $LogDir = 'F:\CI\Logs' ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $scriptDir = $PSScriptRoot # ── Resolve defaults ────────────────────────────────────────────────────────── if (-not $TemplatePath) { if ($GuestOS -eq 'Linux') { $TemplatePath = if ($env:GITEA_CI_LINUX_TEMPLATE_PATH) { $env:GITEA_CI_LINUX_TEMPLATE_PATH } else { 'F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx' } } else { $TemplatePath = if ($env:GITEA_CI_TEMPLATE_PATH) { $env:GITEA_CI_TEMPLATE_PATH } else { 'F:\CI\Templates\WinBuild2025\WinBuild2025.vmx' } } } if (-not $SnapshotName) { $SnapshotName = if ($GuestOS -eq 'Linux') { 'BaseClean-Linux' } else { 'BaseClean' } } # ── Build command ───────────────────────────────────────────────────────────── # Writes a marker file to the standard output directory for the chosen OS. if ($GuestOS -eq 'Linux') { $buildCommand = 'mkdir -p /opt/ci/output && echo smoke-ok > /opt/ci/output/smoke.txt' $artifactSource = '/opt/ci/output' } else { $buildCommand = 'New-Item -ItemType Directory -Path C:\CI\output -Force | Out-Null; Set-Content C:\CI\output\smoke.txt "smoke-ok"' $artifactSource = 'C:\CI\output' } Write-Host "============================================================" Write-Host "[Test-Smoke] GuestOS : $GuestOS" Write-Host "[Test-Smoke] Template : $TemplatePath" Write-Host "[Test-Smoke] Snapshot : $SnapshotName" Write-Host "[Test-Smoke] JobId : $JobId" Write-Host "============================================================" # ── Run the pipeline ────────────────────────────────────────────────────────── $invokeParams = @{ JobId = $JobId RepoUrl = 'https://example.invalid/smoke-test.git' # never cloned; UseGitClone omitted Branch = 'main' TemplatePath = $TemplatePath SnapshotName = $SnapshotName BuildCommand = $buildCommand GuestArtifactSource = $artifactSource ArtifactBaseDir = $ArtifactBaseDir LogDir = $LogDir GuestOS = $GuestOS VmrunPath = $VmrunPath } $invokeScript = Join-Path $scriptDir 'Invoke-CIJob.ps1' & $invokeScript @invokeParams $pipelineExit = $LASTEXITCODE # ── Assert artifacts ────────────────────────────────────────────────────────── $artifactDir = Join-Path $ArtifactBaseDir $JobId $jsonlPath = Join-Path $LogDir $JobId 'invoke-ci.jsonl' Write-Host "`n[Test-Smoke] Verifying results..." $pass = $true if ($pipelineExit -ne 0) { Write-Host "[Test-Smoke] FAIL: Invoke-CIJob.ps1 exited $pipelineExit" -ForegroundColor Red $pass = $false } else { Write-Host "[Test-Smoke] OK: pipeline exit 0" -ForegroundColor Green } if (Test-Path $artifactDir) { Write-Host "[Test-Smoke] OK: artifact dir exists: $artifactDir" -ForegroundColor Green } else { Write-Host "[Test-Smoke] FAIL: artifact dir not found: $artifactDir" -ForegroundColor Red $pass = $false } if (Test-Path $jsonlPath) { $jobSuccess = Get-Content $jsonlPath -Raw -ErrorAction SilentlyContinue | Where-Object { $_ } | ForEach-Object { $_ } | Where-Object { $_ -match '"phase"\s*:\s*"job"' -and $_ -match '"status"\s*:\s*"success"' } if ($jobSuccess) { Write-Host "[Test-Smoke] OK: JSONL contains job/success event" -ForegroundColor Green } else { Write-Host "[Test-Smoke] FAIL: JSONL missing job/success event in: $jsonlPath" -ForegroundColor Red $pass = $false } } else { Write-Host "[Test-Smoke] FAIL: JSONL log not found: $jsonlPath" -ForegroundColor Red $pass = $false } Write-Host '' if ($pass) { Write-Host "[Test-Smoke] PASSED — $GuestOS smoke test completed successfully." -ForegroundColor Green exit 0 } else { Write-Host "[Test-Smoke] FAILED — one or more checks did not pass." -ForegroundColor Red exit 1 }