chore(plans): archive Phase A and B completed documents

Moves all A/B closeouts, checklists, idea docs, and implementation plans
to plans/archived/2026-05-23/. Both phases are production-stable.

Active plans remaining in plans/:
  - idea-3-powershell-removal.md  (Phase C — in progress)
  - idea-3-esxi-support.md        (Phase D — future)
  - ideas-overview.md             (roadmap reference)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 19:52:09 +02:00
parent 222c41dd16
commit 0d6486b19b
17 changed files with 0 additions and 0 deletions
@@ -0,0 +1,349 @@
# Fase A — Checklist finale per l'utente
La Fase A è **code-complete e pushata** sul branch `feature/python-rewrite-and-linux-migration`.
Restano solo le validazioni che richiedono accesso fisico all'host CI con VMware
Workstation, snapshot template attivi e act_runner registrato.
Questo documento elenca i passi da eseguire in ordine, con checklist e comandi
copiabili. Stop a primo errore: ogni passo è un gate per il successivo.
> **Tempo stimato totale**: 12 ore (escluse build lunghe nel passo 5).
---
## Passo 1 — Aggiornare il venv di produzione sull'host CI
Il codice nuovo va installato nel venv che act_runner usa
(`F:\CI\python\venv\`).
- [x] Aprire PowerShell **come amministratore** sull'host CI.
- [x] Posizionarsi nella copia git aggiornata del repo (pull del branch
`feature/python-rewrite-and-linux-migration`):
```powershell
cd <path-locale-repo>
git fetch origin
git checkout feature/python-rewrite-and-linux-migration
git pull
```
- [x] Installare il package nel venv di produzione (**non editable**):
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m pip install .
```
> ⚠️ **Non usare `pip install -e .` su questo host.** act_runner gira
> come `LocalSystem`. Un install editable scrive un `.pth` verso la
> sorgente; se il `cd` era in una dir di lavoro di act_runner
> (`F:\CI\RunnerWork\<hash>\hostexecutor`, transitoria) o sul drive
> utente `N:` (non risolto da LocalSystem), il runner fallisce con
> `No module named ci_orchestrator`. L'install regolare copia il
> package in `site-packages` su `F:` (accessibile a LocalSystem).
> Conseguenza: ogni modifica al codice richiede di ri-eseguire
> `pip install .` — è uno step di deploy. Assicurarsi che il `cd` del
> passo precedente punti alla copia git reale del repo, non a una dir
> sotto `F:\CI\RunnerWork`.
- [x] Smoke check rapido che la CLI risponda:
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator --help
```
Atteso: lista degli 11 sub-comandi (`wait-ready`, `vm`, `build`,
`artifacts`, `monitor`, `report`, `job`).
---
## Passo 2 — Riavviare act_runner
L'act_runner gira come servizio SYSTEM e legge `runner/config.yaml`
all'avvio. La modifica di A4 (`PYTHONIOENCODING=utf-8`) ha effetto solo
dopo restart.
- [x] Trovare il servizio:
```powershell
Get-Service | Where-Object { $_.Name -like '*act*runner*' }
```
- [x] Restart (sostituisci `<NomeServizio>` con quello trovato):
```powershell
Restart-Service -Name '<NomeServizio>'
```
- [x] Verificare che sia partito:
```powershell
Get-Service -Name '<NomeServizio>'
```
Atteso: `Status = Running`.
---
## Passo 3 — Smoke `wait-ready` su VM Windows reale
PoC pendente da A1.
- [x] Clonare manualmente un template Windows:
```powershell
& 'C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe' `
-T ws clone `
'F:\CI\Templates\WinBuild2025\WinBuild2025.vmx' `
'F:\CI\BuildVMs\smoke-win\smoke-win.vmx' `
linked -snapshot=BaseClean -cloneName=smoke-win
```
- [x] Avviare la VM:
```powershell
& 'C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe' `
-T ws start 'F:\CI\BuildVMs\smoke-win\smoke-win.vmx' nogui
```
- [x] Eseguire `wait-ready`:
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator wait-ready `
--vmx 'F:\CI\BuildVMs\smoke-win\smoke-win.vmx' `
--guest-os windows --timeout 180
```
Atteso: exit code `0` entro 3 minuti.
- [x] Cleanup VM di smoke:
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator vm remove `
--vmx 'F:\CI\BuildVMs\smoke-win\smoke-win.vmx' --force
```
---
## Passo 4 — Smoke `wait-ready` su VM Linux reale
Stesso schema, template Linux. PoC pendente da A1.
- [x] Clonare:
```powershell
& 'C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe' `
-T ws clone `
'F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx' `
'F:\CI\BuildVMs\smoke-linux\smoke-linux.vmx' `
linked -snapshot=BaseClean-Linux -cloneName=smoke-linux
```
- [x] Start + wait-ready:
```powershell
& 'C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe' `
-T ws start 'F:\CI\BuildVMs\smoke-linux\smoke-linux.vmx' nogui
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator wait-ready `
--vmx 'F:\CI\BuildVMs\smoke-linux\smoke-linux.vmx' `
--guest-os linux --timeout 180
```
Atteso: exit code `0`.
> **Prerequisito scoperto**: `F:\CI\config.toml` deve esistere con `ssh_key_path`
> impostato — altrimenti SSH fallisce con `No authentication methods available`.
> Creato durante questa validazione; vedi HOST-SETUP.md step 6.
- [x] Cleanup:
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator vm remove `
--vmx 'F:\CI\BuildVMs\smoke-linux\smoke-linux.vmx' --force
```
---
## Passo 5 — Smoke end-to-end pipeline (`job`)
Valida A3+A4 insieme: clone → wait → build → collect → cleanup.
- [x] Lanciare un job sul template Windows con uno script trivial:
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator job `
--template-path 'F:\CI\Templates\WinBuild2025\WinBuild2025.vmx' `
--snapshot-name BaseClean `
--job-id smoke-job-win `
--repo-url 'http://10.10.20.11:3100/Simone/your-repo.git' `
--branch main `
--build-command 'echo hello > artifact.txt' `
--guest-artifact-source 'artifact.txt' `
--artifact-base-dir 'F:\CI\Artifacts\smoke-job-win'
```
Atteso: exit code `0`, file `F:\CI\Artifacts\smoke-job-win\artifact.txt` presente,
VM smoke-job-win **non** più esistente in `F:\CI\BuildVMs\` (cleanup garantito).
- [x] Ripetere su Linux:
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator job `
--template-path 'F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx' `
--snapshot-name BaseClean-Linux `
--guest-os linux `
--job-id smoke-job-linux `
--repo-url 'http://10.10.20.11:3100/Simone/your-repo.git' `
--branch main `
--build-command 'echo hello > artifact.txt' `
--guest-artifact-source 'artifact.txt' `
--artifact-base-dir 'F:\CI\Artifacts\smoke-job-linux'
```
Atteso: exit code `0`, `F:\CI\Artifacts\smoke-job-linux\smoke-job-linux\artifact.txt` presente.
- [x] Verificare assenza VM orfane:
```powershell
& 'F:\CI\python\venv\Scripts\python.exe' -m ci_orchestrator vm cleanup --what-if
```
Atteso: nessun candidato.
---
## Passo 6 — Workflow Gitea end-to-end
Validazione di A4 lato runner reale.
- [x] Aprire la UI Gitea, repo `local-ci-cd-system`, branch
`feature/python-rewrite-and-linux-migration`.
- [x] Triggerare manualmente i 3 workflow (Actions → Run workflow):
- [x] `lint.yml` → atteso PASS
- [x] `self-test.yml` → PASS — validati **entrambi i transport**
(in-guest clone default + host-side clone+zip) su Win e Linux:
| Job | Transport | Esito |
| ---------------------------- | ----------------------- | ----------- |
| smoke-windows | in-guest git clone | SUCCESS 26s |
| smoke-linux | in-guest git clone | SUCCESS 51s |
| smoke-windows-hostclone | host-side clone + zip | SUCCESS 28s |
| smoke-linux-hostclone | host-side clone + zip | SUCCESS 46s |
Note: artifact github-free (no upload-artifact; file raw su
`F:\CI\Artifacts\<job>`); `use-git-clone`/`submodules` default ON.
- [x] `build-ns7zip.yml` matrix Win+Linux → PASS (target repo
`Simone/nsis-plugin-ns7zip`, in-guest clone, `--dist`):
| Job | Esito |
| ------------------ | --------------------------------------- |
| build (windows) | SUCCESS — DLL in dist/, artifact host |
| build (linux) | SUCCESS — 8 vCPU/8 GB, wall ~121s |
| release (tag push) | SUCCESS — release Gitea + 2 asset upload |
Note: `release` validato con tag throwaway `v0.0.0-phaseA-test`
(poi rimosso); usa il token Actions automatico (Default Token
Permissions = Permissive) + REST API Gitea, legge gli artifact
host-side (no download-artifact). Linux perf: vCPU-starvation a 4
vCPU risolta con guest-cpu=8 (≈ Windows VM ~120s); gap col Windows
nativo MSVC (~30s) è inerente MinGW, fuori scope CI.
> Tutti i workflow PASS — nessun fallimento da triagare. (Procedura
> storica: in caso di fallimento, scaricare i log del run e aprire una
> voce in `TODO.md` con sha + output errore.)
---
## Passo 7 — Burn-in capacità (4 job concorrenti)
Validazione finale di A5 (definizione di "fatto Fase A").
- [x] Burn-in via `scripts/Start-BurnInTest.ps1` (wrapper lab che
hardcoda repo `burnin-dummy` + `BuildCommand` = `build.ps1`;
`Test-CapacityBurnIn.ps1` diretto senza `-BuildCommand` usa il
default dotnet → fallisce su repo non-.NET):
```powershell
.\scripts\Start-BurnInTest.ps1
```
- [x] Esito (4 job concorrenti × 3 round):
| Round | Pass | Fail | Elapsed | Status |
| ----- | ---- | ---- | ------- | ------ |
| 1 | 4 | 0 | 76s | PASS |
| 2 | 4 | 0 | 88s | PASS |
| 3 | 4 | 0 | 73s | PASS |
Total 12/12 PASS — **OVERALL: PASS**. Cleanup VM + lock OK ogni
round (0 orfani). A5 / Passo 7 validato.
---
## Passo 8 — Benchmark wall-clock
Confronto Python vs PowerShell. Pendenza A4.
- [x] Eseguito `.\scripts\Measure-CIBenchmark.ps1` (4 iter):
| Iter | Clone | Start | IP | WinRM | Destroy | Boot tot |
| ---- | ----- | ----- | ----- | ----- | ------- | -------- |
| 1 | 0.63 | 1.75 | 66.57 | 0.01 | 4.81 | 68.96 |
| 2 | 0.63 | 1.89 | 20.21 | 0.01 | 6.39 | 22.74 |
| 3 | 0.62 | 1.72 | 85.07 | 0.01 | 4.50 | 87.42 |
| 4 | 0.61 | 1.72 | 60.97 | 0.01 | 4.20 | 63.31 |
Nessun errore, destroy OK (~4-6s), 0 orfani. Clone/start/WinRM
trascurabili; **fase IP (20-85s) = costo dominante e variabile**
(detect IP guest via VMware Tools / ci-report-ip) — noto, non
bloccante. Prerequisito scoperto: lo shim `Remove-BuildVM.ps1`
inoltrava `-ErrorAction` come `--error-action` (destroy falliva ->
orfana); risolto per tutti gli shim blind-loop (commit
`fix(shims): skip PowerShell common params`).
- [x] Confronto col baseline pre-Python — **SALTATO** (deciso): nessun
baseline PS affidabile registrato; metriche infra appese a
`F:\CI\Logs\benchmark.jsonl` per trend futuri. Non bloccante.
---
## Passo 9 — Merge della Fase A in `main`
Solo dopo che i passi 37 sono tutti `[x]` PASS.
- [x] Self-review pre-merge: diff `main...feature` 108 file
(+12597/-3128), nessun secret/.venv/.env per nome. Solo 5 file
rimossi su feature = cleanup intenzionale (vecchio `gitea/`
action+lint → `.gitea/`; Pester test degli script PS rimpiazzati).
- [x] Merge `feature → main` con `--no-ff` (storia per-fase
preservata; conflitto rename/delete `build-nsInnoUnp.yml` →
`build-ns7zip.yml` risolto a favore di feature). Albero `main`
risultante == `feature` (Phase A esatto). Commit merge `2aa12bb`,
pushato a `origin/main`.
- [x] Tag release `v2.0.0-phaseA` creato (annotato su `b4ca7f3`) e
pushato a `origin`. Il push (`v*`) triggera `build-ns7zip.yml`
matrix + release = validazione finale end-to-end di `main`.
Cleanup: cancellare dalla UI Gitea la release auto-pubblicata
`v2.0.0-phaseA` (contiene binari ns7zip — quirk wiring del job
release), tenendo il **tag** come marker Phase A.
---
## Tracciamento globale
| Passo | Descrizione | Stato |
| ----- | ----------------------------------------- | ----- |
| 1 | Aggiorna venv di produzione | [x] |
| 2 | Restart act_runner | [x] |
| 3 | Smoke `wait-ready` Windows | [x] |
| 4 | Smoke `wait-ready` Linux | [x] |
| 5 | Smoke `job` end-to-end (Win + Linux) | [x] |
| 6 | Workflow Gitea (lint + self-test + build) | [x] |
| 7 | Burn-in 4 job concorrenti × 3 round | [x] |
| 8 | Benchmark wall-clock | [x] |
| 9 | Merge in `main` + tag `v2.0.0-phaseA` | [x] |
**Fase A definitivamente chiusa** (Passi 1-9 tutti `[x]`). Pronta la
Fase B (porting su host Linux). Cleanup residuo non bloccante:
cancellare dalla UI Gitea le release di test `v0.0.0-phaseA-test` e
l'auto-pubblicata `v2.0.0-phaseA` (i **tag** restano).