feat(sprint2): fix critical and high-priority bugs
C1: composite action selects Linux/Windows template from GITEA_CI_LINUX_TEMPLATE_PATH
based on resolved guest OS; build-nsis.yml adds belt-and-suspenders guest-os param.
C2: redact ExtraGuestEnv secrets in Invoke-RemoteBuild.ps1 (envPrefix never logged).
H2: composite action outputs block corrected; duplicate artifact-name input removed.
H3: Linux Mode 2 PAT now uses http.extraHeader (mirrors Windows branch, drops GIT_CLONE_URL).
H6: Setup-Host.ps1 directory array updated to canonical layout (adds State, ip-leases, keys,
Cache\pip, WinBuild2025/2022/LinuxBuild2404; removes obsolete WinBuild).
H7: Backup-CITemplate.ps1 default TemplatePath -> WinBuild2025; -AllTemplates switch added.
H8: Setup-Host.ps1 adds StrictHostKeyChecking=accept-new and Step 8 to replicate SSH config
to LocalSystem profile for act_runner service account.
H11: runner/config.yaml adds GITEA_CI_SCRIPT_ROOT env var; action.yml uses it in place of
hardcoded N:\ path.
Also: Invoke-RemoteBuild.ps1 skips 7-Zip/Compress-Archive when artifact source dir does not
exist (fixes burn-in smoke runs with exit-0 build command and no output).
This commit is contained in:
@@ -136,6 +136,10 @@ param(
|
||||
# SSH username (used when GuestOS=Linux).
|
||||
[string] $SshUser = 'ci_build',
|
||||
|
||||
# Persistent known_hosts file for SSH calls (CI jobs).
|
||||
# Pass an empty string to disable host-key checking (template provisioning only).
|
||||
[string] $SshKnownHostsFile = 'F:\CI\State\known_hosts',
|
||||
|
||||
# Work directory inside the Linux guest.
|
||||
[string] $GuestLinuxWorkDir = '/opt/ci/build',
|
||||
|
||||
@@ -176,6 +180,7 @@ if ($GuestOS -eq 'Linux') {
|
||||
|
||||
# Step 1: Clean work dir (parent permissions handled by template setup)
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile `
|
||||
-Command "rm -rf '$GuestLinuxWorkDir' && mkdir -p '$GuestLinuxWorkDir'"
|
||||
|
||||
if ($hostCloneMode) {
|
||||
@@ -193,10 +198,12 @@ if ($GuestOS -eq 'Linux') {
|
||||
try {
|
||||
Write-Host "[Invoke-RemoteBuild] Copying source archive to guest:$guestTar ..."
|
||||
Copy-SshItem -Source $hostTar -Destination $guestTar `
|
||||
-IP $IPAddress -User $SshUser -KeyPath $SshKeyPath -Direction ToGuest
|
||||
-IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile -Direction ToGuest
|
||||
|
||||
Write-Host "[Invoke-RemoteBuild] Extracting source in guest ($GuestLinuxWorkDir) ..."
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile `
|
||||
-Command "tar -xzf '$guestTar' -C '$GuestLinuxWorkDir' && rm -f '$guestTar'"
|
||||
}
|
||||
finally {
|
||||
@@ -208,36 +215,41 @@ if ($GuestOS -eq 'Linux') {
|
||||
$cloneCmd = "git clone --depth 1 --branch '$CloneBranch'"
|
||||
if ($CloneSubmodules) { $cloneCmd += ' --recurse-submodules' }
|
||||
|
||||
# PAT injection for private repos
|
||||
$cloneTargetUrl = $CloneUrl
|
||||
if ($GiteaCredentialTarget -ne '') {
|
||||
try {
|
||||
Import-Module CredentialManager -ErrorAction Stop
|
||||
$pat = Get-StoredCredential -Target $GiteaCredentialTarget -ErrorAction Stop
|
||||
if ($pat) {
|
||||
$cloneTargetUrl = $CloneUrl -replace '(https?://)', ('$1' + [uri]::EscapeDataString($pat.UserName) + ':' + [uri]::EscapeDataString($pat.GetNetworkCredential().Password) + '@')
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "[Invoke-RemoteBuild] Could not load PAT from Credential Manager ($GiteaCredentialTarget) — cloning without auth (public repo?)."
|
||||
}
|
||||
}
|
||||
|
||||
$cloneCmd += " '$CloneUrl' '$GuestLinuxWorkDir'" # non-authed URL for logging
|
||||
Write-Host "[Invoke-RemoteBuild] Cloning $CloneUrl into guest $GuestLinuxWorkDir ..."
|
||||
|
||||
if ($cloneTargetUrl -ne $CloneUrl) {
|
||||
# PAT injected via env var inside SSH session — never in args
|
||||
$envCloneCmd = "export GIT_CLONE_URL='$cloneTargetUrl'; git clone --depth 1 --branch '$CloneBranch'"
|
||||
if ($CloneSubmodules) { $envCloneCmd += ' --recurse-submodules' }
|
||||
$envCloneCmd += " `"`$GIT_CLONE_URL`" '$GuestLinuxWorkDir'; unset GIT_CLONE_URL"
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath -Command $envCloneCmd
|
||||
# PAT injection via git http.extraHeader — PAT never appears in argv or /proc/environ
|
||||
$authHeader = ''
|
||||
if ($GiteaCredentialTarget -ne '') {
|
||||
try {
|
||||
Import-Module CredentialManager -ErrorAction Stop
|
||||
$credObj = Get-StoredCredential -Target $GiteaCredentialTarget -ErrorAction Stop
|
||||
if ($credObj) {
|
||||
$b64 = [Convert]::ToBase64String(
|
||||
[System.Text.Encoding]::UTF8.GetBytes(
|
||||
"$($credObj.UserName):$($credObj.GetNetworkCredential().Password)"))
|
||||
$authHeader = "Authorization: Basic $b64"
|
||||
}
|
||||
} catch {
|
||||
Write-Warning "[Invoke-RemoteBuild] Could not load PAT from Credential Manager ($GiteaCredentialTarget) — cloning without auth (public repo?)."
|
||||
}
|
||||
}
|
||||
|
||||
if ($authHeader -ne '') {
|
||||
$authCloneCmd = "git -c credential.helper= -c 'http.extraHeader=$authHeader' clone --depth 1 --branch '$CloneBranch'"
|
||||
if ($CloneSubmodules) { $authCloneCmd += ' --recurse-submodules' }
|
||||
$authCloneCmd += " '$CloneUrl' '$GuestLinuxWorkDir'"
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile -Command $authCloneCmd
|
||||
} else {
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath -Command $cloneCmd
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile -Command $cloneCmd
|
||||
}
|
||||
|
||||
# Checkout specific commit if requested
|
||||
if ($CloneCommit -ne '') {
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile `
|
||||
-Command "git -C '$GuestLinuxWorkDir' checkout '$CloneCommit'"
|
||||
}
|
||||
}
|
||||
@@ -254,16 +266,20 @@ if ($GuestOS -eq 'Linux') {
|
||||
} else {
|
||||
$buildCmd = "${envPrefix}cd '$GuestLinuxWorkDir' && make"
|
||||
}
|
||||
Write-Host "[Invoke-RemoteBuild] Running build: $buildCmd"
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath -Command $buildCmd
|
||||
$displayCmd = if ($BuildCommand -ne '') { $BuildCommand } else { 'make' }
|
||||
Write-Host "[Invoke-RemoteBuild] Running build (env vars redacted): cd '$GuestLinuxWorkDir' && $displayCmd"
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile -Command $buildCmd
|
||||
|
||||
# Step 4: Stage artifact tree under $GuestLinuxOutputDir for SCP collection
|
||||
$outDir = $GuestLinuxOutputDir
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile `
|
||||
-Command "rm -rf '$outDir' && mkdir -p '$outDir'"
|
||||
|
||||
$artSrc = if ($GuestArtifactSource -ne '') { $GuestArtifactSource } else { 'dist' }
|
||||
Invoke-SshCommand -IP $IPAddress -User $SshUser -KeyPath $SshKeyPath `
|
||||
-KnownHostsFile $SshKnownHostsFile `
|
||||
-Command "if [ -d '$GuestLinuxWorkDir/$artSrc' ]; then cp -r '$GuestLinuxWorkDir/$artSrc/.' '$outDir/'; elif [ -e '$GuestLinuxWorkDir/$artSrc' ]; then cp '$GuestLinuxWorkDir/$artSrc' '$outDir/'; else echo '[Invoke-RemoteBuild] WARNING: artifact source not found: $artSrc' >&2; fi"
|
||||
|
||||
Write-Host "[Invoke-RemoteBuild] Linux build complete."
|
||||
@@ -432,14 +448,19 @@ try {
|
||||
New-Item -ItemType Directory -Path $archiveDir -Force | Out-Null
|
||||
}
|
||||
$srcPath = Join-Path $workDir $artifactSrc
|
||||
$7zip = 'C:\Program Files\7-Zip\7z.exe'
|
||||
if (Test-Path $7zip) {
|
||||
Write-Host "[Build] Compressing artifacts with 7-Zip..."
|
||||
& $7zip a -mmt=on -mx1 $artifactZip $srcPath 2>&1 | Where-Object { $_ -notmatch '^7-Zip' } | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -ne 0) { throw "7-Zip failed" }
|
||||
if (-not (Test-Path $srcPath)) {
|
||||
Write-Host "[Build] Artifact source '$srcPath' not found — skipping packaging."
|
||||
}
|
||||
else {
|
||||
Compress-Archive -Path $srcPath -DestinationPath $artifactZip -Force
|
||||
$7zip = 'C:\Program Files\7-Zip\7z.exe'
|
||||
if (Test-Path $7zip) {
|
||||
Write-Host "[Build] Compressing artifacts with 7-Zip..."
|
||||
& $7zip a -mmt=on -mx1 $artifactZip $srcPath 2>&1 | Where-Object { $_ -notmatch '^7-Zip' } | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -ne 0) { throw "7-Zip failed" }
|
||||
}
|
||||
else {
|
||||
Compress-Archive -Path $srcPath -DestinationPath $artifactZip -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,14 +504,19 @@ try {
|
||||
if (-not (Test-Path $archiveDir)) {
|
||||
New-Item -ItemType Directory -Path $archiveDir -Force | Out-Null
|
||||
}
|
||||
$7zip = 'C:\Program Files\7-Zip\7z.exe'
|
||||
if (Test-Path $7zip) {
|
||||
Write-Host "[Build] Compressing output with 7-Zip..."
|
||||
& $7zip a -mmt=on -mx1 $artifactZip "$outputDir\*" 2>&1 | Where-Object { $_ -notmatch '^7-Zip' } | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -ne 0) { throw "7-Zip failed" }
|
||||
if (-not (Test-Path $outputDir)) {
|
||||
Write-Host "[Build] Output dir '$outputDir' not found — skipping packaging."
|
||||
}
|
||||
else {
|
||||
Compress-Archive -Path "$outputDir\*" -DestinationPath $artifactZip -Force
|
||||
$7zip = 'C:\Program Files\7-Zip\7z.exe'
|
||||
if (Test-Path $7zip) {
|
||||
Write-Host "[Build] Compressing output with 7-Zip..."
|
||||
& $7zip a -mmt=on -mx1 $artifactZip "$outputDir\*" 2>&1 | Where-Object { $_ -notmatch '^7-Zip' } | ForEach-Object { Write-Host $_ }
|
||||
if ($LASTEXITCODE -ne 0) { throw "7-Zip failed" }
|
||||
}
|
||||
else {
|
||||
Compress-Archive -Path "$outputDir\*" -DestinationPath $artifactZip -Force
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user