Commit Graph
64 Commits
Author SHA1 Message Date
Simone 20e573ccef fix(toolchain): chown /opt/rust after install, not only before
The chown ran before rustup and cargo-audit were installed, so everything
those created under RUSTUP_HOME/CARGO_HOME was left root-owned: only the two
empty directories existing at chown time belonged to ci_build. Measured on the
previous snapshot: 18350 root-owned paths, including cargo/registry. Every Rust
build with external dependencies failed with "Permission denied (os error 13)".

Re-assert ownership after the installs, and assert writability rather than mere
existence -- test -x on the binaries could not catch this, so a broken template
passed its own build and failed in consumers' jobs instead.

Also wire the toolchain for non-login shells. The orchestrator runs build
commands via paramiko exec_command + `sh -c`, which never sources
/etc/profile.d, so profile.d alone was not enough: add RUSTUP_HOME/CARGO_HOME
to /etc/environment (read by pam_env at SSH session open) and symlink the
rustup proxies into /usr/local/bin.
2026-07-22 14:08:40 +02:00
Simone f91039b946 fix(toolchain): disable WU scan tasks via cmdlets, not schtasks.exe
schtasks.exe /Change on a non-existent task writes to stderr and exits 1.
Inside the disk-cleanup function (EAP=Stop, wrapped by the exit-code-sensitive
prepare-win cleanup invoker), that leaked $LASTEXITCODE=1 all the way to the
result marker — DISM runs via Start-Process and does not reset it — so the
step failed with "Disk cleanup failed (exit 1)" even though everything worked.
On a freshly-deployed WS2025 the UpdateOrchestrator "Schedule Scan" task does
not exist, so this fired every run.

Replace the schtasks loop with Get-ScheduledTask | Disable-ScheduledTask,
which no-ops silently on a missing task and sets no process exit code.

Follow-up to fb5de6f; applied to both toolchains.
2026-06-10 00:52:25 +02:00
Simone fb5de6f59f fix(toolchain): pin WU disabled across the DISM /ResetBase window
The disk-cleanup function stopped wuauserv before DISM /StartComponentCleanup
/ResetBase but only re-enforced Start=4 AFTER it. /ResetBase drives heavy CBS
servicing (TiWorker); during that window WaaSMedicSvc woke, flipped wuauserv
Start back to Manual, and a "Schedule Scan" task started it. If the pass was
interrupted there (reboot/crash), the template was left with WU running and
Manual startup — a half-prepared state where Windows Update keeps firing on a
supposedly-locked-down build template.

Move the lockdown ahead of DISM: set wuauserv Start=4, apply the
WaaSMedicSvc registry write-deny ACL (the only reliable lever — the service
is protected and cannot itself be disabled), and disable the WindowsUpdate /
UpdateOrchestrator scan tasks, all BEFORE /ResetBase rather than only after.
The post-DISM re-enforce stays as a belt-and-suspenders check.

Applied identically to the WinBuild2025 and WinBuild2022 toolchains.
2026-06-10 00:48:00 +02:00
Simone de0f5e6c68 fix(toolchain): refresh dotnet-install.ps1 pinned hash
Microsoft rotated the unversioned https://dot.net/v1/dotnet-install.ps1, so
the pinned SHA256 was stale and the toolchain aborted ("Possible MITM or
wrong installer version"). Independently re-downloaded the official script
(builds.dotnet.microsoft.com) — its hash matches the guest's observed
value, confirming it is the legitimate current script, not tampering.

Update the pin in both WinBuild2025 and WinBuild2022 toolchains to
6585899AED55FF6AE13DBE1E8C3B878F2D00433520E7EFBE250B75DB948B7DA9 and note
that this pin must be refreshed whenever MS updates the script in place.
2026-06-09 21:02:23 +02:00
Simone 43442eecd4 feat(template): add GTK4/PyGObject/Xvfb toolchain deps; always apt-update
Step 4a installs python3-gi gir1.2-gtk-4.0 xvfb for headless PyGObject
GUI tests, with import-gi and Xvfb assertions.

Step 1 now always runs apt-get update; --skip-update only skips the
(slow) full upgrade. Previously --skip-update skipped the index refresh
too, so a fresh package (gir1.2-gtk-4.0/xvfb) could not be located.
2026-06-06 12:55:22 +02:00
Simone 387f93f3c6 fix(template): make prepare-win robust without prior Deploy run
- WinRM MaxProcessesPerShell: apply 100 if below threshold before asserting
- DesktopHeap SharedSection: apply 4096 KB registry value if below threshold before asserting
- Replace cleanmgr (hangs in WinRM Session 0, no window station) with direct
  PowerShell cleanup for dumps, WER files and Recycle Bin; DISM already covers
  component store and WU cache
- vcpkg git clone/checkout: wrap with EAP=Continue to suppress PS5.1
  NativeCommandError on git stderr (gotcha #3 from AGENTS.md)
- template.py: filter CI_EXITCODE:N marker from displayed output
- ci-static-ip.ps1: switch from vmware-rpctool (removed in recent Tools) to
  vmtoolsd --cmd; use temp-file redirect to capture output from native cmd
2026-05-25 22:03:49 +02:00
Simone 5867fe1e12 feat(template): cleanup-after-update + ruff fixes
Move disk cleanup out of the Windows Update loop:
- PS scripts: extract Invoke-DiskCleanup function, add -CleanupOnly switch
  for standalone post-update cleanup pass.
- Python command: always pass -SkipCleanup:$true during WU loop; after
  loop exits 0, run a separate -CleanupOnly invocation (skipped if
  --skip-cleanup). Fails fast if cleanup-only returns nonzero.
- Tests: 3 new tests for cleanup-runs-after-loop, skip-cleanup suppresses
  it, and cleanup-failure propagates as ClickException.
- ruff --fix: remove unused shutil import, sort imports, fix UP037/UP035.
2026-05-24 02:41:15 +02:00
Simone 5014c86f26 fix(templates): import PSWSMan module on Linux before New-PSSession
Without Import-Module PSWSMan the native WSMan library isn't registered
and New-PSSession hangs/fails silently. Import guarded by $IsWindows so
Windows PS 5.1 is unaffected.
2026-05-24 00:53:19 +02:00
Simone a464484c91 fix(templates): skip TrustedHosts config on Linux host
WSMan TrustedHosts is a Windows WinRM client concept — does not exist
on Linux. Guard the configure+restore blocks with $isLinuxHost so the
Prepare scripts run without elevation errors from a Linux host.
-SkipCACheck/-SkipCNCheck in sessionOptions is sufficient on Linux.
2026-05-24 00:50:25 +02:00
Simone 68df07c623 fix(templates): drop -SkipRevocationCheck from New-PSSessionOption
Parameter not available in PS 7 on Linux. -SkipCACheck -SkipCNCheck
sufficient for self-signed lab certs; revocation check is irrelevant
for self-signed certs regardless.
2026-05-24 00:48:13 +02:00
Simone 773ee2cf3d fix(templates): replace Test-NetConnection with TcpClient in Prepare scripts
Test-NetConnection is Windows-only. Replace with cross-platform TcpClient
async-connect helper (same pattern as Measure-CIBenchmark.ps1) so the
Prepare scripts run on the Linux host under PowerShell.
2026-05-24 00:46:19 +02:00
Simone 5aa2d9c697 feat(templates): install ci-static-ip/ci-report-ip via Prepare+Install scripts
Windows (Prepare-WinBuild2025/2022): read ci-static-ip.ps1 from
guest-setup/windows/ on the host, push content over WinRM, register the
CI-StaticIp scheduled task (AtStartup/SYSTEM). Adds StaticIpTask and
StaticIpScript post-setup assertions.

Linux (Install-CIToolchain-Linux2404.sh): embed ci-report-ip.sh and
ci-report-ip.service content inline via heredoc tee, replacing the broken
cp-from-relative-path approach (the script runs inside the VM where the
host-side guest-setup/ directory does not exist).
2026-05-24 00:37:07 +02:00
Simone 4228578a42 feat(ip-pool): add guest-side static-IP boot scripts
template/guest-setup/linux/ci-report-ip.sh
  Updated version: checks guestinfo.ip-assignment first (static path),
  falls back to DHCP detection if absent.  Applies static IP before
  network-online.target so SSH starts on the correct address immediately.

template/guest-setup/linux/ci-report-ip.service
  Drops 'network.target' from After= — runs before network is up so the
  static IP is configured before SSH/other services start.

template/guest-setup/windows/ci-static-ip.ps1
  Reads guestinfo.ip-assignment via vmware-rpctool at system startup (SYSTEM
  account Task Scheduler task).  Disables DHCP, applies static IP+gateway,
  reports back via guestinfo.ci-ip.  No-op when ip-assignment is absent.

template/Install-CIToolchain-Linux2404.sh
  Step 7b now copies scripts from guest-setup/linux/ instead of embedding
  the old DHCP-only inline script.
2026-05-24 00:27:10 +02:00
Simone 93f5a88f77 fix(templates): bump WinRM quotas + desktop heap for parallel Win builds
Parallel MSBuild fan-out (e.g. ns7zip x86/x64/x86-ansi) over pypsrp
Linux→Win fails with MSBuild MSB6003 / Win32 1816 'Not enough quota'
because two default guest limits are too tight for concurrent native
processes via WinRM:

  - Plugin Microsoft.PowerShell MaxMemoryPerShellMB = 150 MB
    (pypsrp uses the plugin endpoint, not the Shell endpoint that
    Deploy was previously bumping)
  - Non-interactive desktop heap SharedSection 3rd field = 768 KB
    (Session 0 csrss; CreateProcess fails when 3+ cl.exe spawn)

Pre-migration Win→Win went through Invoke-Command on PSSession with
quotas inherited from the local process, so the limits never bit.

Changes:
  - Deploy-WinBuild2025.ps1 / Deploy-WinBuild2022.ps1: also set the
    plugin-level MaxMemoryPerShellMB=2048, bump MaxProcessesPerShell
    25→100, patch SharedSection 3rd field 768→4096 (reboot needed for
    csrss to pick up, applied by post-install shutdown).
  - Install-CIToolchain-WinBuild2025/2022.ps1: add Assert-Step for
    plugin quota, MaxProcessesPerShell≥100, SharedSection≥4096; fail
    hard if any are under threshold.
  - docs/WINDOWS-TEMPLATE-SETUP.md: new "WinRM quotas e desktop heap"
    section explaining the diagnosis + one-shot patch for legacy
    templates; updated Step 3 validation row + troubleshooting entry.
  - AGENTS.md: error #13 with symptom, root cause, and pointer to docs.
2026-05-21 23:35:57 +02:00
Simone 8b18d56eec ci(lint): add CmdletBinding and ShouldProcess support to ISO creation functions for safer execution 2026-05-14 18:34:03 +02:00
Simone fcf5dceeed ci(lint): enhance PSScriptAnalyzer settings and suppress false positives; improve error handling in scripts 2026-05-14 18:34:03 +02:00
Simone cb24c3cfad ci(lint): update PSScriptAnalyzer settings and suppress warnings for plain-text passwords in templates 2026-05-14 18:34:03 +02:00
Simone 6d04e8e084 feat: update installer SHA256 hashes for Python, DotNetInstallScript, SevenZip, and NodeJS 2026-05-13 10:41:42 +02:00
Simone b30d905487 nice-to-have: implement all 6 tier items
- Get-CIJobSummary.ps1: already present with full implementation (marked done)
- Get-BuildArtifacts.ps1: add -JobId/-Commit params; Write-ArtifactManifest writes
  manifest.json (name, size, sha256, commit, jobId) after both Linux and Windows
  artifact collection branches
- Invoke-CIJob.ps1: add -GuestCPU/-GuestMemoryMB params; insert post-clone VMX
  override block (numvcpus/memsize rewrite) before vmrun start; pass -JobId/-Commit
  to Get-BuildArtifacts calls
- Watch-RunnerHealth.ps1: add -GiteaUrl/-GiteaCredentialTarget params; optional
  GET /api/v1/admin/runners check in Running branch warns if 0 online runners
- Install-CIToolchain-WinBuild2025.ps1: fill SHA256 hashes for Python 3.13.3,
  7-Zip 26.01, Node.js 22.14.0, dotnet-install.ps1
- Measure-CIBenchmark.ps1: add deltaKB field (linked-clone disk footprint in KB)
  measured post-clone; added to result object and summary Format-Table
2026-05-13 10:38:49 +02:00
Simone a637923fd6 feat(low): sprint 4 Low items tutti 5 completati
codice:
- template/Validate-SetupState.ps1: docblock HTTP/Basic -> HTTPS/Basic, port 5986
- scripts/Validate-HostState.ps1 (nuovo): check ACL SSH key ci_linux, Credential Manager
  target BuildVMGuest, struttura dir F:\CI\, vmrun.exe raggiungibile

docs:
- docs/TEST-PLAN-v1.3-to-HEAD.md sezione 3.6: campi JSONL corretti (cloneSec/startSec/
  ipSec/winrmSec/destroySec/totalBootSec) per riflettere output reale di Measure-CIBenchmark.ps1
- docs/CI-FLOW.md tabella failure: 'partial artifacts' -> Get-GuestDiagnostics a diagnostics/
- docs/CHANGELOG.md (nuovo): log reverse-cronologico di tutti gli sprint completati
- plans/final-master-plan.md: tutti i Low marcati done
2026-05-13 10:26:08 +02:00
Simone d562ba90c0 fix(template): clear machine-id in Prepare-LinuxBuild2404 (Step 7b)
Each Ubuntu clone derived from the same snapshot shared an identical
machine-id, causing systemd-networkd to use the same DHCP client-id
and receive the same NAT IP  triggering IP collision failures.

Step 7b truncates /etc/machine-id and removes /var/lib/dbus/machine-id
before the snapshot is taken. On first boot each clone generates a
fresh machine-id from /dev/urandom -> unique DHCP client-id -> unique IP.
2026-05-12 22:33:55 +02:00
Simone a797588e80 feat(sprint4): operational hardening, diagnostics, VMDK SHA256, runbook
Task 4.1: Invoke-CIJob.ps1 pre-clone disk gate (needs 10 GB free), JobId/ExtraGuestEnv
          pattern validation, redacted command logger (already included via _Common.psm1).
Task 4.2: Get-GuestDiagnostics helper invoked from catch block (best-effort, no throw).
Task 4.3: UseSharedCache wired through composite action and orchestrator.
Task 4.4: SSH known_hosts in F:\CI\State\known_hosts for CI jobs; accept-new for templates.
Task 4.5: Deploy-LinuxBuild2404.ps1 verifies Ubuntu VMDK SHA256 before import.
Task 4.6: RUNBOOK.md consolidated template-refresh section: stop runner, backup, boot,
          KMS reactivation, Prepare-*, shutdown, snapshot, Validate-DeployState, smoke,
          update config, retain prior snapshot 7 days, rollback procedure.
Validate-SetupState.ps1: minor lint fixes and docblock updates.
Wait-VMReady.ps1: Get-BuildArtifacts.ps1: hardening alignment with Sprint 4 objectives.
2026-05-12 21:12:51 +02:00
Simone dcc93d80d8 feat(sprint3): Invoke-VmrunBounded, Get-GuestIPAddress, transport and concurrency hardening
H4: Invoke-VmrunBounded added to _Common.psm1 (Start-Process + Wait-Process + taskkill on
    timeout, returns {ExitCode;Output;TimedOut;ElapsedSeconds}). Wired in Invoke-CIJob.ps1
    for vmrun start (180s) and Remove-BuildVM.ps1 for stop/deleteVM (60s/90s).
H5: Cleanup-OrphanedBuildVMs.ps1 removes stale vm-start.lock (>30 min). ValidateRange
    lowered to 0 to allow emergency -MaxAgeHours 0. Invoke-RetentionPolicy.ps1 same.
H8: _Transport.psm1 SSH hardening: StrictHostKeyChecking=accept-new, F:\CI\State\known_hosts.
H9: Validate-DeployState.ps1 Linux branch added: checks ci-report-ip.service enabled,
    ci-report-ip.sh executable via SSH. New params: -GuestOS, -SshKeyPath, -SshUser.
H12: Get-GuestIPAddress extracted into _Common.psm1 (guestinfo.ci-ip primary, getGuestIPAddress
     fallback). Invoke-CIJob.ps1 Phase 3b replaced with single call. Measure-CIBenchmark.ps1
     updated to match.
Also: _Common.psm1 adds Write-CIRedactedCommand and ConvertTo-SafeShellSingleQuotedString.
     Pester suite updated: 30/30 pass.
2026-05-12 21:12:33 +02:00
Simone e3c4bbc86e refactor(§7.5): rinomina Setup-* Install-CIToolchain-* (WinBuild2025/2022/Linux2404)
- template/Setup-WinBuild2025.ps1  Install-CIToolchain-WinBuild2025.ps1
- template/Setup-WinBuild2022.ps1  Install-CIToolchain-WinBuild2022.ps1
- template/Setup-LinuxBuild2404.sh  Install-CIToolchain-Linux2404.sh

Aggiornati tutti i riferimenti in: Prepare-WinBuild2025/2022, Prepare-LinuxBuild2404,
Deploy-WinBuild2025/2022/LinuxBuild2404, Validate-DeployState, Validate-SetupState,
README.md, TODO.md, docs/WINDOWS-TEMPLATE-SETUP.md, docs/LINUX-TEMPLATE-SETUP.md,
docs/TEST-PLAN-v1.3-to-HEAD.md, gitea/actions/local-ci-build/action.yml.

§7 chiuso (5/5 done).
2026-05-11 22:48:33 +02:00
Simone c8fe7cebf6 fix(template): skip KMS activation if Windows already activated 2026-05-11 21:59:16 +02:00
Simone 2289d078d8 fix(template): re-affirm autologin after reboot before snapshot 2026-05-11 21:57:32 +02:00
Simone 3030a0fed2 feat(template): reboot VM before final shutdown+snapshot 2026-05-11 21:11:21 +02:00
Simone 76c7ceaa72 fix(template): use absolute \ path before PATH refresh (git not yet in session PATH) 2026-05-11 21:01:24 +02:00
Simone 902242cbcf fix: suppress Test-NetConnection progress bar noise (\Continue = SilentlyContinue) 2026-05-11 20:52:22 +02:00
Simone f3d80f4579 perf(template): replace all IWR -OutFile with WebClient.DownloadFile (10 occurrences) 2026-05-11 20:47:00 +02:00
Simone 45a5c2e48c perf(template): NSIS download use WebClient instead of IWR (no progress-bar overhead) 2026-05-11 20:44:50 +02:00
Simone 28e8c91cc3 fix(template): NSIS download fix meta-refresh regex to match downloads.sf.net token URL 2026-05-11 20:38:36 +02:00
Simone 2195c0fd1d fix(template): NSIS download browser User-Agent + PE magic bytes guard 2026-05-11 20:32:55 +02:00
Simone 1d3def4816 chore(template): bump PS7 7.6.1, NSIS 3.12, gh CLI 2.92.0 2026-05-11 20:29:23 +02:00
Simone eaebd28769 refactor(template): promote PS7/NSIS/gh CLI from Tier-2 to Tier-1 (Step 11) 2026-05-11 20:26:06 +02:00
Simone 8ec3a80bb1 feat(template): add -SkipTier2 switch to skip Tier-2 toolchain installation
Setup-WinBuild2025.ps1:
  - New [switch] \ param (after \)
  - Step 12 block wrapped with if (\) { skip-message } else { ... }
  - Final gate Tier-2 Assert-Step wrapped with if (-not \)

Prepare-WinBuild2025.ps1:
  - New [switch] \ param forwarded to Setup via setupArgs

Validate-SetupState.ps1:
  - New [switch] \ param
  - \ passed into both remote scriptblocks via -ArgumentList
  - Tier-2 Chk calls guarded with if (-not \) in both blocks
2026-05-11 20:13:58 +02:00
Simone b24510962e feat(template): §6.6 Tier-2 toolchain PS7/NSIS/CMake/Node.js/WiX/gh CLI/Sysinternals/vcpkg
Step 12 in Setup-WinBuild2025.ps1 installs all 8 Tier-2 tools:
  - PowerShell 7.4.7 LTS (pwsh.exe)
  - NSIS 3.10 (makensis.exe)
  - CMake 3.31.6 (cmake.exe)
  - Node.js 22.14.0 LTS (node.exe + npm)
  - WiX 4.0.5 via dotnet tool (wix.exe, C:\BuildTools\Wix\)
  - GitHub CLI 2.67.0 (gh.exe)
  - Sysinternals Suite (C:\BuildTools\Sysinternals\, extracted via 7-Zip)
  - vcpkg HEAD shallow clone + bootstrap (C:\BuildTools\vcpkg\)

All tools added to Machine PATH; idempotent (binary-presence check).
Hash entries in \ ready for SHA256 pinning.
knownTempFiles extended; Final gate Assert-Step added for all 8 binaries.

Prepare-WinBuild2025.ps1: 7 new params + pass-through to Setup.
Validate-SetupState.ps1: Tier-2 checks in both main + re-run scriptblocks.
TODO.md: §6.6 [~] -> [x], Sprint 11 summary.
2026-05-11 20:04:50 +02:00
Simone dac5a74d08 feat(linux): add Ubuntu 24.04 template VM automation scripts
Deploy-LinuxBuild2404.ps1 (host-side):
- Downloads Ubuntu 24.04 cloud VMDK (cached in F:\CI\ISO\)
- Generates cloud-init seed ISO (nocloud + guestinfo backup datasource)
- user-data: user+SSH key only  no packages/runcmd, all provisioning
  delegated to Prepare/Setup (removed -MinimalConfig, now always minimal)
- Assembles VMX, powers on VM, waits for cloud-init completion via SSH
- Removes seed ISO from VMX after first boot (ide1:0 disabled)
- Next-steps message uses correct -VMIPAddress parameter

Prepare-LinuxBuild2404.ps1 (host-side):
- Powers on template VM, waits for SSH readiness
- Copies Setup-LinuxBuild2404.sh into guest, runs it with sudo
- Validates setup result (all tools in PATH, dirs, sshd, swap off)
- Takes snapshot BaseClean-Linux (cold, VM shut down before snapshot)
- -NoMingw switch to skip mingw-w64 cross-compiler installation

Setup-LinuxBuild2404.sh (guest-side):
- apt update/upgrade, build-essential, gcc, g++, clang, cmake, ninja
- python3, pip3, venv; git, p7zip-full, curl, wget, ca-certificates
- Optional .NET SDK (--dotnet), mingw-w64 cross-compiler (--no-mingw to skip)
- /opt/ci/{build,output,scripts,cache} dirs (ci_build ownership)
- SSH hardening (PasswordAuthentication no, PubkeyAuthentication yes)
- Swap disable (swapoff -a + fstab), MAC-agnostic netplan for linked clones
- ci-report-ip systemd service (guestinfo.ci-ip reporter)
- apt auto-update disabled; full validation gate at end
2026-05-11 18:34:38 +02:00
Simone c0501b4d97 chore: Bump 7-Zip 24.07→26.01, Git 2.47→2.54 across docs + setup
Setup-WinBuild2025.ps1: default SevenZipVersion '24.07' → '26.01'
TODO.md: Tier-1 table + bullet list updated to current versions
TEST-PLAN: expected version strings and checklist updated
2026-05-10 22:32:26 +02:00
Simone a397c15df6 fix(template): Add 7-Zip to machine PATH registry (not just session PATH)
Root cause: Assert-Step 'Final' 'dotnet/python/msbuild' block contains a
registry PATH refresh that overwrites $env:PATH, discarding the temporary
session injection added in §6.6. Next assertion (7z command available) then fails.

Fix: use SetEnvironmentVariable('PATH', ..., 'Machine') to permanently register
C:\Program Files\7-Zip in the system PATH — same pattern used for dotnet and MSBuild.
Follow-up registry refresh ensures $env:PATH is also current.
2026-05-10 21:50:48 +02:00
Simone 9926719d73 fix(template): Fix Git skip path + 7-Zip PATH injection
Two root causes:
1. Git skip check used C:\BuildTools\Git but Git installs to
   C:\Program Files\Git (default). Changed $gitDir to correct path.

2. 7-Zip MSI does not register in system PATH. Registry refresh
   (GetEnvironmentVariable Machine+User) was picking up empty result.
   Fixed: inject sevenZipDir directly into $env:PATH if not present.
2026-05-10 21:42:29 +02:00
Simone 7c1cbd34a4 fix(template): Always refresh PATH after git/7z check, not just after install
PATH refresh was inside the 'else' block (only during fresh install).
If tools already exist from previous run, PATH not refreshed → validation fails.

Move PATH refresh outside if/else for both Git and 7-Zip:
- Already installed: skip download+install, but refresh PATH anyway
- Fresh install: download+install, then refresh PATH

Ensures validations can always resolve git/7z commands, even on retry runs.
2026-05-10 21:35:06 +02:00
Simone b5c92d295c fix(template): Refresh PATH after 7-Zip MSI installation
7-Zip MSI installer adds to system PATH but PowerShell session doesn't
see it until PATH is refreshed. Refresh via:
  $env:PATH = [System.Environment]::GetEnvironmentVariable('PATH', 'Machine') + ';' +
              [System.Environment]::GetEnvironmentVariable('PATH', 'User')

Same pattern already used for Git installer. Fixes validation error:
  '7z command resolvable' now passes after installation.
2026-05-10 21:29:59 +02:00
Simone 199264e42d fix(template): Handle Git version tag vs filename mismatch
GitHub release tag: v2.54.0.windows.1
Filename in release: Git-2.54.0-64-bit.exe (no .windows.1)

Extract base version for filename via regex:
  $gitVersionBase = $GitVersion -replace '\.windows\.\d+$', ''

URL now correctly formed as:
  .../download/v2.54.0.windows.1/Git-2.54.0-64-bit.exe

Reverted GitVersion back to '2.54.0.windows.1' (needed for tag).
2026-05-10 21:26:00 +02:00
Simone c68e14cb8d fix(template): Correct Git version to 2.54.0 (no .windows.1 suffix)
GitHub release tag is v2.54.0, not v2.54.0.windows.1.
Filename format: Git-2.54.0-64-bit.exe
2026-05-10 21:25:29 +02:00
Simone 1f59d9cc45 fix(template): Update Git for Windows to 2.54.0 + add SHA256 hash
Version 2.47.0.windows.1 no longer available on GitHub (network errors).
Updated to latest stable 2.54.0.windows.1 with SHA256 hash pinning (§1.3).

Hash: 2b96e7854f0520f0f6b709c21041d9801b1be44d5e1a0d9fa621b2fbc40f1983
Source: https://github.com/git-for-windows/git/releases

This fixes download failures in Setup-WinBuild2025 Step 11 (Tier-1 Toolchain).
2026-05-10 21:24:18 +02:00
Simone 00708190f2 test(validation): Add Git + 7-Zip checks to Validate-SetupState
§6.6 Tier-1 Toolchain (Git for Windows, 7-Zip) now included in final
state validation. Checks:
- 'Git for Windows (git.exe in PATH)'
- '7-Zip (7z.exe in PATH)'

Added to both initial validation pass and re-validation pass (post-remediation).
2026-05-10 21:01:46 +02:00
Simone 55280b476f feat(template): Add Step 11 Tier-1 Toolchain — Git + 7-Zip installation
Implement §6.6 minimal viable product: install Git for Windows and 7-Zip
to the template VM. Critical prerequisites for §3.3 (In-VM Git clone).

Step 11 additions:
- Git for Windows (latest LTS configurable) — silent installer, adds to PATH
- 7-Zip (latest stable configurable) — MSI installer to Program Files
- SHA256 hash pinning for both tools (currently unpinned, warn at runtime)
- Assert-Step validation for git/7z command availability
- Final pre-snapshot gate checks for both tools + cleanup of installers

Parameters added:
- -GitVersion (default: 2.47.0.windows.1)
- -SevenZipVersion (default: 24.07)

Rationale:
- Enables §3.3 in-VM Git clone (git clone directly in VM instead of host-zip-transfer)
- Supports cross-platform builds and multi-tool workflows
- Fallback from §3.2 7-Zip compression finally available in template
- Positions for future expansion of Tier-1 tools (NSIS, CMake, Node.js, WiX, etc.)

Updated documentation:
- Setup-WinBuild2025.ps1 docstring: Step 11 added to list + step ordering rationale
- Removed NOTE about Git not being installed
- Final validation now checks: 9 assertions (was 7)
2026-05-10 20:48:43 +02:00
Simone e7ffc96f3d feat(template): add WinBuild2022 script variants (Deploy/Prepare/Setup) 2026-05-10 18:17:47 +02:00
Simone bfb9cbfc03 feat(setup): Step 3b — Windows KMS activation via slmgr /skms + /ato
Activates Windows against kms8.msguides.com before Windows Update runs
so WU sees correct license state. Uses cscript //NoLogo to route slmgr
output to stdout (dialogs hang in WinRM sessions). Best-effort: activation
failure emits a warning but does not abort Setup — CI builds function
within the grace period.

Placed between Step 3 (WinRM/network confirmed) and Step 4 (user creation).
2026-05-10 17:27:23 +02:00