Commit Graph

240 Commits

Author SHA1 Message Date
Simone 435ccba06f docs(AGENTS): add machine-id Linux DHCP collision as known error #11 2026-05-12 22:30:18 +02:00
Simone 74331ac301 fix(diagnostics): use StrictHostKeyChecking=no for Linux guest-diag SSH
Diagnostics is best-effort. Using accept-new without UserKnownHostsFile
caused the system known_hosts (~/.ssh/known_hosts) to be consulted,
which holds a stale key from a previous clone of the same IP.
Switch to no+NUL (same as Wait-VMReady) to avoid false host-key errors.
2026-05-12 22:29:57 +02:00
Simone 31a040682e fix(linux): purge stale known_hosts entry before first SSH on each clone
Each Linux BuildVM clone gets a new SSH host key for the same
NAT IP, causing 'host key has changed' errors with accept-new mode.

After IP detection, ssh-keygen -R removes the old entry from the
CI-local known_hosts file (F:\CI\State\known_hosts by default)
before Phase 4/5 make any SSH connection. The file is created if
it does not exist yet. Windows jobs are unaffected.
2026-05-12 22:23:33 +02:00
Simone d275f149a6 docs(burnin-dummy): update README for Linux build support 2026-05-12 22:16:31 +02:00
Simone f765f3e74b feat(burnin): add build.sh for Linux guest + Start-BurnInTest-Linux.ps1
gitea/burnin-dummy/build.sh: bash equivalent of build.ps1 (sleep 30,
writes dist/build-info.txt). Needed because powershell is not present
on LinuxBuild2404 template.

scripts/Start-BurnInTest-Linux.ps1: burn-in wrapper for LinuxBuild2404
template (SnapshotName=BaseClean-Linux, GuestOS=Linux,
BuildCommand='bash build.sh'). Mirrors Start-BurnInTest.ps1.
2026-05-12 22:14:52 +02:00
Simone 9007934dca feat: expose skip-artifact as workflow input in action.yml
action.yml:
  - Add skip-artifact input (default: 'false').
  - Forward as INPUT_SKIP_ARTIFACT env var to the PS run step.
  - Pass SkipArtifact=true to Invoke-CIJob.ps1 when set.
  - Gate 'Upload artifacts' step on inputs.skip-artifact != 'true'.

Invoke-CIJob.ps1:
  - Restore -SkipArtifact switch; skips Phase 6 and logs 'skipped' event.

Invoke-RemoteBuild.ps1:
  - Restore -SkipArtifact switch; skips packaging inside the guest.
  - Error message updated to mention skip-artifact workflow input.
2026-05-12 22:05:17 +02:00
Simone a6acf1eef7 refactor(burn-in): remove -SkipArtifact; build.ps1 always produces dist/ 2026-05-12 22:00:43 +02:00
Simone 36cdd1fc25 docs(burn-in): add README for burnin-dummy repo 2026-05-12 21:57:18 +02:00
Simone 9601210baa feat(burn-in): add fake build script for burnin-dummy repo; update default BuildCommand
gitea/burnin-dummy/build.ps1:
  Fake build script to commit to the burnin-dummy repo.
  Creates dist\build-info.txt (date, host, pid) after ~30s ping delay.
  Invoke-RemoteBuild packages dist\ as artifacts.zip.

Start-BurnInTest.ps1:
  Default BuildCommand updated from ping-only delay to build.ps1 invocation.
  Run with -NoSkipArtifact to exercise the full artifact pipeline.
2026-05-12 21:55:38 +02:00
Simone 0a9b3f4348 fix(invoke-cijob): wrap Write-Host format string in parens to avoid -f being parsed as -ForegroundColor 2026-05-12 21:37:03 +02:00
Simone 041f350aa8 fix(burn-in): use hashtable splat for conditional -SkipArtifact in Start-BurnInTest
In PS 5.1, $(if (...) { '-SkipArtifact' }) inside a call produces the
literal string '-SkipArtifact' bound as a positional argument (-> IPList),
not interpreted as a switch name.
Fixed by building a hashtable and setting SkipArtifact = \True when needed.
2026-05-12 21:30:16 +02:00
Simone 80eeb389af fix(burn-in): add -SkipArtifact switch; restore production fail-on-missing-dist
PROBLEM: Invoke-RemoteBuild.ps1 was creating a placeholder artifact when the build
produced no dist/ directory. In production this hides build defects (build exits 0
but produces nothing = silent failure treated as success).

SOLUTION: Add explicit -SkipArtifact switch to the call chain:

Invoke-RemoteBuild.ps1:
  - Add -SkipArtifact switch. When set: skips packaging entirely (no zip created).
  - When absent (production default): missing GuestArtifactSource is a hard error
    with a clear message pointing to -SkipArtifact as the opt-in for no-output builds.

Invoke-CIJob.ps1:
  - Add -SkipArtifact switch. Passes it to Invoke-RemoteBuild.ps1.
  - Phase 6 (Get-BuildArtifacts) is entirely skipped when set; logs 'skipped' event.

Test-CapacityBurnIn.ps1:
  - Add -SkipArtifact switch. Adds '-SkipArtifact' flag to each child job argList.

Start-BurnInTest.ps1:
  - Always passes -SkipArtifact by default (burn-in uses delay commands, no output).
  - Add -NoSkipArtifact override switch for runs that do produce real artifacts.
  - Remove -NoSkipArtifact escape from wrapper: default burn-in never needs artifacts.
2026-05-12 21:28:11 +02:00
Simone e0b45fc71d fix(burn-in): create placeholder artifact when build command produces no output dir
Invoke-RemoteBuild.ps1: when BuildCommand succeeds (exit 0) but GuestArtifactSource
(default: dist) does not exist, instead of silently skipping packaging, now creates a
placeholder 'build-ok.txt' in the artifact output dir and zips it. This ensures
Get-BuildArtifacts.ps1 always finds artifacts.zip regardless of whether the build
produced real output files. Correct for burn-in, smoke, and delay-only build commands.

Start-BurnInTest.ps1: revert default BuildCommand to 'ping 127.0.0.1 -n 31 > nul'
(~30s delay, no artifact output) now that the pipeline handles missing dist gracefully.
The previous 'if not exist dist mkdir dist' workaround is no longer needed.
2026-05-12 21:23:40 +02:00
Simone 8595fbaf45 fix(burn-in): default BuildCommand creates artifact dir to exercise full pipeline
'exit 0' left C:\CI\build\dist non-existent -> packaging skipped -> Get-BuildArtifacts
could not find artifacts.zip -> all 4 jobs FAIL at artifact collection phase.

New default: 'if not exist dist mkdir dist & echo burnin_ok > dist\marker.txt'
This creates dist\marker.txt relative to C:\CI\build (GuestWorkDir), so the
packaging step finds it, creates artifacts.zip, and Get-BuildArtifacts succeeds.

Also updated docblock: clarify command runs via cmd /c; replace Start-Sleep example
(PS cmdlet, does not work via WinRM cmd) with ping delay equivalent.
2026-05-12 21:21:56 +02:00
Simone 8134a3e8d3 docs(plans): update master plan (sprints 2-5 complete, burn-in harness ready)
All Sprint 2 (C1, C2, H2, H3, H6, H7), Sprint 3 (H4, H5, H8, H9, H10, H11, H12),
Sprint 4 (T4.1-T4.6), Sprint 5 (T5.1-T5.6) tasks marked done.
Burn-in harness code-complete; live 4-way run pending.
Remaining open: smoke test live workflow validation (Task 1.4), benchmark alignment
verification, act_runner SSH alias live test.
2026-05-12 21:13:46 +02:00
Simone bb2572f451 feat(burn-in): capacity burn-in harness (Test-CapacityBurnIn.ps1)
scripts/Test-CapacityBurnIn.ps1 (new): N-way parallel burn-in harness using Start-Job
to launch N concurrent Invoke-CIJob.ps1 child processes for R rounds. After each round
asserts: all VMs destroyed, all jobs got distinct IPs, vm-start.lock gone, ip-leases
empty, wall time recorded. Params: -RepoUrl (mandatory), -IPList = @() (optional,
auto-detects via VMware Tools when empty), -GiteaCredentialTarget = 'GiteaPAT',
-Parallelism = 4, -Rounds = 3, -RoundTimeoutMinutes = 60, plus all Invoke-CIJob params.

scripts/Start-BurnInTest.ps1 (new): lab wrapper with all default params hardcoded
(template F:\CI\Templates\WinBuild2025, credentials BuildVMGuest/GiteaPAT, etc.)
for daily use. Exposes -Rounds, -Parallelism, -BuildCommand, -RoundTimeoutMinutes.
2026-05-12 21:13:31 +02:00
Simone c04a2f25aa feat(sprint5): quality pass, smoke test workflow, Get-CIJobSummary
Task 5.1: Delete runner/Install-Runner.ps1 (superseded by Setup-Host.ps1).
Task 5.2: Replace Unicode/Discord emoji in Watch-DiskSpace.ps1, Watch-RunnerHealth.ps1,
          Test-E2E-Section3.3.ps1 with plain-text prefixes ([WARNING], [ALERT], [WARN]).
Task 5.3: docs/TEST-PLAN-v1.3-to-HEAD.md: ForEach-Object -Parallel replaced with Start-Job;
          -RepositoryUrl replaced with -RepoUrl (3 occurrences); PS7 syntax removed.
Task 5.4: scripts/Get-CIJobSummary.ps1 (new): scans JSONL logs in F:\CI\Logs, prints summary
          table per job, -JobId detail view, -Failed filter, -Last N.
Task 3.5: gitea/workflows/self-test.yml (new): workflow_dispatch, smoke-windows + smoke-linux.
          scripts/Test-Smoke.ps1 (new): invokes Invoke-CIJob.ps1 with marker-file build,
          asserts artifact dir and JSONL success event.
Task 5.6: docs/BEST-PRACTICES.md Section 10 added: SHA256 pinning policy, priority table,
          PS 5.1 implementation pattern, update guidance.
2026-05-12 21:13:15 +02:00
Simone 9de86ac289 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 509d1fc284 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 7dff7d3dba 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).
2026-05-12 21:12:07 +02:00
Simone d33aaada1e feat(agent): add CI PS51 Author agent for PowerShell 5.1 scripting 2026-05-11 23:47:58 +02:00
Simone ec13461862 docs(plans): add multi-agent technical review and final master plan
- plans/gpt55-analysis.md: independent analysis by GPT-5.5
- plans/opus47-analysis.md: independent analysis by Opus 4.7
- plans/gpt55-review-of-opus.md: GPT-5.5 cross-review of Opus analysis
- plans/opus47-review-of-gpt55.md: Opus 4.7 cross-review of GPT-5.5 analysis
- plans/final-master-plan.md: consolidated master plan (8129 words)

Severity: 2 Critical, 12 High, 16 Medium, 10 Low, 6 Nice-to-have.
Top priorities: C2 secret logging in Invoke-RemoteBuild.ps1, C1 Linux
matrix template selection, H1 capacity=4 burn-in.
2026-05-11 23:47:06 +02:00
Simone 4758fbc519 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 6511d47a9a P3 done: workflow-example.yml usa composite action (generalizzazione per altri repo)
Riscritta gitea/workflow-example.yml per usare la composite action
Simone/local-ci-system/.gitea/actions/local-ci-build@main invece della
chiamata diretta a Invoke-CIJob.ps1.

Commenti inline guidano la personalizzazione per ogni repo:
- build-command e artifact-source (unici campi obbligatori da adattare)
- submodules, repo-url, use-git-clone (opzionali)
- extra-guest-env-json per secret injection (chiavi di firma, GPG)
- artifact-name personalizzato (e.g. con ref_name per tag build)

Aggiunge workflow_dispatch per trigger manuale.
Rimossa logica di orchestrazione inline: zero duplicazione tra repo.
TODO.md: Gitea Workflow Integration chiuso (5/5).
2026-05-11 22:38:54 +02:00
Simone 7d12dedddd Sprint 13-14: §6.2 composite action + §6.4 build matrix + §6.5 secret injection
§6.2 - New composite action gitea/actions/local-ci-build/action.yml
  Wraps Invoke-CIJob.ps1 for reuse across repos. Inputs: build-command,
  artifact-source, submodules, guest-os, use-git-clone, configuration,
  template-path, snapshot-name, artifact-name, artifact-retention-days.
  Anti-injection: all params via INPUT_* env vars, never interpolated in shell.

§6.4 - Build matrix windows+linux in build-nsis.yml
  gitea/workflows/build-nsis.yml rewritten with strategy.matrix target:
  [windows, linux], fail-fast: false, routes to {target}-build runner.
  Added action inputs: job-id-suffix (matrix disambig for artifact dirs),
  repo-url (SSH URL override for gitea-ci alias).

§6.5 - ExtraGuestEnv secret injection chain
  New param -ExtraGuestEnv [hashtable] in Invoke-CIJob.ps1 and
  Invoke-RemoteBuild.ps1. Windows: SetEnvironmentVariable in WinRM session
  ScriptBlock before build command. Linux: export KEY='val'; prefix before
  cd && buildcmd (POSIX single-quote escaping). Composite action input
  extra-guest-env-json (JSON object -> ConvertFrom-Json -> hashtable),
  never logged.

PSScriptAnalyzer fixes: _Common.psm1, Invoke-RetentionPolicy.ps1,
  Watch-RunnerHealth.ps1 (empty catch, ShouldProcess suppression, etc.)

Docs/test: TEST-PLAN-v1.3-to-HEAD.md updated §3.3/§6.1/§5.4 status.
  TODO.md: §6 fully closed (6.1-6.2 done, 6.3 deferred, 6.4-6.5 done, 6.6 done).
2026-05-11 22:35:36 +02:00
Simone 0f14caad63 fix(template): skip KMS activation if Windows already activated 2026-05-11 21:59:16 +02:00
Simone cf7274ad20 fix(template): re-affirm autologin after reboot before snapshot 2026-05-11 21:57:32 +02:00
Simone fe2d51f44e feat(template): reboot VM before final shutdown+snapshot 2026-05-11 21:11:21 +02:00
Simone b89fc7340d fix(template): use absolute \ path before PATH refresh (git not yet in session PATH) 2026-05-11 21:01:24 +02:00
Simone 2693c9dc42 fix: suppress Test-NetConnection progress bar noise (\Continue = SilentlyContinue) 2026-05-11 20:52:22 +02:00
Simone 143b00efc7 perf(template): replace all IWR -OutFile with WebClient.DownloadFile (10 occurrences) 2026-05-11 20:47:00 +02:00
Simone 364c51b448 perf(template): NSIS download use WebClient instead of IWR (no progress-bar overhead) 2026-05-11 20:44:50 +02:00
Simone 1ad9b4dd4f fix(template): NSIS download fix meta-refresh regex to match downloads.sf.net token URL 2026-05-11 20:38:36 +02:00
Simone 133701dd60 fix(template): NSIS download browser User-Agent + PE magic bytes guard 2026-05-11 20:32:55 +02:00
Simone 1b4c3be3f5 chore(template): bump PS7 7.6.1, NSIS 3.12, gh CLI 2.92.0 2026-05-11 20:29:23 +02:00
Simone 5c1a197559 refactor(template): promote PS7/NSIS/gh CLI from Tier-2 to Tier-1 (Step 11) 2026-05-11 20:26:06 +02:00
Simone 1bf7c2347b 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 987b36ff3f 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.
v1.5.0
2026-05-11 20:04:50 +02:00
Simone f948f23f0f docs(todo): Sprint 10 - mark §6.1 Linux e2e PASS + close In-VM Git Clone section v1.4.0 2026-05-11 19:49:10 +02:00
Simone 039fcdb9c9 feat(script): add UseGitClone and GuestRepoUrl parameters for in-VM cloning 2026-05-11 18:50:05 +02:00
Simone 1c39701534 fix(workflows): use shell:powershell (PS 5.1) instead of pwsh; fix ciScriptsDir path
- All 3 workflows: pwsh -> powershell (host requires PS 5.1, not Core 7+)
- workflow-example.yml: replace GITHUB_WORKSPACE-relative ciScriptsDir with
  hardcoded host path; use SSH alias URL (host-clone mode) instead of HTTP
- docs: add WORKFLOW-AUTHORING.md reference for AI and developers
2026-05-11 18:48:07 +02:00
Simone db1530cf0f fix(linux): correct PS escape for $GIT_CLONE_URL in UseGitClone clone cmd
In PS double-quoted strings, backslash does NOT escape '$'.
Only backtick does ('`$'). The previous '\' was being
expanded as a PS variable (undefined), triggering StrictMode error:
'Cannot retrieve variable \ because it has not been set.'

Replace '\$' with '`$' so the literal shell variable reference
\ is emitted correctly to the SSH command.
2026-05-11 18:40:19 +02:00
Simone 54399a2120 chore: update runner config and workflow example for linux-build label
runner/config.yaml:
- Add linux-build:host label alongside windows-build:host
- capacity remains 4 (concurrent jobs)

gitea/workflow-example.yml:
- Add linux-build job example (runs-on: linux-build:host)
- Document GuestOS auto-detection and SSH transport parameters
2026-05-11 18:35:24 +02:00
Simone 1c8fdcf028 docs: update documentation for Linux VM support (Sprint 9)
AGENTS.md (new):
- Environment reference for AI agents: host specs, PS 5.1 constraints,
  dir structure, VM templates, transport layer, style rules
- Lessons #9 (snapshot cold state) and #10 (vmrun list vs getGuestIPAddress)

ARCHITECTURE.md:
- Add SSH/SCP transport section (Linux VMs)
- Update system diagram to include _Transport.psm1, SSH transport path
- Network layout: add SSH port 22 for Linux VMs
- Timeline: Linux readiness check phases documented

CI-FLOW.md:
- Prerequisites table: add Template VM (Linux), SSH key row
- Step 6 (readiness): document Windows vs Linux phases
- Step 7 (build) and Step 8 (artifacts): document Linux/SSH paths
- ci-report-ip guestinfo mechanism referenced

HOST-SETUP.md:
- Directory tree: add LinuxBuild2404 template dir and keys/
- Post-setup checklist: add step 5 (SSH key generation + Linux template)
- Fix duplicate step numbering (56, 67)
- Reference Paths table: add Linux template VMX, snapshot, SSH key

LINUX-TEMPLATE-SETUP.md:
- Rewritten as implementation record (no longer a plan)
- Fase A user-data: minimal (user+SSH key only, no packages/runcmd)
- All phases marked complete with actual paths and snapshot names

WINDOWS-TEMPLATE-SETUP.md: minor updates for consistency

TODO.md:
- Summary: update last-updated to 2026-05-11, Sprint 9 description
- Linux Build VM row: all 5 items complete
- Prossimi passi: Test Plan + §6.6 Tier-2 as next priorities
2026-05-11 18:35:11 +02:00
Simone 383d6864ce test: add Linux build E2E test scripts
Test-Ns7zipBuild-Linux.ps1: e2e test for nsis7z plugin build on Linux VM
  (confirmed PASS: nsis7z.dll 2272 KB in 03:09  2026-05-11)

Test-NsinnounpBuild-Linux.ps1: e2e test for nsinnounp plugin build on Linux VM
2026-05-11 18:34:50 +02:00
Simone 9fcc46afd6 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 fee5963a65 feat(linux): update orchestration scripts for dual-OS (Windows/Linux) support
Wait-VMReady.ps1:
- Phase 1: vmrun list + path matching instead of getGuestIPAddress (avoids hang)
- Phase 2/3: WinRM (Windows) or TCP:22 + ssh echo (Linux) based on -Transport param
- -Transport SSH auto-selected by Invoke-CIJob when guestOS=ubuntu-64

Invoke-CIJob.ps1:
- Auto-detect GuestOS from clone VMX guestOS field
- Pass -GuestOS Linux to Wait-VMReady, Invoke-RemoteBuild, Get-BuildArtifacts
- Git clone output streamed line-by-line (fix buffered stdout)

Invoke-RemoteBuild.ps1:
- -GuestOS Linux path: SSH+SCP via _Transport.psm1
- Always uses in-VM git clone for Linux builds

Get-BuildArtifacts.ps1:
- -GuestOS Linux path: scp -r ci_build@<ip>:/opt/ci/output/ to host artifact dir
2026-05-11 18:34:16 +02:00
Simone 08f7bb1757 feat(linux): add SSH/SCP transport module (_Transport.psm1)
Exported functions:
- Invoke-SshCommand   run a command on a Linux guest via ssh.exe (BatchMode=yes)
- Copy-SshItem        scp a local path to a remote path (or vice versa)
- Test-SshReady       test TCP:22 + ssh echo round-trip

Used by Wait-VMReady.ps1 -Transport SSH, Invoke-RemoteBuild.ps1 -GuestOS Linux,
Get-BuildArtifacts.ps1 -GuestOS Linux.
2026-05-11 18:34:00 +02:00
Simone 59d38bee51 docs(linux): resolve 4 open questions in Deploy plan (EFI, vdiskmanager, growpart, transport scope) 2026-05-11 00:01:14 +02:00
Simone be80293af6 docs(linux): add Step 1b auto-download cloud VMDK in Deploy plan 2026-05-10 23:54:48 +02:00