fix: apply all FIX-TODO items (P0/P1/P2)

P0 bugs:
- Invoke-CIJob.ps1: skip --depth 1 when $Commit specified (shallow clone
  + checkout specific commit was silently failing)
- Get-BuildArtifacts.ps1: check .Length -eq 0 not rounded sizeKB (false
  fail on artifacts smaller than 50 bytes)
- build-nsis.yml: upgrade upload-artifact v3 -> v4 (v3 deprecated)

P0 security:
- Remove hardcoded default password CIBuild!ChangeMe2026 from all scripts,
  README, TODO; prompt Read-Host -AsSecureString at runtime instead
- Setup-TemplateVM.ps1: replace `net user $u $p /add` (password in argv /
  audit log 4688) with New-LocalUser + local ConvertTo-SecureString
- Prepare-TemplateSetup.ps1: save and restore WSMan AllowUnencrypted +
  TrustedHosts in finally block (was permanently mutating host WinRM config)
- Setup-TemplateVM.ps1: remove duplicate MaxMemoryPerShellMB (winrm set
  + Set-Item both setting same value)

P1 doc (stale Host-Only / VMnet11 era):
- Setup-TemplateVM.ps1: rewrite NETWORK REQUIREMENT block + final steps
  (system uses VMnet8 NAT permanently, not VMnet11 Host-Only)
- Invoke-CIJob.ps1 Phase 1 comment: correct network model
- ARCHITECTURE.md: remove Git from toolchain list (not installed); clarify
  zip-transfer rationale (no PAT in VM, not network isolation)
- BEST-PRACTICES.md: rewrite Step 8 as NAT topology verification

P1 minor:
- Invoke-RemoteBuild.ps1: remove wasted first New-Item (created then
  immediately removed and recreated)
- Wait-VMReady.ps1: remove unused $elapsed; simplify try/catch around
  native command (exit codes don't throw)
- Install-Runner.ps1: add deprecation notice pointing to Setup-Host.ps1

P2 operational:
- Add scripts/Cleanup-OrphanedBuildVMs.ps1 with -WhatIf support
- Get-BuildArtifacts.ps1 -IncludeLogs: add -Recurse (msbuild logs in subdir)
- Add gitea/workflows/lint.yml (PSScriptAnalyzer on .ps1 push/PR)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Simone
2026-05-09 00:39:52 +02:00
parent ecd79c2219
commit f373c0c24b
16 changed files with 318 additions and 175 deletions
+33 -33
View File
@@ -22,18 +22,17 @@
╔══════════════════════════════════════════════════════════════════════╗
║ NETWORK REQUIREMENT DURING SETUP ║
║ The VM must have internet access while this script runs so it can ║
║ download Windows Updates and tool installers. Configure the VM NIC
║ to VMnet8 (NAT) before running setup, then switch back to VMnet11
(Host-Only) BEFORE taking the BaseClean snapshot.
║ download Windows Updates and tool installers. The VM NIC must be
set to VMnet8 (NAT) — keep it on NAT permanently (builds use NAT
for pip/nuget downloads at runtime).
╚══════════════════════════════════════════════════════════════════════╝
After this script completes:
1. Switch VM NIC from VMnet8 (NAT) → VMnet11 (Host-Only) in VMware
Workstation: VM → Settings → Network Adapter → Custom: VMnet11
2. Shut down the VM (Start → Shut down)
3. In VMware Workstation: VM → Snapshot → Take Snapshot
1. Shut down the VM (Start → Shut down)
The VM stays on VMnet8 (NAT) — internet access is required for builds.
2. In VMware Workstation: VM → Snapshot → Take Snapshot
Name it exactly: BaseClean
4. Power off the VM and leave it powered off permanently
3. Power off the VM and leave it powered off permanently
.PARAMETER SkipWindowsUpdate
Skip the Windows Update step (useful if updates were already applied).
@@ -50,9 +49,10 @@ param(
[string] $BuildUsername = 'ci_build',
# Password for the build account.
# IMPORTANT: Change this to a strong password and store it in
# Windows Credential Manager on the HOST as target "BuildVMGuest".
[string] $BuildPassword = 'CIBuild!ChangeMe2026',
# Must be supplied by the caller (Prepare-TemplateSetup.ps1 prompts interactively).
# Store the same password in Windows Credential Manager on the HOST as target "BuildVMGuest".
[Parameter(Mandatory)]
[string] $BuildPassword,
# .NET SDK channel to install (should match the host SDK version)
[string] $DotNetSdkVersion = '10.0',
@@ -187,11 +187,9 @@ winrm set winrm/config/service '@{AllowUnencrypted="true"}' | Out-Null
winrm set winrm/config/service/auth '@{Basic="true"}' | Out-Null
# Increase shell memory and timeout limits for long builds
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="2048"}' | Out-Null
winrm set winrm/config/winrs '@{MaxProcessesPerShell="25"}' | Out-Null
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048 -Force 3>$null
Set-Item WSMan:\localhost\Shell\IdleTimeOut 7200000 -Force 3>$null # 2 hours
Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048 -Force 3>$null
Set-Item WSMan:\localhost\Shell\IdleTimeOut 7200000 -Force 3>$null # 2 hours
# Ensure WinRM starts automatically
Set-Service -Name WinRM -StartupType Automatic 3>$null
@@ -202,9 +200,10 @@ Write-Host "WinRM configured."
# ── Step 2: Firewall ──────────────────────────────────────────────────────────
Write-Step "Disabling Windows Firewall (all profiles) — isolated lab VM"
# Disable all firewall profiles entirely. This VM lives on a Host-Only network
# (VMnet11) with no external exposure, so full disable is acceptable and avoids
# any rule-order or profile-classification issues that would block WinRM/ICMP.
# Disable all firewall profiles entirely. This VM lives on VMnet8 NAT behind
# the VMware NAT gateway with no inbound exposure from outside the host, so
# full disable is acceptable and avoids profile-classification issues blocking
# WinRM/ICMP from the host.
Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled False
Write-Host "Windows Firewall disabled on all profiles."
@@ -216,11 +215,16 @@ if ($existingUser) {
Write-Host "User '$BuildUsername' already exists — skipping creation."
}
else {
# Use net user instead of New-LocalUser: the LocalAccounts cmdlets have a known
# bug where SecureString deserialized over WinRM causes InvalidPasswordException.
$netResult = & net user $BuildUsername $BuildPassword /add /y 2>&1
if ($LASTEXITCODE -ne 0) {
throw "Failed to create user '$BuildUsername': $netResult"
# Convert to SecureString locally (inside the VM session) to avoid exposing
# the password as a process argument visible in audit log event 4688.
$secPwd = ConvertTo-SecureString $BuildPassword -AsPlainText -Force
try {
New-LocalUser -Name $BuildUsername -Password $secPwd `
-PasswordNeverExpires -Description 'CI build account' `
-ErrorAction Stop | Out-Null
}
catch {
throw "Failed to create user '$BuildUsername': $_"
}
Write-Host "User '$BuildUsername' created."
}
@@ -639,21 +643,17 @@ Write-Host "============================================================" -Foreg
Write-Host ""
Write-Host " MANDATORY NEXT STEPS:"
Write-Host ""
Write-Host " 1. SWITCH NIC TO HOST-ONLY (critical before snapshot!):"
Write-Host " VMware Workstation -> VM -> Settings -> Network Adapter"
Write-Host " Change from: VMnet8 (NAT)"
Write-Host " Change to: Custom: VMnet11"
Write-Host " 1. Shut down this VM: Start -> Shut down"
Write-Host " (Keep NIC on VMnet8 NAT — internet is required for builds)"
Write-Host ""
Write-Host " 2. Shut down this VM: Start -> Shut down"
Write-Host ""
Write-Host " 3. Take snapshot in VMware Workstation:"
Write-Host " 2. Take snapshot in VMware Workstation:"
Write-Host " VM -> Snapshot -> Take Snapshot"
Write-Host " Name it EXACTLY: BaseClean"
Write-Host ""
Write-Host " 4. Leave VM powered off permanently."
Write-Host " 3. Leave VM powered off permanently."
Write-Host ""
Write-Host " 5. On the HOST - store credentials in Windows Credential Manager:"
Write-Host " 4. On the HOST - store credentials in Windows Credential Manager:"
Write-Host " New-StoredCredential -Target 'BuildVMGuest' -UserName '$BuildUsername' ``"
Write-Host " -Password '$BuildPassword' -Persist LocalMachine"
Write-Host " -Password '<your-build-password>' -Persist LocalMachine"
Write-Host " (Run in an elevated PowerShell with CredentialManager module)"
Write-Host ""