Refactor documentation and analysis in final master plan, opus47 analysis, and opus47 review of GPT-5.5
- Updated the final master plan to improve clarity and consistency in the status of various capabilities, including fixes and enhancements made as of 2026-05-12. - Revised the opus47 analysis to provide a more structured overview of the system's production readiness, including detailed coverage of OWASP Top 10 risks and operational gaps. - Enhanced the opus47 review of GPT-5.5 by clarifying severity ratings and rationales for various items, while adding new high-severity items that were previously overlooked.
This commit is contained in:
@@ -35,41 +35,41 @@ Ogni build gira in una VM **usa e getta** ripristinata dallo snapshot: Windows S
|
|||||||
|
|
||||||
## Requisiti Host
|
## Requisiti Host
|
||||||
|
|
||||||
| Componente | Versione / Dettaglio |
|
| Componente | Versione / Dettaglio |
|
||||||
|---|---|
|
| ---------------------- | ----------------------------------------------------------------- |
|
||||||
| OS | Windows 11 |
|
| OS | Windows 11 |
|
||||||
| CPU/RAM | i9-10900X, 64 GB RAM |
|
| CPU/RAM | i9-10900X, 64 GB RAM |
|
||||||
| VMware Workstation Pro | installato, `vmrun.exe` disponibile |
|
| VMware Workstation Pro | installato, `vmrun.exe` disponibile |
|
||||||
| PowerShell | 5.1 |
|
| PowerShell | 5.1 |
|
||||||
| act_runner | v1.0.2 — `F:\CI\act_runner\act_runner.exe` |
|
| act_runner | v1.0.2 — `F:\CI\act_runner\act_runner.exe` |
|
||||||
| Gitea | self-hosted `http://10.10.20.11:3100` / `https://gitea.emulab.it` |
|
| Gitea | self-hosted `http://10.10.20.11:3100` / `https://gitea.emulab.it` |
|
||||||
|
|
||||||
## Template VM
|
## Template VM
|
||||||
|
|
||||||
### Windows (snapshot `BaseClean`)
|
### Windows (snapshot `BaseClean`)
|
||||||
|
|
||||||
| Componente | Versione |
|
| Componente | Versione |
|
||||||
|---|---|
|
| -------------- | ------------------------------------------------------------------------------ |
|
||||||
| OS | Windows Server 2025 |
|
| OS | Windows Server 2025 |
|
||||||
| VMX | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` (env `GITEA_CI_TEMPLATE_PATH`) |
|
| VMX | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` (env `GITEA_CI_TEMPLATE_PATH`) |
|
||||||
| VS Build Tools | 2026 (MSBuild 18.5.4 / toolset v145) |
|
| VS Build Tools | 2026 (MSBuild 18.5.4 / toolset v145) |
|
||||||
| .NET SDK | 10.0.203 |
|
| .NET SDK | 10.0.203 |
|
||||||
| Python | 3.13.3 |
|
| Python | 3.13.3 |
|
||||||
| Rete | VMnet8 NAT — `192.168.79.0/24` |
|
| Rete | VMnet8 NAT — `192.168.79.0/24` |
|
||||||
| WinRM | HTTPS/5986, Basic auth, self-signed cert (SkipCACheck — lab-only) |
|
| WinRM | HTTPS/5986, Basic auth, self-signed cert (SkipCACheck — lab-only) |
|
||||||
|
|
||||||
Variante **Windows Server 2022**: `*WinBuild2022.ps1` + VMX `F:\CI\Templates\WinBuild2022\WinBuild2022.vmx`.
|
Variante **Windows Server 2022**: `*WinBuild2022.ps1` + VMX `F:\CI\Templates\WinBuild2022\WinBuild2022.vmx`.
|
||||||
|
|
||||||
### Linux (snapshot `BaseClean-Linux`)
|
### Linux (snapshot `BaseClean-Linux`)
|
||||||
|
|
||||||
| Componente | Versione |
|
| Componente | Versione |
|
||||||
|---|---|
|
| ------------ | ---------------------------------------------------------------------------------------- |
|
||||||
| OS | Ubuntu 24.04 LTS (cloud image) |
|
| OS | Ubuntu 24.04 LTS (cloud image) |
|
||||||
| VMX | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` (env `GITEA_CI_LINUX_TEMPLATE_PATH`) |
|
| VMX | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` (env `GITEA_CI_LINUX_TEMPLATE_PATH`) |
|
||||||
| Toolchain | GCC, G++, Clang, CMake, Ninja, Python 3, Git, 7-Zip |
|
| Toolchain | GCC, G++, Clang, CMake, Ninja, Python 3, Git, 7-Zip |
|
||||||
| Rete | VMnet8 NAT — `192.168.79.0/24` |
|
| Rete | VMnet8 NAT — `192.168.79.0/24` |
|
||||||
| SSH | porta 22, utente `ci_build`, chiave `F:\CI\keys\ci_linux` |
|
| SSH | porta 22, utente `ci_build`, chiave `F:\CI\keys\ci_linux` |
|
||||||
| Runner label | `linux-build:host` |
|
| Runner label | `linux-build:host` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -217,14 +217,14 @@ nssm start act_runner
|
|||||||
|
|
||||||
Imposta queste variabili d'ambiente nel servizio (`runner/config.yaml`):
|
Imposta queste variabili d'ambiente nel servizio (`runner/config.yaml`):
|
||||||
|
|
||||||
| Variabile | Valore |
|
| Variabile | Valore |
|
||||||
|---|---|
|
| ------------------------------ | --------------------------------------------------- |
|
||||||
| `GITEA_CI_TEMPLATE_PATH` | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
|
| `GITEA_CI_TEMPLATE_PATH` | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
|
||||||
| `GITEA_CI_LINUX_TEMPLATE_PATH` | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` |
|
| `GITEA_CI_LINUX_TEMPLATE_PATH` | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` |
|
||||||
| `GITEA_CI_CLONE_BASE_DIR` | `F:\CI\BuildVMs` |
|
| `GITEA_CI_CLONE_BASE_DIR` | `F:\CI\BuildVMs` |
|
||||||
| `GITEA_CI_ARTIFACT_DIR` | `F:\CI\Artifacts` |
|
| `GITEA_CI_ARTIFACT_DIR` | `F:\CI\Artifacts` |
|
||||||
| `GITEA_CI_GUEST_CRED_TARGET` | `BuildVMGuest` |
|
| `GITEA_CI_GUEST_CRED_TARGET` | `BuildVMGuest` |
|
||||||
| `GITEA_CI_SSH_KEY_PATH` | `F:\CI\keys\ci_linux` |
|
| `GITEA_CI_SSH_KEY_PATH` | `F:\CI\keys\ci_linux` |
|
||||||
|
|
||||||
Labels runner: `windows-build:host` (job Windows) e `linux-build:host` (job Linux).
|
Labels runner: `windows-build:host` (job Windows) e `linux-build:host` (job Linux).
|
||||||
|
|
||||||
@@ -283,14 +283,14 @@ Usa una **strategy matrix** `[windows, linux]` che esegue in parallelo su entram
|
|||||||
La composite action [gitea/actions/local-ci-build/action.yml](gitea/actions/local-ci-build/action.yml)
|
La composite action [gitea/actions/local-ci-build/action.yml](gitea/actions/local-ci-build/action.yml)
|
||||||
asconde tutta la logica Invoke-CIJob.ps1 e accetta questi input principali:
|
asconde tutta la logica Invoke-CIJob.ps1 e accetta questi input principali:
|
||||||
|
|
||||||
| Input | Descrizione |
|
| Input | Descrizione |
|
||||||
|---|---|
|
| ----------------- | ------------------------------------------------ |
|
||||||
| `build-command` | Comando di build da eseguire nel guest |
|
| `build-command` | Comando di build da eseguire nel guest |
|
||||||
| `guest-os` | `Windows` (default) o `Linux` |
|
| `guest-os` | `Windows` (default) o `Linux` |
|
||||||
| `artifact-source` | Path artifacts nel guest |
|
| `artifact-source` | Path artifacts nel guest |
|
||||||
| `skip-artifact` | `true` per job senza output |
|
| `skip-artifact` | `true` per job senza output |
|
||||||
| `repo-url` | URL SSH del repository |
|
| `repo-url` | URL SSH del repository |
|
||||||
| `job-id-suffix` | Suffisso per disambiguare artifact dir in matrix |
|
| `job-id-suffix` | Suffisso per disambiguare artifact dir in matrix |
|
||||||
|
|
||||||
Per adattare ad altri repository, copia [gitea/workflow-example.yml](gitea/workflow-example.yml)
|
Per adattare ad altri repository, copia [gitea/workflow-example.yml](gitea/workflow-example.yml)
|
||||||
e aggiorna `build-command`, `artifact-source`, `repo-url`.
|
e aggiorna `build-command`, `artifact-source`, `repo-url`.
|
||||||
@@ -299,19 +299,19 @@ e aggiorna `build-command`, `artifact-source`, `repo-url`.
|
|||||||
|
|
||||||
## Documentazione
|
## Documentazione
|
||||||
|
|
||||||
| File | Contenuto |
|
| File | Contenuto |
|
||||||
|---|---|
|
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
||||||
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Diagramma componenti e flusso dati |
|
| [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | Diagramma componenti e flusso dati |
|
||||||
| [docs/CI-FLOW.md](docs/CI-FLOW.md) | Descrizione dettagliata di ogni fase del pipeline |
|
| [docs/CI-FLOW.md](docs/CI-FLOW.md) | Descrizione dettagliata di ogni fase del pipeline |
|
||||||
| [docs/HOST-SETUP.md](docs/HOST-SETUP.md) | Bootstrap macchina host (Setup-Host.ps1) |
|
| [docs/HOST-SETUP.md](docs/HOST-SETUP.md) | Bootstrap macchina host (Setup-Host.ps1) |
|
||||||
| [docs/WINDOWS-TEMPLATE-SETUP.md](docs/WINDOWS-TEMPLATE-SETUP.md) | Provisioning template Windows (Deploy + Prepare + Setup) |
|
| [docs/WINDOWS-TEMPLATE-SETUP.md](docs/WINDOWS-TEMPLATE-SETUP.md) | Provisioning template Windows (Deploy + Prepare + Setup) |
|
||||||
| [docs/LINUX-TEMPLATE-SETUP.md](docs/LINUX-TEMPLATE-SETUP.md) | Template Ubuntu 24.04: Deploy-LinuxBuild2404, Prepare-LinuxBuild2404, snapshot BaseClean-Linux |
|
| [docs/LINUX-TEMPLATE-SETUP.md](docs/LINUX-TEMPLATE-SETUP.md) | Template Ubuntu 24.04: Deploy-LinuxBuild2404, Prepare-LinuxBuild2404, snapshot BaseClean-Linux |
|
||||||
| [docs/OPTIMIZATION.md](docs/OPTIMIZATION.md) | Layout NVMe, snapshot strategy, cache, tuning |
|
| [docs/OPTIMIZATION.md](docs/OPTIMIZATION.md) | Layout NVMe, snapshot strategy, cache, tuning |
|
||||||
| [docs/BEST-PRACTICES.md](docs/BEST-PRACTICES.md) | Sicurezza WinRM, threat model, credenziali |
|
| [docs/BEST-PRACTICES.md](docs/BEST-PRACTICES.md) | Sicurezza WinRM, threat model, credenziali |
|
||||||
| [docs/RUNBOOK.md](docs/RUNBOOK.md) | Triage incident comuni (runner offline, clone fail, ecc.) |
|
| [docs/RUNBOOK.md](docs/RUNBOOK.md) | Triage incident comuni (runner offline, clone fail, ecc.) |
|
||||||
| [docs/TEST-PLAN-v1.3-to-HEAD.md](docs/TEST-PLAN-v1.3-to-HEAD.md) | Test plan completo features post-v1.3 |
|
| [docs/TEST-PLAN-v1.3-to-HEAD.md](docs/TEST-PLAN-v1.3-to-HEAD.md) | Test plan completo features post-v1.3 |
|
||||||
| [docs/Setup-GiteaSSH.md](docs/Setup-GiteaSSH.md) | Configurazione SSH alias `gitea-ci` |
|
| [docs/Setup-GiteaSSH.md](docs/Setup-GiteaSSH.md) | Configurazione SSH alias `gitea-ci` |
|
||||||
| [TODO.md](TODO.md) | Roadmap, audit trail task completati, backlog |
|
| [TODO.md](TODO.md) | Roadmap, audit trail task completati, backlog |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ _Last updated: 2026-05-11 (post Sprint 15: §7.5 DONE — Rinomina Setup-* → I
|
|||||||
| [x] | §4 Osservabilità & manutenzione | 3 | 0 | 4.1/4.3/4.4 done (4.2 Prometheus, 4.5 Dashboard rimossi) |
|
| [x] | §4 Osservabilità & manutenzione | 3 | 0 | 4.1/4.3/4.4 done (4.2 Prometheus, 4.5 Dashboard rimossi) |
|
||||||
| [x] | §5 Qualità codice & test | 5 | 0 | 5.1/5.2/5.3/5.4/5.5 done |
|
| [x] | §5 Qualità codice & test | 5 | 0 | 5.1/5.2/5.3/5.4/5.5 done |
|
||||||
| [x] | §6 Scalabilità & estensioni | 5 | 0 | 6.1-6.2 done, 6.3 deferred (home lab), 6.4-6.5 done, 6.6 done |
|
| [x] | §6 Scalabilità & estensioni | 5 | 0 | 6.1-6.2 done, 6.3 deferred (home lab), 6.4-6.5 done, 6.6 done |
|
||||||
| [x] | §7 Refactor Deploy ↔ Setup | 5 | 0 | 7.1-7.5 done; Setup-* → Install-CIToolchain-* (2026-05-11) |
|
| [x] | §7 Refactor Deploy ↔ Setup | 5 | 0 | 7.1-7.5 done; Setup-* → Install-CIToolchain-* (2026-05-11) |
|
||||||
| [x] | In-VM Git Clone (§3.3) | 4 | 0 | COMPLETATO 2026-05-10 — e2e PASS: 34s/25.7% vs baseline |
|
| [x] | In-VM Git Clone (§3.3) | 4 | 0 | COMPLETATO 2026-05-10 — e2e PASS: 34s/25.7% vs baseline |
|
||||||
| [x] | Linux Build VM (§6.1) | 5 | 0 | Deploy/Prepare/Setup/Transport + doc + e2e PASS nsis7z.dll 2272 KB |
|
| [x] | Linux Build VM (§6.1) | 5 | 0 | Deploy/Prepare/Setup/Transport + doc + e2e PASS nsis7z.dll 2272 KB |
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -60,11 +60,11 @@ $session = New-PSSession -ComputerName $ip -Port 5986 -UseSSL -Authentication Ba
|
|||||||
The template VM disables Windows Defender, Windows Firewall, and User Account Control (UAC).
|
The template VM disables Windows Defender, Windows Firewall, and User Account Control (UAC).
|
||||||
This is **intentional** — not a bug, not an oversight. Each has tradeoffs:
|
This is **intentional** — not a bug, not an oversight. Each has tradeoffs:
|
||||||
|
|
||||||
| Feature | Disabled? | Why | Cost if enabled |
|
| Feature | Disabled? | Why | Cost if enabled |
|
||||||
|---------|-----------|-----|-----------------|
|
| --------------------------------------- | --------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- |
|
||||||
| **Windows Defender** | Yes | Real-time AV scanning blocks .NET compilation, Python wheels, and npm installs | 5–10 min per build overhead; false positives on dev tools |
|
| **Windows Defender** | Yes | Real-time AV scanning blocks .NET compilation, Python wheels, and npm installs | 5–10 min per build overhead; false positives on dev tools |
|
||||||
| **Windows Firewall** | Yes | Blocks inbound WinRM even with rules; requires Domain/Home profile tuning | Complex rules; fragile across OS updates |
|
| **Windows Firewall** | Yes | Blocks inbound WinRM even with rules; requires Domain/Home profile tuning | Complex rules; fragile across OS updates |
|
||||||
| **UAC (LocalAccountTokenFilterPolicy)** | Yes | Prevents non-elevated WinRM scripts from running builds | Requires built-in Administrator account; WinRM behaves like a user with limited rights |
|
| **UAC (LocalAccountTokenFilterPolicy)** | Yes | Prevents non-elevated WinRM scripts from running builds | Requires built-in Administrator account; WinRM behaves like a user with limited rights |
|
||||||
|
|
||||||
### When this threat model is acceptable
|
### When this threat model is acceptable
|
||||||
|
|
||||||
@@ -368,13 +368,13 @@ cached in the ISO or in `F:\CI\ISO\`).
|
|||||||
|
|
||||||
Priority targets (descending risk):
|
Priority targets (descending risk):
|
||||||
|
|
||||||
| Installer | Script | Where to pin |
|
| Installer | Script | Where to pin |
|
||||||
|-----------|--------|--------------|
|
| ----------------------- | ----------------------------------------------- | ------------------------------------------------------ |
|
||||||
| Git for Windows `.exe` | `template/Install-CIToolchain-WinBuild2025.ps1` | `-sha256` param or `Get-FileHash` check after download |
|
| Git for Windows `.exe` | `template/Install-CIToolchain-WinBuild2025.ps1` | `-sha256` param or `Get-FileHash` check after download |
|
||||||
| 7-Zip `.msi` / `.exe` | `template/Install-CIToolchain-WinBuild2025.ps1` | same |
|
| 7-Zip `.msi` / `.exe` | `template/Install-CIToolchain-WinBuild2025.ps1` | same |
|
||||||
| Python `.exe` | `template/Install-CIToolchain-WinBuild2025.ps1` | same |
|
| Python `.exe` | `template/Install-CIToolchain-WinBuild2025.ps1` | same |
|
||||||
| .NET SDK install script | `template/Install-CIToolchain-WinBuild2025.ps1` | HTTPS only; hash less critical |
|
| .NET SDK install script | `template/Install-CIToolchain-WinBuild2025.ps1` | HTTPS only; hash less critical |
|
||||||
| Ubuntu cloud VMDK | `template/Deploy-LinuxBuild2404.ps1` | already implemented via `-VmdkSha256` parameter |
|
| Ubuntu cloud VMDK | `template/Deploy-LinuxBuild2404.ps1` | already implemented via `-VmdkSha256` parameter |
|
||||||
|
|
||||||
**Implementation pattern** (PS 5.1):
|
**Implementation pattern** (PS 5.1):
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -8,17 +8,17 @@
|
|||||||
|
|
||||||
Before any CI job runs, the following must be in place:
|
Before any CI job runs, the following must be in place:
|
||||||
|
|
||||||
| Component | State |
|
| Component | State |
|
||||||
| ------------------ | ----------------------------------------------------------------------- |
|
| ------------------ | ----------------------------------------------------------------------------- |
|
||||||
| Gitea server | Running, accessible on LAN |
|
| Gitea server | Running, accessible on LAN |
|
||||||
| act_runner | Registered, running as Windows service on host |
|
| act_runner | Registered, running as Windows service on host |
|
||||||
| Template VM (Win) | Provisioned, snapshot "BaseClean" taken, VM powered off |
|
| Template VM (Win) | Provisioned, snapshot "BaseClean" taken, VM powered off |
|
||||||
| Template VM (Lin) | Ubuntu 24.04 LTS, snapshot "BaseClean-Linux" taken, VM powered off (optional) |
|
| Template VM (Lin) | Ubuntu 24.04 LTS, snapshot "BaseClean-Linux" taken, VM powered off (optional) |
|
||||||
| WinRM | Enabled on Windows template VM (inherits to all clones) |
|
| WinRM | Enabled on Windows template VM (inherits to all clones) |
|
||||||
| SSH key | `F:\CI\keys\ci_linux` (ed25519) present; public key in Linux template |
|
| SSH key | `F:\CI\keys\ci_linux` (ed25519) present; public key in Linux template |
|
||||||
| vmrun.exe | Present at `C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe` |
|
| vmrun.exe | Present at `C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe` |
|
||||||
| `F:\CI\BuildVMs\` | Directory exists and writable |
|
| `F:\CI\BuildVMs\` | Directory exists and writable |
|
||||||
| `F:\CI\Artifacts\` | Directory exists and writable |
|
| `F:\CI\Artifacts\` | Directory exists and writable |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+32
-32
@@ -7,15 +7,15 @@ Eseguire **una volta** prima di qualsiasi provisioning del template VM o esecuzi
|
|||||||
|
|
||||||
## Prerequisiti host
|
## Prerequisiti host
|
||||||
|
|
||||||
| Componente | Versione/Note |
|
| Componente | Versione/Note |
|
||||||
| ----------------------- | ----------------------------------------------------------------- |
|
| ------------------ | ----------------------------------------------------------------- |
|
||||||
| OS | Windows 11 (host fisico) o Windows Server 2022+ |
|
| OS | Windows 11 (host fisico) o Windows Server 2022+ |
|
||||||
| VMware Workstation | Pro 17.x — necessario per `vmrun.exe` e supporto linked clone |
|
| VMware Workstation | Pro 17.x — necessario per `vmrun.exe` e supporto linked clone |
|
||||||
| Storage | NVMe dedicato (consigliato `F:\` riservato a CI, ≥ 500 GB libero) |
|
| Storage | NVMe dedicato (consigliato `F:\` riservato a CI, ≥ 500 GB libero) |
|
||||||
| RAM | ≥ 32 GB (4 VM parallele × 6-8 GB) |
|
| RAM | ≥ 32 GB (4 VM parallele × 6-8 GB) |
|
||||||
| Rete | VMnet8 (NAT) configurato in VMware Workstation |
|
| Rete | VMnet8 (NAT) configurato in VMware Workstation |
|
||||||
| PowerShell | 5.1+ (built-in) o 7.x |
|
| PowerShell | 5.1+ (built-in) o 7.x |
|
||||||
| Privilegi | Account amministrativo per Setup-Host.ps1 |
|
| Privilegi | Account amministrativo per Setup-Host.ps1 |
|
||||||
|
|
||||||
Software opzionali installati on-demand dallo script:
|
Software opzionali installati on-demand dallo script:
|
||||||
- **NSSM** — installazione automatica via Chocolatey se presente; altrimenti install manuale da https://nssm.cc
|
- **NSSM** — installazione automatica via Chocolatey se presente; altrimenti install manuale da https://nssm.cc
|
||||||
@@ -94,20 +94,20 @@ Apri PowerShell **come Administrator**, poi:
|
|||||||
|
|
||||||
## Parametri principali
|
## Parametri principali
|
||||||
|
|
||||||
| Parametro | Default | Note |
|
| Parametro | Default | Note |
|
||||||
| ---------------------------- | -------------------------------- | ------------------------------------- |
|
| ------------------------ | ------------------------------------ | ------------------------------------- |
|
||||||
| `-CIRoot` | `F:\CI` | Base directory per tutti i dati CI |
|
| `-CIRoot` | `F:\CI` | Base directory per tutti i dati CI |
|
||||||
| `-GuestCredentialTarget` | `BuildVMGuest` | Target Credential Manager |
|
| `-GuestCredentialTarget` | `BuildVMGuest` | Target Credential Manager |
|
||||||
| `-GuestUsername` | `ci_build` | Account build dentro la VM |
|
| `-GuestUsername` | `ci_build` | Account build dentro la VM |
|
||||||
| `-GuestPassword` | (prompt) | Mai hard-codare |
|
| `-GuestPassword` | (prompt) | Mai hard-codare |
|
||||||
| `-ActRunnerExe` | `<CIRoot>\act_runner\act_runner.exe` | Path binario runner |
|
| `-ActRunnerExe` | `<CIRoot>\act_runner\act_runner.exe` | Path binario runner |
|
||||||
| `-ActRunnerConfigYaml` | `<repo>\runner\config.yaml` | Source del config da copiare |
|
| `-ActRunnerConfigYaml` | `<repo>\runner\config.yaml` | Source del config da copiare |
|
||||||
| `-GiteaUrl` | `http://10.10.20.11:3100` | URL Gitea per registrazione |
|
| `-GiteaUrl` | `http://10.10.20.11:3100` | URL Gitea per registrazione |
|
||||||
| `-GiteaRunnerToken` | (vuoto) | Token registrazione (Admin → Runners) |
|
| `-GiteaRunnerToken` | (vuoto) | Token registrazione (Admin → Runners) |
|
||||||
| `-SkipRunnerInstall` | `$false` | Salta installazione servizio |
|
| `-SkipRunnerInstall` | `$false` | Salta installazione servizio |
|
||||||
| `-SkipSSHConfig` | `$false` | Salta scrittura SSH alias |
|
| `-SkipSSHConfig` | `$false` | Salta scrittura SSH alias |
|
||||||
| `-GiteaSSHHost` | `10.10.20.11` | Hostname SSH Gitea |
|
| `-GiteaSSHHost` | `10.10.20.11` | Hostname SSH Gitea |
|
||||||
| `-GiteaSSHPort` | `2222` | Porta SSH Gitea |
|
| `-GiteaSSHPort` | `2222` | Porta SSH Gitea |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ Allo `Setup-Host.ps1` exit 0:
|
|||||||
| act_runner config | `F:\CI\act_runner\config.yaml` |
|
| act_runner config | `F:\CI\act_runner\config.yaml` |
|
||||||
| act_runner logs | `F:\CI\act_runner\logs\` (stdout.log, stderr.log) |
|
| act_runner logs | `F:\CI\act_runner\logs\` (stdout.log, stderr.log) |
|
||||||
| Template VMX (Windows) | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
|
| Template VMX (Windows) | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
|
||||||
| Template VMX (Linux) | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` |
|
| Template VMX (Linux) | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` |
|
||||||
| Snapshot name (Windows) | `BaseClean` |
|
| Snapshot name (Windows) | `BaseClean` |
|
||||||
| Snapshot name (Linux) | `BaseClean-Linux` |
|
| Snapshot name (Linux) | `BaseClean-Linux` |
|
||||||
| SSH key (Linux VMs) | `F:\CI\keys\ci_linux` (privata), `F:\CI\keys\ci_linux.pub` |
|
| SSH key (Linux VMs) | `F:\CI\keys\ci_linux` (privata), `F:\CI\keys\ci_linux.pub` |
|
||||||
@@ -188,11 +188,11 @@ Task schedulati (vedi `scripts/Register-CIScheduledTasks.ps1` per il bootstrap):
|
|||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
| Sintomo | Diagnosi / Fix |
|
| Sintomo | Diagnosi / Fix |
|
||||||
| --------------------------------------- | -------------------------------------------------------------------- |
|
| ------------------------------- | ---------------------------------------------------------------- |
|
||||||
| `vmrun.exe NOT found` | Installa VMware Workstation Pro, riesegui |
|
| `vmrun.exe NOT found` | Installa VMware Workstation Pro, riesegui |
|
||||||
| `NSSM not available` | Install manuale da https://nssm.cc, aggiungi a PATH, riesegui |
|
| `NSSM not available` | Install manuale da https://nssm.cc, aggiungi a PATH, riesegui |
|
||||||
| Runner registration `exit != 0` | Verifica token Gitea + URL raggiungibile da host |
|
| Runner registration `exit != 0` | Verifica token Gitea + URL raggiungibile da host |
|
||||||
| Service `act_runner` non parte | Check `F:\CI\act_runner\logs\stderr.log` |
|
| Service `act_runner` non parte | Check `F:\CI\act_runner\logs\stderr.log` |
|
||||||
| `New-StoredCredential` fail | Verifica modulo CredentialManager importato + scope corretto |
|
| `New-StoredCredential` fail | Verifica modulo CredentialManager importato + scope corretto |
|
||||||
| Job CI fallisce su `Test-WSMan` | TrustedHosts host non include subnet VM, AllowUnencrypted=$false |
|
| Job CI fallisce su `Test-WSMan` | TrustedHosts host non include subnet VM, AllowUnencrypted=$false |
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
## Architettura: tre script + modulo transport
|
## Architettura: tre script + modulo transport
|
||||||
|
|
||||||
| Script / Modulo | Dove gira | Ruolo |
|
| Script / Modulo | Dove gira | Ruolo |
|
||||||
| ------------------------------------- | ---------------- | --------------------------------------------------------------------------- |
|
| ------------------------------------------- | ---------------- | --------------------------------------------------------------------------- |
|
||||||
| `template/Deploy-LinuxBuild2404.ps1` | **Host** (PS) | Crea VM da cloud image VMDK, genera seed ISO cloud-init, avvia, aspetta SSH |
|
| `template/Deploy-LinuxBuild2404.ps1` | **Host** (PS) | Crea VM da cloud image VMDK, genera seed ISO cloud-init, avvia, aspetta SSH |
|
||||||
| `template/Prepare-LinuxBuild2404.ps1` | **Host** (PS) | Copia + esegue setup via SSH, valida stato, prende snapshot |
|
| `template/Prepare-LinuxBuild2404.ps1` | **Host** (PS) | Copia + esegue setup via SSH, valida stato, prende snapshot |
|
||||||
| `template/Install-CIToolchain-Linux2404.sh` | **Guest** (Bash) | Installa toolchain CI, dirs, hardening, gate finale |
|
| `template/Install-CIToolchain-Linux2404.sh` | **Guest** (Bash) | Installa toolchain CI, dirs, hardening, gate finale |
|
||||||
| `scripts/_Transport.psm1` | **Host** (PS) | Funzioni SSH-only per il branch Linux (WinRM esistente invariato per ora) |
|
| `scripts/_Transport.psm1` | **Host** (PS) | Funzioni SSH-only per il branch Linux (WinRM esistente invariato per ora) |
|
||||||
|
|
||||||
Perche tre script separati (non tutto-in-uno): cloud-init copre solo il bootstrap OS
|
Perche tre script separati (non tutto-in-uno): cloud-init copre solo il bootstrap OS
|
||||||
(utente, SSH key, pacchetti base). Il toolchain CI e le validazioni per step sono piu
|
(utente, SSH key, pacchetti base). Il toolchain CI e le validazioni per step sono piu
|
||||||
@@ -26,7 +26,7 @@ Deploy/Setup/Prepare di Windows.
|
|||||||
| Parametro | Valore |
|
| Parametro | Valore |
|
||||||
| ------------- | ---------------------------------------------------- |
|
| ------------- | ---------------------------------------------------- |
|
||||||
| OS | Ubuntu 24.04 LTS (cloud image, non ISO installer) |
|
| OS | Ubuntu 24.04 LTS (cloud image, non ISO installer) |
|
||||||
| Immagine base | `noble-server-cloudimg-amd64.vmdk` |
|
| Immagine base | `noble-server-cloudimg-amd64.vmdk` |
|
||||||
| Download | `https://cloud-images.ubuntu.com/noble/current/` |
|
| Download | `https://cloud-images.ubuntu.com/noble/current/` |
|
||||||
| vCPU | 4 |
|
| vCPU | 4 |
|
||||||
| RAM | 4096 MB |
|
| RAM | 4096 MB |
|
||||||
|
|||||||
+10
-10
@@ -200,16 +200,16 @@ Estimated time: 2-4 hours including Windows Update.
|
|||||||
|
|
||||||
## Quick Reference
|
## Quick Reference
|
||||||
|
|
||||||
| Symptom | First command |
|
| Symptom | First command |
|
||||||
| ------------------------------ | ---------------------------------------------------------------------- |
|
| ------------------- | ------------------------------------------------------------------ |
|
||||||
| Runner offline | `Get-Service act_runner`, then `Restart-Service act_runner` |
|
| Runner offline | `Get-Service act_runner`, then `Restart-Service act_runner` |
|
||||||
| Phase 2 clone fails | `Test-Path F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
|
| Phase 2 clone fails | `Test-Path F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` |
|
||||||
| Disk full | `Get-PSDrive F \| Select Free`; run `Invoke-RetentionPolicy.ps1` |
|
| Disk full | `Get-PSDrive F \| Select Free`; run `Invoke-RetentionPolicy.ps1` |
|
||||||
| Stale lock | `Remove-Item F:\CI\State\vm-start.lock` |
|
| Stale lock | `Remove-Item F:\CI\State\vm-start.lock` |
|
||||||
| Slow builds | Check `invoke-ci.jsonl` phase timestamps; check disk I/O |
|
| Slow builds | Check `invoke-ci.jsonl` phase timestamps; check disk I/O |
|
||||||
| Template corrupt | Remove `*.lck` files; if persistent, restore from `F:\CI\Backups\` |
|
| Template corrupt | Remove `*.lck` files; if persistent, restore from `F:\CI\Backups\` |
|
||||||
| Snapshot missing | `vmrun listSnapshots <vmx>`; update `GITEA_CI_SNAPSHOT_NAME` |
|
| Snapshot missing | `vmrun listSnapshots <vmx>`; update `GITEA_CI_SNAPSHOT_NAME` |
|
||||||
| IP collision | `Remove-Item F:\CI\State\ip-leases\*.lease`; lower `capacity` |
|
| IP collision | `Remove-Item F:\CI\State\ip-leases\*.lease`; lower `capacity` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Organized by sprint area with pre-requisites, test steps, and pass/fail criteria
|
|||||||
| **Sprint 2** (Reliability) | 2.1/2.2/2.3/2.5 | Partial | §2.2/§2.3 validated locally 2026-05-10; §2.1/§2.5 need real VMs |
|
| **Sprint 2** (Reliability) | 2.1/2.2/2.3/2.5 | Partial | §2.2/§2.3 validated locally 2026-05-10; §2.1/§2.5 need real VMs |
|
||||||
| **Sprint 3** (Observability) | 4.1/4.3/4.4 | Partial | §4.3/§4.4 validated locally 2026-05-10; §4.1 (JSONL) needs real build job |
|
| **Sprint 3** (Observability) | 4.1/4.3/4.4 | Partial | §4.3/§4.4 validated locally 2026-05-10; §4.1 (JSONL) needs real build job |
|
||||||
| **Sprint 4-6** (Quality/Perf) | 1.4/3.1/3.6/5.2/5.3/5.4 | Partial | §1.4/§5.2/§5.3/§5.4 validated 2026-05-10; §3.1/§3.6 need real VMs |
|
| **Sprint 4-6** (Quality/Perf) | 1.4/3.1/3.6/5.2/5.3/5.4 | Partial | §1.4/§5.2/§5.3/§5.4 validated 2026-05-10; §3.1/§3.6 need real VMs |
|
||||||
| **Sprint 7** (Testing) | 5.1 | [x] Done | 22/22 Pester tests passing in 12.9s (re-validated 2026-05-11) |
|
| **Sprint 7** (Testing) | 5.1 | [x] Done | 22/22 Pester tests passing in 12.9s (re-validated 2026-05-11) |
|
||||||
| **§1.6** (Docs) | Threat model | [x] Done | BEST-PRACTICES.md verified 2026-05-10 |
|
| **§1.6** (Docs) | Threat model | [x] Done | BEST-PRACTICES.md verified 2026-05-10 |
|
||||||
| **§3.2** (Perf) | 7-Zip compression | Partial | Fallback path validated; in-VM 7-Zip speed test needs real VM |
|
| **§3.2** (Perf) | 7-Zip compression | Partial | Fallback path validated; in-VM 7-Zip speed test needs real VM |
|
||||||
| **§5.4** (PSScriptAnalyzer) | 0 errors, 298 warnings | [x] Done | All 6 actionable warnings fixed 2026-05-11; 0 Error severity violations |
|
| **§5.4** (PSScriptAnalyzer) | 0 errors, 298 warnings | [x] Done | All 6 actionable warnings fixed 2026-05-11; 0 Error severity violations |
|
||||||
|
|||||||
@@ -11,16 +11,16 @@ credenziali archiviate, ISO Windows Server presente).
|
|||||||
|
|
||||||
## Architettura: tre script
|
## Architettura: tre script
|
||||||
|
|
||||||
| Script | Dove gira | Scopo |
|
| Script | Dove gira | Scopo |
|
||||||
| ----------------------------------- | ------------- | -------------------------------------------------------------------- |
|
| ----------------------------------------------- | ------------- | -------------------------------------------------------------------- |
|
||||||
| `template/Deploy-WinBuild2025.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2025 unattended da ISO |
|
| `template/Deploy-WinBuild2025.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2025 unattended da ISO |
|
||||||
| `template/Prepare-WinBuild2025.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2025) |
|
| `template/Prepare-WinBuild2025.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2025) |
|
||||||
| `template/Install-CIToolchain-WinBuild2025.ps1` | **Dentro VM** | CI toolchain (user, .NET, Python, VS) + validazione hardening Deploy |
|
| `template/Install-CIToolchain-WinBuild2025.ps1` | **Dentro VM** | CI toolchain (user, .NET, Python, VS) + validazione hardening Deploy |
|
||||||
| `template/Deploy-WinBuild2022.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2022 unattended da ISO |
|
| `template/Deploy-WinBuild2022.ps1` | **Host** | Opzionale: crea VM e installa Windows Server 2022 unattended da ISO |
|
||||||
| `template/Prepare-WinBuild2022.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2022) |
|
| `template/Prepare-WinBuild2022.ps1` | **Host** | Orchestratore: copia + esegue Setup nel guest via WinRM (2022) |
|
||||||
| `template/Install-CIToolchain-WinBuild2022.ps1` | **Dentro VM** | CI toolchain per Windows Server 2022 (stesso flusso del 2025) |
|
| `template/Install-CIToolchain-WinBuild2022.ps1` | **Dentro VM** | CI toolchain per Windows Server 2022 (stesso flusso del 2025) |
|
||||||
| `template/Validate-DeployState.ps1` | **Host** | Valida stato post-Deploy prima di eseguire Prepare (2025 e 2022) |
|
| `template/Validate-DeployState.ps1` | **Host** | Valida stato post-Deploy prima di eseguire Prepare (2025 e 2022) |
|
||||||
| `template/Validate-SetupState.ps1` | **Host** | Valida stato post-Setup (Deploy + Setup) prima dello snapshot |
|
| `template/Validate-SetupState.ps1` | **Host** | Valida stato post-Setup (Deploy + Setup) prima dello snapshot |
|
||||||
|
|
||||||
**Confine Deploy / Setup** (refactor §7, 2026-05-10):
|
**Confine Deploy / Setup** (refactor §7, 2026-05-10):
|
||||||
- `Deploy-WinBuild2025.ps1` si occupa dell'**OS hardening** (Firewall, WinRM, UAC, Defender, UX tweaks, autologin Administrator, WU GPO locks). Se usato, Setup valida questi come Assert-Step senza re-applicarli.
|
- `Deploy-WinBuild2025.ps1` si occupa dell'**OS hardening** (Firewall, WinRM, UAC, Defender, UX tweaks, autologin Administrator, WU GPO locks). Se usato, Setup valida questi come Assert-Step senza re-applicarli.
|
||||||
@@ -145,7 +145,7 @@ Ogni step ha validazione `Assert-Step` (throw on failure, `[OK]` su pass):
|
|||||||
| `-BuildPassword` | (prompt) | Password per `ci_build` — mai hard-codare |
|
| `-BuildPassword` | (prompt) | Password per `ci_build` — mai hard-codare |
|
||||||
| `-BuildUsername` | ci_build | Account CI dentro la VM |
|
| `-BuildUsername` | ci_build | Account CI dentro la VM |
|
||||||
| `-DotNetSdkVersion` | 10.0 | Channel .NET SDK |
|
| `-DotNetSdkVersion` | 10.0 | Channel .NET SDK |
|
||||||
| `-SkipWindowsUpdate` | (off) | Pass-through a Install-CIToolchain-WinBuild2025.ps1 |
|
| `-SkipWindowsUpdate` | (off) | Pass-through a Install-CIToolchain-WinBuild2025.ps1 |
|
||||||
| `-StoreCredential` | (off) | Registra `BuildUsername`/`BuildPassword` in Windows Credential Manager |
|
| `-StoreCredential` | (off) | Registra `BuildUsername`/`BuildPassword` in Windows Credential Manager |
|
||||||
| `-CredentialTarget` | BuildVMGuest | Target Credential Manager (deve corrispondere a quanto usato da Invoke-CIJob) |
|
| `-CredentialTarget` | BuildVMGuest | Target Credential Manager (deve corrispondere a quanto usato da Invoke-CIJob) |
|
||||||
|
|
||||||
@@ -292,15 +292,15 @@ toolchain (.NET, VS Build Tools, Python).
|
|||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
| Sintomo | Diagnosi / Fix |
|
| Sintomo | Diagnosi / Fix |
|
||||||
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
|
||||||
| `Cannot reach $VMIPAddress via WinRM` | VM non avviata, WinRM non abilitato, IP errato — verifica con ipconfig |
|
| `Cannot reach $VMIPAddress via WinRM` | VM non avviata, WinRM non abilitato, IP errato — verifica con ipconfig |
|
||||||
| `Install-CIToolchain-WinBuild2025.ps1 exited with code 3010` | Reboot richiesto post-WU. Re-run con `-SkipWindowsUpdate` |
|
| `Install-CIToolchain-WinBuild2025.ps1 exited with code 3010` | Reboot richiesto post-WU. Re-run con `-SkipWindowsUpdate` |
|
||||||
| `[Defender] Validation failed: GPO key` | Defender riattivato da Windows Update — disabilita via gpedit + reboot |
|
| `[Defender] Validation failed: GPO key` | Defender riattivato da Windows Update — disabilita via gpedit + reboot |
|
||||||
| `VS Build Tools installation timed out` | Network slow o cache corrotta. Re-run con cache pulita (`C:\ProgramData\Microsoft\VisualStudio\Packages`) |
|
| `VS Build Tools installation timed out` | Network slow o cache corrotta. Re-run con cache pulita (`C:\ProgramData\Microsoft\VisualStudio\Packages`) |
|
||||||
| `Python version match` fail | `$PythonVersion` ≠ versione installata. Aggiorna param o reinstalla |
|
| `Python version match` fail | `$PythonVersion` ≠ versione installata. Aggiorna param o reinstalla |
|
||||||
| Post-setup `MSBuild not found` | VS install fallita silenziosa. Check `C:\CI\vs_log.txt` |
|
| Post-setup `MSBuild not found` | VS install fallita silenziosa. Check `C:\CI\vs_log.txt` |
|
||||||
| Pre-snapshot Final check fail | Stato VM rotto — non prendere snapshot. Re-run o ricomincia da zero |
|
| Pre-snapshot Final check fail | Stato VM rotto — non prendere snapshot. Re-run o ricomincia da zero |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+87
-80
@@ -8,23 +8,30 @@
|
|||||||
|
|
||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
1. [System Overview](#1-system-overview)
|
- [Workflow Authoring Reference](#workflow-authoring-reference)
|
||||||
2. [Runner Labels](#2-runner-labels)
|
- [Table of Contents](#table-of-contents)
|
||||||
3. [Shell Requirement](#3-shell-requirement)
|
- [1. System Overview](#1-system-overview)
|
||||||
4. [Environment Variables (Injected by Runner)](#4-environment-variables-injected-by-runner)
|
- [2. Runner Labels](#2-runner-labels)
|
||||||
5. [Invoke-CIJob.ps1 Parameter Reference](#5-invoke-cijobps1-parameter-reference)
|
- [3. Shell Requirement](#3-shell-requirement)
|
||||||
6. [URL Conventions](#6-url-conventions)
|
- [4. Environment Variables (Injected by Runner)](#4-environment-variables-injected-by-runner)
|
||||||
7. [Artifact Path Convention](#7-artifact-path-convention)
|
- [5. Invoke-CIJob.ps1 Parameter Reference](#5-invoke-cijobps1-parameter-reference)
|
||||||
8. [Workflow Patterns](#8-workflow-patterns)
|
- [Mandatory parameters](#mandatory-parameters)
|
||||||
- [8.1 Windows build (host-clone mode)](#81-windows-build-host-clone-mode)
|
- [Optional parameters](#optional-parameters)
|
||||||
- [8.2 Linux build (host-clone mode)](#82-linux-build-host-clone-mode)
|
- [6. URL Conventions](#6-url-conventions)
|
||||||
- [8.3 Windows build (UseGitClone mode)](#83-windows-build-usegitclone-mode)
|
- [Host-clone mode (default, no `-UseGitClone`)](#host-clone-mode-default-no--usegitclone)
|
||||||
- [8.4 Linux build (UseGitClone mode)](#84-linux-build-usegitclone-mode)
|
- [UseGitClone mode (`-UseGitClone`)](#usegitclone-mode--usegitclone)
|
||||||
- [8.5 PSScriptAnalyzer lint](#85-psscriptanalyzer-lint)
|
- [Quick reference](#quick-reference)
|
||||||
- [8.6 Matrix build (multiple configs)](#86-matrix-build-multiple-configs)
|
- [7. Artifact Path Convention](#7-artifact-path-convention)
|
||||||
9. [Checkout Step](#9-checkout-step)
|
- [8. Workflow Patterns](#8-workflow-patterns)
|
||||||
10. [Timeouts](#10-timeouts)
|
- [8.1 Windows build (host-clone mode)](#81-windows-build-host-clone-mode)
|
||||||
11. [Common Mistakes](#11-common-mistakes)
|
- [8.2 Linux build (host-clone mode)](#82-linux-build-host-clone-mode)
|
||||||
|
- [8.3 Windows build (UseGitClone mode)](#83-windows-build-usegitclone-mode)
|
||||||
|
- [8.4 Linux build (UseGitClone mode)](#84-linux-build-usegitclone-mode)
|
||||||
|
- [8.5 PSScriptAnalyzer lint](#85-psscriptanalyzer-lint)
|
||||||
|
- [8.6 Matrix build (multiple configs)](#86-matrix-build-multiple-configs)
|
||||||
|
- [9. Checkout Step](#9-checkout-step)
|
||||||
|
- [10. Timeouts](#10-timeouts)
|
||||||
|
- [11. Common Mistakes](#11-common-mistakes)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -50,12 +57,12 @@ Supported guest OS: Windows Server 2025 / 2022 (WinRM transport), Ubuntu 24.04 (
|
|||||||
|
|
||||||
## 2. Runner Labels
|
## 2. Runner Labels
|
||||||
|
|
||||||
| Label | Configured as | Use for |
|
| Label | Configured as | Use for |
|
||||||
| ---------------- | ---------------- | ----------------------------------- |
|
| --------------- | -------------------- | ------------------------------------------ |
|
||||||
| `windows-build` | `windows-build:host` | Windows VM builds, Windows-only tools |
|
| `windows-build` | `windows-build:host` | Windows VM builds, Windows-only tools |
|
||||||
| `linux-build` | `linux-build:host` | Linux VM builds (cross-compile, GCC/Clang) |
|
| `linux-build` | `linux-build:host` | Linux VM builds (cross-compile, GCC/Clang) |
|
||||||
| `dotnet` | `dotnet:host` | Alias for windows-build (legacy) |
|
| `dotnet` | `dotnet:host` | Alias for windows-build (legacy) |
|
||||||
| `msbuild` | `msbuild:host` | Alias for windows-build (legacy) |
|
| `msbuild` | `msbuild:host` | Alias for windows-build (legacy) |
|
||||||
|
|
||||||
Both `windows-build` and `linux-build` run on the same physical host. Only the
|
Both `windows-build` and `linux-build` run on the same physical host. Only the
|
||||||
template VM used differs. Use `windows-build` unless you specifically need a Linux
|
template VM used differs. Use `windows-build` unless you specifically need a Linux
|
||||||
@@ -91,14 +98,14 @@ required runtime and may not be present on the host.
|
|||||||
These variables are automatically available in every job step. Do not redeclare them
|
These variables are automatically available in every job step. Do not redeclare them
|
||||||
in the workflow unless you need to override the default.
|
in the workflow unless you need to override the default.
|
||||||
|
|
||||||
| Variable | Value (default) | Description |
|
| Variable | Value (default) | Description |
|
||||||
| ---------------------------- | ---------------------------------------------------- | --------------------------------------- |
|
| ------------------------------ | --------------------------------------------------- | -------------------------------------- |
|
||||||
| `GITEA_CI_TEMPLATE_PATH` | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` | Windows 2025 template VMX path |
|
| `GITEA_CI_TEMPLATE_PATH` | `F:\CI\Templates\WinBuild2025\WinBuild2025.vmx` | Windows 2025 template VMX path |
|
||||||
| `GITEA_CI_LINUX_TEMPLATE_PATH` | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` | Ubuntu 24.04 template VMX path |
|
| `GITEA_CI_LINUX_TEMPLATE_PATH` | `F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx` | Ubuntu 24.04 template VMX path |
|
||||||
| `GITEA_CI_CLONE_BASE_DIR` | `F:\CI\BuildVMs` | Directory for ephemeral VM clones |
|
| `GITEA_CI_CLONE_BASE_DIR` | `F:\CI\BuildVMs` | Directory for ephemeral VM clones |
|
||||||
| `GITEA_CI_ARTIFACT_DIR` | `F:\CI\Artifacts` | Root directory for job artifacts |
|
| `GITEA_CI_ARTIFACT_DIR` | `F:\CI\Artifacts` | Root directory for job artifacts |
|
||||||
| `GITEA_CI_GUEST_CRED_TARGET` | `BuildVMGuest` | Credential Manager target for guest VM |
|
| `GITEA_CI_GUEST_CRED_TARGET` | `BuildVMGuest` | Credential Manager target for guest VM |
|
||||||
| `GITEA_CI_SSH_KEY_PATH` | `F:\CI\keys\ci_linux` | SSH private key for Linux guest access |
|
| `GITEA_CI_SSH_KEY_PATH` | `F:\CI\keys\ci_linux` | SSH private key for Linux guest access |
|
||||||
|
|
||||||
Invoke-CIJob.ps1 reads `GITEA_CI_TEMPLATE_PATH` and `GITEA_CI_CLONE_BASE_DIR`
|
Invoke-CIJob.ps1 reads `GITEA_CI_TEMPLATE_PATH` and `GITEA_CI_CLONE_BASE_DIR`
|
||||||
automatically if `-TemplatePath` and `-CloneBaseDir` are not passed explicitly.
|
automatically if `-TemplatePath` and `-CloneBaseDir` are not passed explicitly.
|
||||||
@@ -111,33 +118,33 @@ Script location (fixed on host): `N:\Code\Workspace\Local-CI-CD-System\scripts\I
|
|||||||
|
|
||||||
### Mandatory parameters
|
### Mandatory parameters
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| ----------- | ------ | --------------------------------------------------------------- |
|
| ---------- | ------ | ------------------------------------------------------------------ |
|
||||||
| `-JobId` | string | Unique job ID. Use `${{ github.run_id }}` or `run_id-run_attempt`. |
|
| `-JobId` | string | Unique job ID. Use `${{ github.run_id }}` or `run_id-run_attempt`. |
|
||||||
| `-RepoUrl` | string | Git URL of the repository to clone/build. See Section 6. |
|
| `-RepoUrl` | string | Git URL of the repository to clone/build. See Section 6. |
|
||||||
| `-Branch` | string | Branch to build. Use `${{ github.ref_name }}`. |
|
| `-Branch` | string | Branch to build. Use `${{ github.ref_name }}`. |
|
||||||
|
|
||||||
### Optional parameters
|
### Optional parameters
|
||||||
|
|
||||||
| Parameter | Type | Default | Description |
|
| Parameter | Type | Default | Description |
|
||||||
| ------------------------ | ------ | --------------------------- | -------------------------------------------------------------- |
|
| ------------------------ | ------ | ------------------------------ | ---------------------------------------------------------------- |
|
||||||
| `-Commit` | string | `''` | Specific commit SHA. Use `${{ github.sha }}`. Empty = HEAD. |
|
| `-Commit` | string | `''` | Specific commit SHA. Use `${{ github.sha }}`. Empty = HEAD. |
|
||||||
| `-TemplatePath` | string | `$env:GITEA_CI_TEMPLATE_PATH` | Full path to template VMX. |
|
| `-TemplatePath` | string | `$env:GITEA_CI_TEMPLATE_PATH` | Full path to template VMX. |
|
||||||
| `-SnapshotName` | string | `BaseClean` | Template snapshot name to clone from. |
|
| `-SnapshotName` | string | `BaseClean` | Template snapshot name to clone from. |
|
||||||
| `-GuestOS` | string | `Auto` | `Windows`, `Linux`, or `Auto` (detected from VMX guestOS field). |
|
| `-GuestOS` | string | `Auto` | `Windows`, `Linux`, or `Auto` (detected from VMX guestOS field). |
|
||||||
| `-BuildCommand` | string | `''` | Shell command to run inside VM. Empty = `dotnet build`. |
|
| `-BuildCommand` | string | `''` | Shell command to run inside VM. Empty = `dotnet build`. |
|
||||||
| `-GuestArtifactSource` | string | `dist` | Path inside VM guest from which artifacts are collected. |
|
| `-GuestArtifactSource` | string | `dist` | Path inside VM guest from which artifacts are collected. |
|
||||||
| `-Submodules` | switch | off | Pass to clone with `--recurse-submodules`. |
|
| `-Submodules` | switch | off | Pass to clone with `--recurse-submodules`. |
|
||||||
| `-UseGitClone` | switch | off | Skip host-side clone; let the guest VM clone directly via HTTPS. |
|
| `-UseGitClone` | switch | off | Skip host-side clone; let the guest VM clone directly via HTTPS. |
|
||||||
| `-GiteaCredentialTarget` | string | `GiteaPAT` | Credential Manager target for Gitea PAT (UseGitClone only). |
|
| `-GiteaCredentialTarget` | string | `GiteaPAT` | Credential Manager target for Gitea PAT (UseGitClone only). |
|
||||||
| `-GuestCredentialTarget` | string | `BuildVMGuest` | Credential Manager target for Windows guest VM login. |
|
| `-GuestCredentialTarget` | string | `BuildVMGuest` | Credential Manager target for Windows guest VM login. |
|
||||||
| `-SshKeyPath` | string | `F:\CI\keys\ci_linux` | SSH key for Linux guest (ignored for Windows). |
|
| `-SshKeyPath` | string | `F:\CI\keys\ci_linux` | SSH key for Linux guest (ignored for Windows). |
|
||||||
| `-SshUser` | string | `ci_build` | SSH username for Linux guest (ignored for Windows). |
|
| `-SshUser` | string | `ci_build` | SSH username for Linux guest (ignored for Windows). |
|
||||||
| `-CloneBaseDir` | string | `$env:GITEA_CI_CLONE_BASE_DIR` | Directory for VM clone files. |
|
| `-CloneBaseDir` | string | `$env:GITEA_CI_CLONE_BASE_DIR` | Directory for VM clone files. |
|
||||||
| `-ArtifactBaseDir` | string | `F:\CI\Artifacts` | Root artifact directory on host. |
|
| `-ArtifactBaseDir` | string | `F:\CI\Artifacts` | Root artifact directory on host. |
|
||||||
| `-VMIPAddress` | string | `''` | Override guest IP. Empty = auto-detected via vmrun. |
|
| `-VMIPAddress` | string | `''` | Override guest IP. Empty = auto-detected via vmrun. |
|
||||||
| `-LogDir` | string | `F:\CI\Logs` | Directory for per-job transcripts and JSONL logs. |
|
| `-LogDir` | string | `F:\CI\Logs` | Directory for per-job transcripts and JSONL logs. |
|
||||||
| `-LogRetentionDays` | int | `30` | Days before log directories are purged. `0` = disabled. |
|
| `-LogRetentionDays` | int | `30` | Days before log directories are purged. `0` = disabled. |
|
||||||
|
|
||||||
Exit codes: `0` = success, `1` = failure (VM is always destroyed regardless).
|
Exit codes: `0` = success, `1` = failure (VM is always destroyed regardless).
|
||||||
|
|
||||||
@@ -173,11 +180,11 @@ https://gitea.emulab.it/<owner>/<repo>.git
|
|||||||
|
|
||||||
### Quick reference
|
### Quick reference
|
||||||
|
|
||||||
| Mode | RepoUrl to use |
|
| Mode | RepoUrl to use |
|
||||||
| ----------------- | ---------------------------------------------------------- |
|
| ----------------- | -------------------------------------------- |
|
||||||
| Default (Windows) | `ssh://gitea-ci/<owner>/<repo>.git` |
|
| Default (Windows) | `ssh://gitea-ci/<owner>/<repo>.git` |
|
||||||
| Default (Linux) | `ssh://gitea-ci/<owner>/<repo>.git` |
|
| Default (Linux) | `ssh://gitea-ci/<owner>/<repo>.git` |
|
||||||
| UseGitClone | `https://gitea.emulab.it/<owner>/<repo>.git` |
|
| UseGitClone | `https://gitea.emulab.it/<owner>/<repo>.git` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -537,13 +544,13 @@ The CI scripts are at a fixed path on the runner host and do not need a checkout
|
|||||||
|
|
||||||
## 10. Timeouts
|
## 10. Timeouts
|
||||||
|
|
||||||
| Build type | Recommended `timeout-minutes` |
|
| Build type | Recommended `timeout-minutes` |
|
||||||
| --------------------------- | ----------------------------- |
|
| -------------------------- | ----------------------------- |
|
||||||
| Windows build (typical) | 90 |
|
| Windows build (typical) | 90 |
|
||||||
| Windows build (large/slow) | 120 |
|
| Windows build (large/slow) | 120 |
|
||||||
| Linux build (typical) | 60 |
|
| Linux build (typical) | 60 |
|
||||||
| Lint / static analysis | 10 |
|
| Lint / static analysis | 10 |
|
||||||
| Template provisioning | 180 |
|
| Template provisioning | 180 |
|
||||||
|
|
||||||
The runner-level timeout is `2h` (from `runner/config.yaml`). Keep job timeouts
|
The runner-level timeout is `2h` (from `runner/config.yaml`). Keep job timeouts
|
||||||
below that value. If a job timeout fires, the VM may not be cleanly destroyed —
|
below that value. If a job timeout fires, the VM may not be cleanly destroyed —
|
||||||
@@ -553,16 +560,16 @@ the cleanup task `Cleanup-OrphanedBuildVMs.ps1` handles these cases.
|
|||||||
|
|
||||||
## 11. Common Mistakes
|
## 11. Common Mistakes
|
||||||
|
|
||||||
| Mistake | Correct approach |
|
| Mistake | Correct approach |
|
||||||
| ------- | ---------------- |
|
| ---------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||||
| `shell: pwsh` | Use `shell: powershell` (PS 5.1, not Core) |
|
| `shell: pwsh` | Use `shell: powershell` (PS 5.1, not Core) |
|
||||||
| SSH alias URL with `-UseGitClone` | Use `https://gitea.emulab.it/...` for UseGitClone; SSH alias is host-only |
|
| SSH alias URL with `-UseGitClone` | Use `https://gitea.emulab.it/...` for UseGitClone; SSH alias is host-only |
|
||||||
| HTTPS URL without `-UseGitClone` | SSH alias `ssh://gitea-ci/...` for host-clone mode |
|
| HTTPS URL without `-UseGitClone` | SSH alias `ssh://gitea-ci/...` for host-clone mode |
|
||||||
| `$env:GITHUB_WORKSPACE` to find CI scripts | Use hardcoded `N:\Code\Workspace\Local-CI-CD-System\scripts\` |
|
| `$env:GITHUB_WORKSPACE` to find CI scripts | Use hardcoded `N:\Code\Workspace\Local-CI-CD-System\scripts\` |
|
||||||
| `actions/checkout@v4` in build jobs | Omit it; source is handled by Invoke-CIJob.ps1 |
|
| `actions/checkout@v4` in build jobs | Omit it; source is handled by Invoke-CIJob.ps1 |
|
||||||
| `runs-on: ubuntu-latest` or `windows-latest` | Use `windows-build` or `linux-build` — cloud runners are not available |
|
| `runs-on: ubuntu-latest` or `windows-latest` | Use `windows-build` or `linux-build` — cloud runners are not available |
|
||||||
| `&&` in PowerShell run blocks | Not valid in PS 5.1; use `if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }` |
|
| `&&` in PowerShell run blocks | Not valid in PS 5.1; use `if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }` |
|
||||||
| Hardcoded IP in `-VMIPAddress` | Omit it; auto-detected via `vmrun getGuestIPAddress` |
|
| Hardcoded IP in `-VMIPAddress` | Omit it; auto-detected via `vmrun getGuestIPAddress` |
|
||||||
| `-TemplatePath` for Linux without `GITEA_CI_LINUX_TEMPLATE_PATH` | Pass `$env:GITEA_CI_LINUX_TEMPLATE_PATH` or the full path explicitly |
|
| `-TemplatePath` for Linux without `GITEA_CI_LINUX_TEMPLATE_PATH` | Pass `$env:GITEA_CI_LINUX_TEMPLATE_PATH` or the full path explicitly |
|
||||||
| Forgetting `-SnapshotName 'BaseClean-Linux'` for Linux | Linux template uses a different snapshot name than Windows (`BaseClean`) |
|
| Forgetting `-SnapshotName 'BaseClean-Linux'` for Linux | Linux template uses a different snapshot name than Windows (`BaseClean`) |
|
||||||
| Same `-JobId` for matrix jobs | Append matrix key: `${{ github.run_id }}-${{ matrix.config }}` |
|
| Same `-JobId` for matrix jobs | Append matrix key: `${{ github.run_id }}-${{ matrix.config }}` |
|
||||||
|
|||||||
+12
-12
@@ -24,19 +24,19 @@ Top 3 risks today, in order: (1) the Linux matrix leg builds against the Windows
|
|||||||
|
|
||||||
The optimistic [TODO.md](../TODO.md) and the conservative [docs/TEST-PLAN-v1.3-to-HEAD.md](../docs/TEST-PLAN-v1.3-to-HEAD.md) disagree. The honest state, reconciled against the source files, is below.
|
The optimistic [TODO.md](../TODO.md) and the conservative [docs/TEST-PLAN-v1.3-to-HEAD.md](../docs/TEST-PLAN-v1.3-to-HEAD.md) disagree. The honest state, reconciled against the source files, is below.
|
||||||
|
|
||||||
| Area | Genuinely Done | Partially Done | Unvalidated / Broken |
|
| Area | Genuinely Done | Partially Done | Unvalidated / Broken |
|
||||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
|
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||||
| Windows VM lifecycle | Clone, start, IP detect, WinRM HTTPS, build, artifacts, destroy ([scripts/Invoke-CIJob.ps1](../scripts/Invoke-CIJob.ps1), [scripts/New-BuildVM.ps1](../scripts/New-BuildVM.ps1), [scripts/Wait-VMReady.ps1](../scripts/Wait-VMReady.ps1), [scripts/Invoke-RemoteBuild.ps1](../scripts/Invoke-RemoteBuild.ps1), [scripts/Get-BuildArtifacts.ps1](../scripts/Get-BuildArtifacts.ps1), [scripts/Remove-BuildVM.ps1](../scripts/Remove-BuildVM.ps1)) | — | Real 4-way concurrency |
|
| Windows VM lifecycle | Clone, start, IP detect, WinRM HTTPS, build, artifacts, destroy ([scripts/Invoke-CIJob.ps1](../scripts/Invoke-CIJob.ps1), [scripts/New-BuildVM.ps1](../scripts/New-BuildVM.ps1), [scripts/Wait-VMReady.ps1](../scripts/Wait-VMReady.ps1), [scripts/Invoke-RemoteBuild.ps1](../scripts/Invoke-RemoteBuild.ps1), [scripts/Get-BuildArtifacts.ps1](../scripts/Get-BuildArtifacts.ps1), [scripts/Remove-BuildVM.ps1](../scripts/Remove-BuildVM.ps1)) | — | Real 4-way concurrency |
|
||||||
| Linux VM lifecycle | Cloud-init deploy, SSH transport, IP via `guestinfo.ci-ip` ([template/Deploy-LinuxBuild2404.ps1](../template/Deploy-LinuxBuild2404.ps1), [scripts/_Transport.psm1](../scripts/_Transport.psm1)) | Generic validator (Windows-only) ([template/Validate-DeployState.ps1](../template/Validate-DeployState.ps1)) | **FIXED 2026-05-12**: Matrix workflow Linux leg now picks correct template (C1) |
|
| Linux VM lifecycle | Cloud-init deploy, SSH transport, IP via `guestinfo.ci-ip` ([template/Deploy-LinuxBuild2404.ps1](../template/Deploy-LinuxBuild2404.ps1), [scripts/_Transport.psm1](../scripts/_Transport.psm1)) | Generic validator (Windows-only) ([template/Validate-DeployState.ps1](../template/Validate-DeployState.ps1)) | **FIXED 2026-05-12**: Matrix workflow Linux leg now picks correct template (C1) |
|
||||||
| Composite action | Inputs forwarded via env vars, step outputs work, success and failure upload paths ([gitea/actions/local-ci-build/action.yml](../gitea/actions/local-ci-build/action.yml)) | — | **FIXED 2026-05-12**: `outputs:` block corrected (H2); hardcoded `N:\` replaced with env var (H11) |
|
| Composite action | Inputs forwarded via env vars, step outputs work, success and failure upload paths ([gitea/actions/local-ci-build/action.yml](../gitea/actions/local-ci-build/action.yml)) | — | **FIXED 2026-05-12**: `outputs:` block corrected (H2); hardcoded `N:\` replaced with env var (H11) |
|
||||||
| Concurrency | File mutex + lease design ([scripts/Invoke-CIJob.ps1](../scripts/Invoke-CIJob.ps1) ~L303-L460) | **FIXED 2026-05-12**: Stale lock auto-cleanup added (H5) | 4-way burn-in never run |
|
| Concurrency | File mutex + lease design ([scripts/Invoke-CIJob.ps1](../scripts/Invoke-CIJob.ps1) ~L303-L460) | **FIXED 2026-05-12**: Stale lock auto-cleanup added (H5) | 4-way burn-in never run |
|
||||||
| Credential handling | Windows Credential Manager target `BuildVMGuest`; PAT via Credential Manager target `GiteaPAT`; Windows Mode 2 uses `http.extraHeader` | — | **FIXED 2026-05-12**: Linux Mode 2 PAT now uses `http.extraHeader` (H3); `ExtraGuestEnv` logging redacted (C2) |
|
| Credential handling | Windows Credential Manager target `BuildVMGuest`; PAT via Credential Manager target `GiteaPAT`; Windows Mode 2 uses `http.extraHeader` | — | **FIXED 2026-05-12**: Linux Mode 2 PAT now uses `http.extraHeader` (H3); `ExtraGuestEnv` logging redacted (C2) |
|
||||||
| Maintenance | Disk watcher, runner health watcher, retention, orphan cleanup, scheduled tasks ([scripts/Watch-DiskSpace.ps1](../scripts/Watch-DiskSpace.ps1), [scripts/Watch-RunnerHealth.ps1](../scripts/Watch-RunnerHealth.ps1), [scripts/Invoke-RetentionPolicy.ps1](../scripts/Invoke-RetentionPolicy.ps1), [scripts/Cleanup-OrphanedBuildVMs.ps1](../scripts/Cleanup-OrphanedBuildVMs.ps1), [scripts/Register-CIScheduledTasks.ps1](../scripts/Register-CIScheduledTasks.ps1)) | — | — |
|
| Maintenance | Disk watcher, runner health watcher, retention, orphan cleanup, scheduled tasks ([scripts/Watch-DiskSpace.ps1](../scripts/Watch-DiskSpace.ps1), [scripts/Watch-RunnerHealth.ps1](../scripts/Watch-RunnerHealth.ps1), [scripts/Invoke-RetentionPolicy.ps1](../scripts/Invoke-RetentionPolicy.ps1), [scripts/Cleanup-OrphanedBuildVMs.ps1](../scripts/Cleanup-OrphanedBuildVMs.ps1), [scripts/Register-CIScheduledTasks.ps1](../scripts/Register-CIScheduledTasks.ps1)) | — | — |
|
||||||
| Backup | [scripts/Backup-CITemplate.ps1](../scripts/Backup-CITemplate.ps1) functional; **FIXED 2026-05-12**: default `WinBuild2025`, `-AllTemplates` switch added (H7) | — | — |
|
| Backup | [scripts/Backup-CITemplate.ps1](../scripts/Backup-CITemplate.ps1) functional; **FIXED 2026-05-12**: default `WinBuild2025`, `-AllTemplates` switch added (H7) | — | — |
|
||||||
| Host bootstrap | Runner install, NSSM service, credential prompts ([Setup-Host.ps1](../Setup-Host.ps1)); **FIXED 2026-05-12**: directory array updated (H6); `F:\CI\Cache\pip` created on live host | — | act_runner runs as LocalSystem — H8 SSH alias mismatch confirmed, not yet fixed |
|
| Host bootstrap | Runner install, NSSM service, credential prompts ([Setup-Host.ps1](../Setup-Host.ps1)); **FIXED 2026-05-12**: directory array updated (H6); `F:\CI\Cache\pip` created on live host | — | act_runner runs as LocalSystem — H8 SSH alias mismatch confirmed, not yet fixed |
|
||||||
| Observability | JSONL per-job events, Event Log, optional webhook | Phase-duration summary | Cross-job analysis tool |
|
| Observability | JSONL per-job events, Event Log, optional webhook | Phase-duration summary | Cross-job analysis tool |
|
||||||
| Tests | Argument-parsing Pester suite over fake `vmrun.cmd` (4 files in [tests/](../tests/)) | — | Orchestrator state machine, real-VM smoke tests, lock concurrency |
|
| Tests | Argument-parsing Pester suite over fake `vmrun.cmd` (4 files in [tests/](../tests/)) | — | Orchestrator state machine, real-VM smoke tests, lock concurrency |
|
||||||
| Documentation | [docs/ARCHITECTURE.md](../docs/ARCHITECTURE.md), [docs/CI-FLOW.md](../docs/CI-FLOW.md), [docs/RUNBOOK.md](../docs/RUNBOOK.md), [docs/BEST-PRACTICES.md](../docs/BEST-PRACTICES.md), [docs/WORKFLOW-AUTHORING.md](../docs/WORKFLOW-AUTHORING.md) | Drift: README claims production-ready; CI-FLOW claims partial-artifacts-on-failure; test plan uses PS7 syntax and wrong param names | Consolidated template-refresh runbook |
|
| Documentation | [docs/ARCHITECTURE.md](../docs/ARCHITECTURE.md), [docs/CI-FLOW.md](../docs/CI-FLOW.md), [docs/RUNBOOK.md](../docs/RUNBOOK.md), [docs/BEST-PRACTICES.md](../docs/BEST-PRACTICES.md), [docs/WORKFLOW-AUTHORING.md](../docs/WORKFLOW-AUTHORING.md) | Drift: README claims production-ready; CI-FLOW claims partial-artifacts-on-failure; test plan uses PS7 syntax and wrong param names | Consolidated template-refresh runbook |
|
||||||
|
|
||||||
The README is genuinely ahead of the evidence. The accurate label is *feature-complete homelab CI awaiting stabilization pass*. Everything in this plan exists to close that gap.
|
The README is genuinely ahead of the evidence. The accurate label is *feature-complete homelab CI awaiting stabilization pass*. Everything in this plan exists to close that gap.
|
||||||
|
|
||||||
|
|||||||
+84
-84
@@ -30,32 +30,32 @@ The rest of this document expands on these and 30+ smaller findings.
|
|||||||
|
|
||||||
The system declares itself "production-ready" in `README.md` line 1. Measured against what a reasonable definition of that phrase requires, here is the state:
|
The system declares itself "production-ready" in `README.md` line 1. Measured against what a reasonable definition of that phrase requires, here is the state:
|
||||||
|
|
||||||
| Capability | Status | Evidence |
|
| Capability | Status | Evidence |
|
||||||
| --- | --- | --- |
|
| ---------------------------------------------- | ------------ | ---------------------------------------------------------------------------------------- |
|
||||||
| Ephemeral VM lifecycle (clone, start, destroy) | Complete | `scripts/New-BuildVM.ps1`, `Remove-BuildVM.ps1`, `Invoke-CIJob.ps1` |
|
| Ephemeral VM lifecycle (clone, start, destroy) | Complete | `scripts/New-BuildVM.ps1`, `Remove-BuildVM.ps1`, `Invoke-CIJob.ps1` |
|
||||||
| Windows guest (WinRM HTTPS) | Complete | `Invoke-RemoteBuild.ps1`, `Get-BuildArtifacts.ps1` Windows branch |
|
| Windows guest (WinRM HTTPS) | Complete | `Invoke-RemoteBuild.ps1`, `Get-BuildArtifacts.ps1` Windows branch |
|
||||||
| Linux guest (SSH) | Complete | `_Transport.psm1`, Linux branches in build/artifact scripts |
|
| Linux guest (SSH) | Complete | `_Transport.psm1`, Linux branches in build/artifact scripts |
|
||||||
| Auto-detect guest OS from VMX | Complete | `Invoke-CIJob.ps1` `guestOS` regex |
|
| Auto-detect guest OS from VMX | Complete | `Invoke-CIJob.ps1` `guestOS` regex |
|
||||||
| Host-clone mode + zip transfer (Mode 1) | Complete | Default path in `Invoke-RemoteBuild.ps1` |
|
| Host-clone mode + zip transfer (Mode 1) | Complete | Default path in `Invoke-RemoteBuild.ps1` |
|
||||||
| In-VM `git clone` (Mode 2) | Complete | `-UseGitClone`, PAT via `http.extraHeader` |
|
| In-VM `git clone` (Mode 2) | Complete | `-UseGitClone`, PAT via `http.extraHeader` |
|
||||||
| Credential storage (CredentialManager) | Complete | `BuildVMGuest`, `GiteaPAT` |
|
| Credential storage (CredentialManager) | Complete | `BuildVMGuest`, `GiteaPAT` |
|
||||||
| Reusable composite action | Complete | `gitea/actions/local-ci-build/action.yml` |
|
| Reusable composite action | Complete | `gitea/actions/local-ci-build/action.yml` |
|
||||||
| Build matrix Windows + Linux | Complete | `gitea/workflows/build-nsInnoUnp.yml` |
|
| Build matrix Windows + Linux | Complete | `gitea/workflows/build-nsInnoUnp.yml` |
|
||||||
| Shared NuGet/pip cache via HGFS | Complete | `Set-TemplateSharedFolders.ps1`, `-UseSharedCache` |
|
| Shared NuGet/pip cache via HGFS | Complete | `Set-TemplateSharedFolders.ps1`, `-UseSharedCache` |
|
||||||
| Structured JSONL logs | Complete | `Write-JobEvent` in `Invoke-CIJob.ps1` |
|
| Structured JSONL logs | Complete | `Write-JobEvent` in `Invoke-CIJob.ps1` |
|
||||||
| Scheduled maintenance | Complete | `Register-CIScheduledTasks.ps1` (4 tasks) |
|
| Scheduled maintenance | Complete | `Register-CIScheduledTasks.ps1` (4 tasks) |
|
||||||
| Disk-space + runner-health watchdogs | Complete | `Watch-DiskSpace.ps1`, `Watch-RunnerHealth.ps1` |
|
| Disk-space + runner-health watchdogs | Complete | `Watch-DiskSpace.ps1`, `Watch-RunnerHealth.ps1` |
|
||||||
| Retention policy with aggressive fallback | Complete | `Invoke-RetentionPolicy.ps1` |
|
| Retention policy with aggressive fallback | Complete | `Invoke-RetentionPolicy.ps1` |
|
||||||
| Orphan cleanup | Complete | `Cleanup-OrphanedBuildVMs.ps1` |
|
| Orphan cleanup | Complete | `Cleanup-OrphanedBuildVMs.ps1` |
|
||||||
| Template backup before refresh | Complete | `Backup-CITemplate.ps1` |
|
| Template backup before refresh | Complete | `Backup-CITemplate.ps1` |
|
||||||
| Benchmark harness | Complete | `Measure-CIBenchmark.ps1` |
|
| Benchmark harness | Complete | `Measure-CIBenchmark.ps1` |
|
||||||
| Secret injection into guest (`ExtraGuestEnv`) | Complete | Forwarded host → action → `Invoke-CIJob` → `Invoke-RemoteBuild` |
|
| Secret injection into guest (`ExtraGuestEnv`) | Complete | Forwarded host → action → `Invoke-CIJob` → `Invoke-RemoteBuild` |
|
||||||
| Pester unit tests | Stub-level | `tests/*.Tests.ps1`, all use fake `vmrun.cmd` |
|
| Pester unit tests | Stub-level | `tests/*.Tests.ps1`, all use fake `vmrun.cmd` |
|
||||||
| Automated integration test | **Missing** | No automated harness exercises real VMs |
|
| Automated integration test | **Missing** | No automated harness exercises real VMs |
|
||||||
| Concurrency burn-in | **Missing** | `TODO.md §2.1` admits "race non riprodotta in e2e-008/009" |
|
| Concurrency burn-in | **Missing** | `TODO.md §2.1` admits "race non riprodotta in e2e-008/009" |
|
||||||
| Multi-host federation | Not in scope | `TODO.md §6.3` deferred |
|
| Multi-host federation | Not in scope | `TODO.md §6.3` deferred |
|
||||||
| Template snapshot refresh procedure | Partial | `Backup-CITemplate.ps1` exists; refresh procedure not codified |
|
| Template snapshot refresh procedure | Partial | `Backup-CITemplate.ps1` exists; refresh procedure not codified |
|
||||||
| Setup-Host post-conditions documented | Partial | `Setup-Host.ps1` does the work but `Validate-DeployState.ps1` covers templates, not host |
|
| Setup-Host post-conditions documented | Partial | `Setup-Host.ps1` does the work but `Validate-DeployState.ps1` covers templates, not host |
|
||||||
|
|
||||||
Overall completion against the original scope: **~85%**. The remaining 15% is concentrated in test coverage and concurrency validation — exactly the parts that justify the "production-ready" label.
|
Overall completion against the original scope: **~85%**. The remaining 15% is concentrated in test coverage and concurrency validation — exactly the parts that justify the "production-ready" label.
|
||||||
|
|
||||||
@@ -284,18 +284,18 @@ Currently `[string] $GuestPassword = ''`, which triggers a prompt — fine. But
|
|||||||
|
|
||||||
### 5.7 OWASP Top 10 Coverage (in scope)
|
### 5.7 OWASP Top 10 Coverage (in scope)
|
||||||
|
|
||||||
| Risk | Status |
|
| Risk | Status |
|
||||||
| --- | --- |
|
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| A01 Broken Access Control | Local host only. Acceptable. |
|
| A01 Broken Access Control | Local host only. Acceptable. |
|
||||||
| A02 Cryptographic Failures | Self-signed TLS for lab use. Acceptable. PAT base64 in command line is the only real concern (§5.2). |
|
| A02 Cryptographic Failures | Self-signed TLS for lab use. Acceptable. PAT base64 in command line is the only real concern (§5.2). |
|
||||||
| A03 Injection | `BuildCommand` is by-design caller-controlled. JSON env injection parses safely via `ConvertFrom-Json`. SSH commands built from string concatenation in `Invoke-RemoteBuild.ps1` Linux branch — `$GuestLinuxWorkDir`, `$CloneBranch`, etc. are not user-supplied in the trigger path but a workflow author could pass `'$(rm -rf /)'` in `submodules` etc. The `single-quote escape` on `ExtraGuestEnv` values is correct; other interpolated strings are not escaped. **MEDIUM** — see §6.7. |
|
| A03 Injection | `BuildCommand` is by-design caller-controlled. JSON env injection parses safely via `ConvertFrom-Json`. SSH commands built from string concatenation in `Invoke-RemoteBuild.ps1` Linux branch — `$GuestLinuxWorkDir`, `$CloneBranch`, etc. are not user-supplied in the trigger path but a workflow author could pass `'$(rm -rf /)'` in `submodules` etc. The `single-quote escape` on `ExtraGuestEnv` values is correct; other interpolated strings are not escaped. **MEDIUM** — see §6.7. |
|
||||||
| A04 Insecure Design | Acceptable for homelab. |
|
| A04 Insecure Design | Acceptable for homelab. |
|
||||||
| A05 Security Misconfiguration | Defender/Firewall/UAC off, documented in BEST-PRACTICES. Acceptable for isolated lab. |
|
| A05 Security Misconfiguration | Defender/Firewall/UAC off, documented in BEST-PRACTICES. Acceptable for isolated lab. |
|
||||||
| A06 Vulnerable Components | `TODO.md §1.3 SHA256 pinning` was deferred. Toolchain installer downloads (Tier-1/Tier-2) use only placeholders. **MEDIUM** — see §6.8. |
|
| A06 Vulnerable Components | `TODO.md §1.3 SHA256 pinning` was deferred. Toolchain installer downloads (Tier-1/Tier-2) use only placeholders. **MEDIUM** — see §6.8. |
|
||||||
| A07 Auth Failures | Shared `BuildVMGuest` account — see §5.4. |
|
| A07 Auth Failures | Shared `BuildVMGuest` account — see §5.4. |
|
||||||
| A08 Software/Data Integrity | No artifact signing. **NICE-TO-HAVE** for a homelab. |
|
| A08 Software/Data Integrity | No artifact signing. **NICE-TO-HAVE** for a homelab. |
|
||||||
| A09 Logging Failures | Strong (`invoke-ci.jsonl`, Event Log, webhook). Good. |
|
| A09 Logging Failures | Strong (`invoke-ci.jsonl`, Event Log, webhook). Good. |
|
||||||
| A10 SSRF | Not applicable. |
|
| A10 SSRF | Not applicable. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -370,21 +370,21 @@ If a workflow author somehow gets `$GuestLinuxWorkDir` to contain `' && rm -rf /
|
|||||||
|
|
||||||
## 7. Operational Gaps
|
## 7. Operational Gaps
|
||||||
|
|
||||||
| Gap | Severity | Notes |
|
| Gap | Severity | Notes |
|
||||||
| --- | --- | --- |
|
| --------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| No documented template-refresh runbook | HIGH | `Backup-CITemplate.ps1` exists, but the procedure (Win KMS reactivation, snapshot rebuild, validation) is not codified. |
|
| No documented template-refresh runbook | HIGH | `Backup-CITemplate.ps1` exists, but the procedure (Win KMS reactivation, snapshot rebuild, validation) is not codified. |
|
||||||
| No automated end-to-end smoke test | HIGH | The "production-ready" claim rests on `e2e-008`/`e2e-009` manual runs. |
|
| No automated end-to-end smoke test | HIGH | The "production-ready" claim rests on `e2e-008`/`e2e-009` manual runs. |
|
||||||
| `capacity: 4` never validated | HIGH | See §6.1. |
|
| `capacity: 4` never validated | HIGH | See §6.1. |
|
||||||
| No CI for the CI | HIGH | PSScriptAnalyzer lint workflow exists; no Pester run on commit; no integration test on commit. |
|
| No CI for the CI | HIGH | PSScriptAnalyzer lint workflow exists; no Pester run on commit; no integration test on commit. |
|
||||||
| No alerting on stuck jobs | MEDIUM | A job that hangs at 1 h 50 min (just under the 2 h runner timeout) is invisible. Watchdog only checks the runner service, not job duration. |
|
| No alerting on stuck jobs | MEDIUM | A job that hangs at 1 h 50 min (just under the 2 h runner timeout) is invisible. Watchdog only checks the runner service, not job duration. |
|
||||||
| No central log aggregation | MEDIUM | JSONL files are per-job. Cross-job analysis requires manual grep. A `Get-CIJobStats.ps1` summarizer would help. |
|
| No central log aggregation | MEDIUM | JSONL files are per-job. Cross-job analysis requires manual grep. A `Get-CIJobStats.ps1` summarizer would help. |
|
||||||
| No quota/limit on PR builds | MEDIUM | A misbehaving workflow could fork the orchestrator. Concurrency lock prevents IP collisions but not disk fill. `MaxAgeHours 4` provides eventual cleanup. |
|
| No quota/limit on PR builds | MEDIUM | A misbehaving workflow could fork the orchestrator. Concurrency lock prevents IP collisions but not disk fill. `MaxAgeHours 4` provides eventual cleanup. |
|
||||||
| No multi-host fan-out | NICE-TO-HAVE | `§6.3` deferred. Single point of failure is the workstation. Acceptable for homelab. |
|
| No multi-host fan-out | NICE-TO-HAVE | `§6.3` deferred. Single point of failure is the workstation. Acceptable for homelab. |
|
||||||
| No remote-access procedure for debugging a stuck VM | LOW | `Cleanup-OrphanedBuildVMs.ps1` will eventually destroy a stuck VM. Manual inspection between job and cleanup requires knowing the clone path. |
|
| No remote-access procedure for debugging a stuck VM | LOW | `Cleanup-OrphanedBuildVMs.ps1` will eventually destroy a stuck VM. Manual inspection between job and cleanup requires knowing the clone path. |
|
||||||
| No host hardware monitoring | LOW | CPU/RAM/disk-IO not measured. `Measure-CIBenchmark.ps1` is phase-time only. |
|
| No host hardware monitoring | LOW | CPU/RAM/disk-IO not measured. `Measure-CIBenchmark.ps1` is phase-time only. |
|
||||||
| `BaseClean` snapshot age not tracked | LOW | Windows KMS lease is 180 days. After that, builds will silently degrade (activation issues affecting `dotnet`). |
|
| `BaseClean` snapshot age not tracked | LOW | Windows KMS lease is 180 days. After that, builds will silently degrade (activation issues affecting `dotnet`). |
|
||||||
| `runner/Install-Runner.ps1` deprecated but present | LOW | Delete it. |
|
| `runner/Install-Runner.ps1` deprecated but present | LOW | Delete it. |
|
||||||
| `Setup-Host.ps1` password documentation mismatch | LOW | See §4.5. |
|
| `Setup-Host.ps1` password documentation mismatch | LOW | See §4.5. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -436,15 +436,15 @@ Four Pester v5 files exist in `tests/`:
|
|||||||
|
|
||||||
Per `TODO.md §5.1`, they all use a fake `vmrun.cmd` driven by `$env:FAKE_VMRUN_EXIT`. What this means in practice:
|
Per `TODO.md §5.1`, they all use a fake `vmrun.cmd` driven by `$env:FAKE_VMRUN_EXIT`. What this means in practice:
|
||||||
|
|
||||||
| Tested | Not Tested |
|
| Tested | Not Tested |
|
||||||
| --- | --- |
|
| ------------------------------------------------------ | ------------------------------------------------------------------------- |
|
||||||
| Argument construction for `vmrun clone` | Whether `vmrun clone` actually clones |
|
| Argument construction for `vmrun clone` | Whether `vmrun clone` actually clones |
|
||||||
| `Invoke-Vmrun` return shape | Whether `Invoke-Vmrun` works with real `vmrun.exe` |
|
| `Invoke-Vmrun` return shape | Whether `Invoke-Vmrun` works with real `vmrun.exe` |
|
||||||
| Parameter validation regexes | Whether `Test-NetConnection -Port 5986` works |
|
| Parameter validation regexes | Whether `Test-NetConnection -Port 5986` works |
|
||||||
| Path resolution helpers | Whether `Start-Sleep` polling deadlines fire correctly |
|
| Path resolution helpers | Whether `Start-Sleep` polling deadlines fire correctly |
|
||||||
| Throw-on-error paths via fake exit codes | The actual failure modes (`vmware-vmx.exe` file lock, DHCP timeout, etc.) |
|
| Throw-on-error paths via fake exit codes | The actual failure modes (`vmware-vmx.exe` file lock, DHCP timeout, etc.) |
|
||||||
| WinRM session options object shape | Whether WinRM actually accepts self-signed cert |
|
| WinRM session options object shape | Whether WinRM actually accepts self-signed cert |
|
||||||
| Phase 1 readiness loop (with fake `vmrun list` output) | Whether real VM boot timing fits the deadline |
|
| Phase 1 readiness loop (with fake `vmrun list` output) | Whether real VM boot timing fits the deadline |
|
||||||
|
|
||||||
This is meaningful coverage — the Pester suite catches regressions in argument shape, parameter validation, return types, and exit-code interpretation. It is NOT integration coverage. Calling this "production-ready" testing is overstating it.
|
This is meaningful coverage — the Pester suite catches regressions in argument shape, parameter validation, return types, and exit-code interpretation. It is NOT integration coverage. Calling this "production-ready" testing is overstating it.
|
||||||
|
|
||||||
@@ -464,18 +464,18 @@ Estimated test coverage (lines exercised by Pester / lines of production code):
|
|||||||
|
|
||||||
This is the area I am most positive about. The system genuinely has better observability than most paid CI systems give you:
|
This is the area I am most positive about. The system genuinely has better observability than most paid CI systems give you:
|
||||||
|
|
||||||
| Channel | Purpose | Quality |
|
| Channel | Purpose | Quality |
|
||||||
| --- | --- | --- |
|
| ------------------------------------------------------------- | ------------------------------- | ------- |
|
||||||
| `F:\CI\Logs\$JobId\invoke-ci.log` | Per-job transcript | High |
|
| `F:\CI\Logs\$JobId\invoke-ci.log` | Per-job transcript | High |
|
||||||
| `F:\CI\Logs\$JobId\invoke-ci.jsonl` | Per-job structured phase events | High |
|
| `F:\CI\Logs\$JobId\invoke-ci.jsonl` | Per-job structured phase events | High |
|
||||||
| `F:\CI\Logs\benchmark.jsonl` | Cross-job benchmark trend | High |
|
| `F:\CI\Logs\benchmark.jsonl` | Cross-job benchmark trend | High |
|
||||||
| Windows Event Log `CI-DiskAlert` (EventId 1001) | Disk alert | Medium |
|
| Windows Event Log `CI-DiskAlert` (EventId 1001) | Disk alert | Medium |
|
||||||
| Windows Event Log `CI-RunnerHealth` (EventIds 1002/1003/1004) | Runner state changes | High |
|
| Windows Event Log `CI-RunnerHealth` (EventIds 1002/1003/1004) | Runner state changes | High |
|
||||||
| Webhook (Discord/Gitea-compatible) | Real-time notification | High |
|
| Webhook (Discord/Gitea-compatible) | Real-time notification | High |
|
||||||
| `F:\CI\State\runner-restart-log.json` | Rolling 1-hour restart cooldown | High |
|
| `F:\CI\State\runner-restart-log.json` | Rolling 1-hour restart cooldown | High |
|
||||||
| `F:\CI\State\ip-leases\<ip>.lease` | Active IP allocations | Medium |
|
| `F:\CI\State\ip-leases\<ip>.lease` | Active IP allocations | Medium |
|
||||||
| Task Scheduler history | Scheduled-task health | Medium |
|
| Task Scheduler history | Scheduled-task health | Medium |
|
||||||
| PSScriptAnalyzer lint workflow output | Code health | Medium |
|
| PSScriptAnalyzer lint workflow output | Code health | Medium |
|
||||||
|
|
||||||
What is missing:
|
What is missing:
|
||||||
|
|
||||||
@@ -737,17 +737,17 @@ What stops me from agreeing with the `README.md` claim of "production-ready":
|
|||||||
|
|
||||||
Honest grade:
|
Honest grade:
|
||||||
|
|
||||||
| Dimension | Grade |
|
| Dimension | Grade |
|
||||||
| --- | --- |
|
| ---------------------- | ------------------------------------ |
|
||||||
| Architecture | A- |
|
| Architecture | A- |
|
||||||
| Code Quality | B+ |
|
| Code Quality | B+ |
|
||||||
| Security (in scope) | B |
|
| Security (in scope) | B |
|
||||||
| Reliability (in scope) | B- (would be A- with §6.1 validated) |
|
| Reliability (in scope) | B- (would be A- with §6.1 validated) |
|
||||||
| Test Coverage | C |
|
| Test Coverage | C |
|
||||||
| Observability | A- |
|
| Observability | A- |
|
||||||
| Documentation | B+ |
|
| Documentation | B+ |
|
||||||
| Operational Readiness | B- |
|
| Operational Readiness | B- |
|
||||||
| Overall | **B+** |
|
| Overall | **B+** |
|
||||||
|
|
||||||
**Production-ready for the homelab use case it was built for**, with the caveats above. **Not production-ready by any commercial standard**, but it was never built to be, and that is fine.
|
**Production-ready for the homelab use case it was built for**, with the caveats above. **Not production-ready by any commercial standard**, but it was never built to be, and that is fine.
|
||||||
|
|
||||||
|
|||||||
@@ -241,26 +241,26 @@ The other GPT-5.5 recommendations respect PS 5.1, VMware Workstation single-host
|
|||||||
|
|
||||||
## 7. Priority Validation
|
## 7. Priority Validation
|
||||||
|
|
||||||
| GPT-5.5 Severity | Item | My Verdict | Rationale |
|
| GPT-5.5 Severity | Item | My Verdict | Rationale |
|
||||||
| --- | --- | --- | --- |
|
| ---------------- | ------------------------------------ | --------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||||
| CRITICAL | Composite action outputs structure | Should be HIGH | Step-level outputs work today; only caller-facing action interface is broken. Latent, not active. |
|
| CRITICAL | Composite action outputs structure | Should be HIGH | Step-level outputs work today; only caller-facing action interface is broken. Latent, not active. |
|
||||||
| CRITICAL | Linux extra guest env secret logging | CRITICAL (concur) | Active leak path. |
|
| CRITICAL | Linux extra guest env secret logging | CRITICAL (concur) | Active leak path. |
|
||||||
| CRITICAL | Linux Mode 2 PAT in SSH command | HIGH-CRITICAL boundary | PAT visibility limited to host argv + guest /proc. Real but bounded. I would put HIGH; CRITICAL is defensible. |
|
| CRITICAL | Linux Mode 2 PAT in SSH command | HIGH-CRITICAL boundary | PAT visibility limited to host argv + guest /proc. Real but bounded. I would put HIGH; CRITICAL is defensible. |
|
||||||
| HIGH | vmrun unbounded calls | HIGH (concur) | |
|
| HIGH | vmrun unbounded calls | HIGH (concur) | |
|
||||||
| HIGH | Stale vm-start.lock | HIGH (concur) | |
|
| HIGH | Stale vm-start.lock | HIGH (concur) | |
|
||||||
| HIGH | Setup-Host stale dirs | HIGH (concur) | |
|
| HIGH | Setup-Host stale dirs | HIGH (concur) | |
|
||||||
| HIGH | Backup default path | HIGH (concur) | |
|
| HIGH | Backup default path | HIGH (concur) | |
|
||||||
| HIGH | Failure-path diagnostics | Should be MEDIUM | Quality-of-life, not operational-trust. |
|
| HIGH | Failure-path diagnostics | Should be MEDIUM | Quality-of-life, not operational-trust. |
|
||||||
| HIGH | Test plan PS7 / wrong params | Should be MEDIUM | Documentation-only. |
|
| HIGH | Test plan PS7 / wrong params | Should be MEDIUM | Documentation-only. |
|
||||||
| HIGH | Shared cache not wired | Should be MEDIUM | Documented feature missing, performance impact only. |
|
| HIGH | Shared cache not wired | Should be MEDIUM | Documented feature missing, performance impact only. |
|
||||||
| MEDIUM | JobId not sanitized | Should be LOW | Local-only attack surface in single-tenant homelab. |
|
| MEDIUM | JobId not sanitized | Should be LOW | Local-only attack surface in single-tenant homelab. |
|
||||||
| MEDIUM | Wait-VMReady TCP-only check | MEDIUM (concur) | |
|
| MEDIUM | Wait-VMReady TCP-only check | MEDIUM (concur) | |
|
||||||
| MEDIUM | CI-FLOW doc claims partial artifacts | Should be LOW | Pure docs. |
|
| MEDIUM | CI-FLOW doc claims partial artifacts | Should be LOW | Pure docs. |
|
||||||
| MEDIUM | Validate-SetupState PasswordExpires | MEDIUM (concur) | Validation failure mode. |
|
| MEDIUM | Validate-SetupState PasswordExpires | MEDIUM (concur) | Validation failure mode. |
|
||||||
| MEDIUM | Ubuntu VMDK no hash | MEDIUM (concur) | |
|
| MEDIUM | Ubuntu VMDK no hash | MEDIUM (concur) | |
|
||||||
| MEDIUM | Installer hash placeholders | MEDIUM (concur for homelab) | |
|
| MEDIUM | Installer hash placeholders | MEDIUM (concur for homelab) | |
|
||||||
| MEDIUM | Event Log / task name drift | Should be LOW | Tests fail not scripts. |
|
| MEDIUM | Event Log / task name drift | Should be LOW | Tests fail not scripts. |
|
||||||
| MEDIUM | _Transport.psm1 host-key handling | MEDIUM (concur) | |
|
| MEDIUM | _Transport.psm1 host-key handling | MEDIUM (concur) | |
|
||||||
|
|
||||||
Items I would add at HIGH that GPT-5.5 missed: `act_runner` SYSTEM-vs-user SSH alias mismatch (verifiable, runtime-reachable), `ci-report-ip.service` missing from `Validate-DeployState.ps1` (silent 120 s timeout), `capacity: 4` burn-in not run (concurrency claim unmeasured).
|
Items I would add at HIGH that GPT-5.5 missed: `act_runner` SYSTEM-vs-user SSH alias mismatch (verifiable, runtime-reachable), `ci-report-ip.service` missing from `Validate-DeployState.ps1` (silent 120 s timeout), `capacity: 4` burn-in not run (concurrency claim unmeasured).
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user