Files
local-ci-cd-system/TODO.md
T
Simone 41212bd439 docs: restore verbose TODO format, absorb FIX-TODO open items
Restore full reference-style TODO (setup phases, commands, e2e log).
Add new entries from FIX-TODO that were dropped in the compact merge:
- Scripts Verification: Cleanup-OrphanedBuildVMs + Remove-BuildVM fix
- Performance & Maintenance: scheduled task for Cleanup
- New "Open Bug Fixes" section: IP octet validation, SHA256 installer
- Reference Paths: add Log dir row
- Gitea Workflow: mark lint.yml done

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 01:02:26 +02:00

269 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TODO — Local CI/CD System
<!-- Last updated: 2026-05-09 — v1.0 taggato, fix post-review applicati -->
## Setup & Infrastructure
- [x] **Gitea Server** — già in esecuzione su `http://10.10.20.11:3100` (e `https://gitea.emulab.it`)
- [x] Runner registration token ottenuto e usato
- [x] Create at least one test repository with `.gitea/workflows/build.yml`
(`Simone/nsis-plugin-nsinnounp` — testato e2e, workflow in `gitea/workflows/build-nsis.yml`)
- [x] Gitea Actions abilitato (runner registrato con successo)
- [x] **act_runner** — installato e registrato sull'host Windows
- [x] Binario `gitea-runner v1.0.2` scaricato in `F:\CI\act_runner\act_runner.exe`
- [x] Registrato con Gitea (`http://10.10.20.11:3100`) — runner ID 1, nome `local-windows-runner`
- [x] `config.yaml` copiato in `F:\CI\act_runner\config.yaml` con label `windows-build:host`
- [x] Installato come servizio Windows via NSSM — stato: **Running**, StartType: Automatic
- [x] Verificare che il runner appaia "Online" nell'UI Gitea Admin → Actions → Runners
- [x] Confermare riavvio automatico dopo reboot host
- [x] **Directory CI** create su `F:\CI\`
- [x] `F:\CI\BuildVMs\`
- [x] `F:\CI\Artifacts\`
- [x] `F:\CI\act_runner\`
- [x] `F:\CI\Cache\NuGet\`
- [x] `F:\CI\RunnerWork\`
- [x] `F:\CI\Templates\WinBuild\`
- [x] `F:\CI\Logs\` — log per job (retention: 30 giorni)
- [x] `F:\CI\ISO\` — contiene `26100.1742.240906-0331.ge_release_svc_refresh_SERVER_VOL_x64FRE_en-us.iso` (Windows Server 2025)
- [x] **CredentialManager** PowerShell module v2.0 installato (Scope: CurrentUser)
- [x] **Rete VM**: VMnet8 (NAT) — internet access per pip/nuget/npm durante i build
## Template VM
- [x] **Provision template VM** in VMware Workstation — segui questi passi nell'ordine esatto:
### Fase A — Crea e installa la VM (NIC: NAT per internet)
- [x] Crea nuova VM in VMware Workstation con queste impostazioni:
- 4 vCPU, 6144 MB RAM, disco 80 GB thin
- VMX path: `F:\CI\Templates\WinBuild\WinBuild.vmx`
- **NIC: VMnet8 (NAT)** ← internet necessario per Windows Update e installer
- CD-ROM: `F:\CI\ISO\26100.1742.240906-0331.ge_release_svc_refresh_SERVER_VOL_x64FRE_en-us.iso`
- [x] Installa Windows Server 2025 dall'ISO
- [x] All'interno della VM (come Administrator), abilita WinRM:
```cmd
winrm quickconfig -q
```
```powershell
Enable-PSRemoting -Force -SkipNetworkProfileCheck
Set-Item WSMan:\localhost\Service\Auth\Basic $true -Force
Set-Item WSMan:\localhost\Service\AllowUnencrypted $true -Force
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*' -Force
```
- [x] **Attiva Windows Server 2025** (prima dello snapshot — i linked clone ereditano l'attivazione):
```cmd
slmgr /dli
```
Se non attivato, scegli il metodo appropriato:
- **KMS** (server KMS in rete): `slmgr /skms <IP_KMS>` poi `slmgr /ato`
- **MAK/Retail key**: `slmgr /ipk XXXXX-XXXXX-XXXXX-XXXXX-XXXXX` poi `slmgr /ato`
- **KMS pubblico** (alternativa lab): vedi https://github.com/robin113x/Windows-Server-Activation/
Verifica: `slmgr /xpr` — deve mostrare attivazione permanente o scadenza lontana
- [x] Nota l'IP assegnato dal DHCP di VMnet8 (es. `192.168.79.x`) — `ipconfig` nella VM
### Fase B — Provisioning automatico dall'host
- [x] Dall'host, esegui:
```powershell
cd n:\Code\Workspace\Local-CI-CD-System\template
.\Prepare-TemplateSetup.ps1 -VMIPAddress 192.168.79.128 -SkipWindowsUpdate
```
Installa: WinRM config, utente `ci_build`, .NET SDK 10.0, VS Build Tools 2026, Python 3.13.3.
- [x] Setup completato con successo (VS Build Tools 2026 exit code 0).
### Fase C — Spegni e prendi lo snapshot
- [x] VM rimane su **VMnet8 (NAT)** — internet access permanente per build che richiedono pip/nuget/npm
- [x] Spegni la VM: Start → Shut down
- [x] Prendi snapshot: VM → Snapshot → Take Snapshot
**Nome esatto: `BaseClean`**
- [x] Lascia la VM spenta — non modificarla mai più dopo questo snapshot
### Fase D — Credenziali e config
- [x] Archivia credenziali guest sull'host (PowerShell elevato con CredentialManager):
```powershell
New-StoredCredential -Target "BuildVMGuest" -UserName "ci_build" `
-Password "<your-build-password>" -Persist LocalMachine
```
- [x] Verifica `GITEA_CI_TEMPLATE_PATH` in `F:\CI\act_runner\config.yaml` — aggiornato a `CI-WinBuild.vmx` (2026-05-08)
## Scripts Verification
- [x] Test `New-BuildVM.ps1` standalone — clone `Clone_test-002` creato correttamente (2026-05-08)
- [x] Test `Wait-VMReady.ps1` standalone — exit 0 in ~5s, VM pronta (2026-05-08)
- [x] Test `Invoke-RemoteBuild.ps1` — dotnet restore + build OK, artifacts.zip creato in VM (2026-05-08)
- [x] Test `Get-BuildArtifacts.ps1` — artifacts.zip (78 KB) copiato in F:\CI\Artifacts\test-003\ (2026-05-08)
- [x] Test `Remove-BuildVM.ps1` — VM spenta + directory rimossa correttamente (2026-05-08)
- [x] Test `Invoke-CIJob.ps1` end-to-end su una soluzione reale (nsis-plugin-nsinnounp)
- [x] e2e-008: SUCCESS — build OK + artifact raccolto (1632 KB)
- [x] e2e-009: SUCCESS — cleanup automatico VM + clone confermato (finally block)
- [x] `scripts/Cleanup-OrphanedBuildVMs.ps1` creato e verificato — `-WhatIf`, soglia `-MaxAgeHours`, hard stop + deleteVM + rimozione dir (2026-05-09)
- [x] `scripts/Remove-BuildVM.ps1` fix `vmrun deleteVM` exit -1 — poll `vmrun list` + retry 3× backoff 0/3/6s (2026-05-09)
## Runner Configuration
- [x] `runner/config.yaml` aggiornato con percorsi `F:\CI\`, rete VMnet8 (NAT), label corretti
- [x] `capacity: 4` configurato (64 GB RAM / ~8 GB per VM)
- [x] Aggiornare `GITEA_CI_TEMPLATE_PATH` in `config.yaml` dopo creazione template VM
- [x] Archiviare credenziali guest in Windows Credential Manager (target: `BuildVMGuest`)
## Gitea Workflow Integration
- [x] Copiare `gitea/workflow-example.yml` in `.gitea/workflows/build.yml` nel repo di test
(workflow `build-nsis.yml` già presente e funzionante per `nsis-plugin-nsinnounp`)
- [x] Push commit e verificare job in Gitea Actions UI
- [x] Verificare artifact scaricabile da Gitea dopo build riuscita
- [x] `gitea/workflows/lint.yml` creato — PSScriptAnalyzer su push/PR che toccano `.ps1` (2026-05-09)
- [ ] Adattare workflow per altri repository (generalizzare `BUILD_COMMAND` e `ARTIFACT_SOURCE`)
## Performance & Maintenance
- [ ] Benchmark: tempo creazione clone + tempo WinRM readiness
- [ ] Configurare NuGet package cache su shared folder host (vedi OPTIMIZATION.md)
- [ ] Pianificare refresh semestrale snapshot template VM (KMS lease = 180 giorni):
Boot template su VMnet8 (NAT) → `slmgr /ato` → nuovo snapshot BaseClean
- [ ] Monitoraggio Windows Event Log per fallimenti servizio act_runner
- [ ] Configurare retention artifact (pulizia `F:\CI\Artifacts` più vecchi di N giorni)
- [ ] **Scheduled task per `Cleanup-OrphanedBuildVMs.ps1`**
Creare via Task Scheduler o estendere `Setup-Host.ps1`. Suggerito: ogni 6 ore, `-MaxAgeHours 4`.
## Open Bug Fixes
- [ ] **Validazione IP ottetti**`scripts/Invoke-CIJob.ps1`
`ValidatePattern` attuale accetta `999.x.x.x`. Sostituire con validazione per-ottetto 0-255.
- [ ] **Verifica SHA256 installer**`template/Setup-TemplateVM.ps1`
Python, VS BuildTools, `dotnet-install.ps1` scaricati senza verifica hash. Aggiungere
`-ExpectedHash` o hash hardcoded per le versioni pinnate.
## In-VM Git Clone (Ottimizzazione)
Sfruttare l'accesso internet della VM (VMnet8 NAT) per fare il `git clone` direttamente
nella VM, eliminando il ciclo host-clone → zip → WinRM-transfer → unzip.
### Strategia
**Flusso attuale:**
```
host: git clone → host: Compress-Archive → WinRM: copia zip → VM: Expand-Archive → VM: build
```
**Flusso proposto:**
```
VM avviata → WinRM: git clone --recurse-submodules https://<token>@gitea/... → VM: build
```
**Punti chiave:**
- Il PAT **non deve essere nello snapshot** — viene iniettato a runtime come env var via WinRM
(`git clone https://Simone:<pat>@gitea.emulab.it/<repo>.git`) e non viene mai persistito
- Git deve essere installato nel template (`Setup-TemplateVM.ps1`) — ora è assente per design
- L'implementazione deve essere **non-breaking**: nuovo switch opt-in `-UseGitClone` in `Invoke-CIJob.ps1`
- Si perde il parallelismo parziale (clone host avviene mentre VM boota), ma si elimina
tutto l'overhead di zip/transfer (rilevante su repo grandi o con molti submoduli)
- Submoduli funzionano nativamente con `--recurse-submodules` (nessun workaround)
### Task
- [ ] **Setup-TemplateVM.ps1 — installare Git for Windows**
- [ ] Scaricare e installare Git for Windows (installer silenzioso da git-scm.com)
```powershell
$gitUrl = 'https://github.com/git-for-windows/git/releases/download/v2.47.1.windows.1/Git-2.47.1-64-bit.exe'
Start-Process $gitUrl '/VERYSILENT /NORESTART /COMPONENTS=gitlfs' -Wait
```
- [ ] Aggiungere `C:\Program Files\Git\cmd` al PATH di sistema nella VM
- [ ] Verificare: `git --version` ritorna exit 0 nella VM
- [ ] Rimuovere il commento "Git is NOT installed" dal docblock di Setup-TemplateVM.ps1
- [ ] **Setup-TemplateVM.ps1 — altri tool utili**
- [ ] **7-Zip**: installer silenzioso — molto più veloce di `Compress-Archive`/`Expand-Archive`
per archivi grandi (es. npm/NuGet cache warm)
- [ ] **curl.exe**: già presente in Windows 11/Server 2025 (v7.x) — verificare disponibilità
- [ ] Valutare: `jq` (parsing JSON in script PowerShell o bash) — opzionale
- [ ] **Invoke-CIJob.ps1 — aggiungere switch `-UseGitClone`**
- [ ] Quando `-UseGitClone` è attivo:
- Saltare Phase 1 (host git clone) e la creazione del `HostSourceDir` temporaneo
- Dopo Wait-VMReady, leggere PAT da Windows Credential Manager sull'host
(es. target `git:https://gitea.emulab.it/...` o un target dedicato CI)
- Passare PAT come parametro a `Invoke-RemoteBuild.ps1` (mai loggato/stampato)
- [ ] Comportamento default invariato (`-UseGitClone` = `$false`) — nessuna regressione
- [ ] **Invoke-RemoteBuild.ps1 — modalità in-VM clone**
- [ ] Aggiungere parametri: `-CloneUrl`, `-CloneBranch`, `-CloneCommit`, `-GitPat`
(tutti opzionali, usati solo quando `-UseGitClone` è attivo)
- [ ] Quando presenti: anziché copiare zip, eseguire nella VM:
```powershell
git clone --recurse-submodules `
"https://Simone:$env:CI_GIT_PAT@gitea.emulab.it/Simone/<repo>.git" `
C:\CI\build
git -C C:\CI\build checkout $CloneCommit # pin al commit esatto
```
- [ ] Iniettare PAT come variabile d'ambiente della sessione WinRM (non argv, non log)
- [ ] Pulire la variabile d'ambiente dopo il clone: `[System.Environment]::SetEnvironmentVariable('CI_GIT_PAT', $null, 'Process')`
- [ ] **Test e2e con `-UseGitClone`**
- [ ] Aggiornare snapshot `BaseClean` con Git installato
- [ ] Eseguire `e2e-010` con `-UseGitClone` su `nsis-plugin-nsinnounp` (ha submoduli)
- [ ] Confrontare tempo totale con e2e-009 (senza `-UseGitClone`)
- [ ] Verificare che il PAT non appaia nei log di `Invoke-CIJob.ps1`
---
## Linux Build VM (Future)
Aggiungere supporto per build su Linux per testare la compilazione cross-platform
(es. versione Linux del plugin o build check con GCC/Clang).
- [ ] **Template VM Linux** — Provisionare template VM con Ubuntu Server 24.04 LTS
- [ ] Scegliere distro: Ubuntu 24.04 LTS (raccomandato) o Debian 12
- [ ] Installare toolchain: GCC, Clang, CMake, Python 3.x, build-essential
- [ ] Configurare accesso SSH (chiave pubblica da host) in alternativa/integrazione a WinRM
- [ ] Prendere snapshot `BaseClean-Linux`
- [ ] Archiviare credenziali SSH in Credential Manager (o key file su host)
- [ ] **Invoke-CIJob.ps1 — branch Linux**
- [ ] Aggiungere parametro `-GuestOS` (`Windows` / `Linux`) o rilevamento automatico da VMX
- [ ] Sostituire WinRM con SSH + SCP per trasferimento zip e raccolta artifacts
- [ ] Aggiungere supporto a comandi Linux (`bash`, `make`, `cmake --build`)
- [ ] **Workflow Gitea — build matrix**
- [ ] Definire matrix strategy `[windows-build, linux-build]` nel workflow
- [ ] Aggiungere label `linux-build` al runner (o registrare runner separato se necessario)
- [ ] Verificare che artifacts da entrambe le piattaforme vengano raccolti correttamente
- [ ] **Test e2e Linux** — eseguire almeno un build end-to-end su VM Linux
- [ ] Confermare che `build_plugin.py` (o analogo script) funzioni su Linux
- [ ] Confrontare artifact Linux con quelli Windows
---
## Security Hardening (Post-MVP)
- [ ] Passare WinRM da HTTP (5985) a HTTPS (5986) con certificato self-signed
- [ ] Rimuovere `AllowUnencrypted=true` dalla config WinRM dopo migrazione HTTPS
- [ ] Verificare che Get-StoredCredential funzioni correttamente negli script
- [ ] Regole firewall — limitare WinRM alla subnet build VM (192.168.79.0/24 — VMnet8 NAT)
- [ ] Rotazione password guest VM trimestralmente
---
## Reference Paths
| Item | Path / Value |
| ------------------------- | ------------------------------------------------------------ |
| vmrun.exe | `C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe` |
| act_runner | `F:\CI\act_runner\act_runner.exe` (servizio: `act_runner`) |
| act_runner config | `F:\CI\act_runner\config.yaml` |
| act_runner logs | `F:\CI\act_runner\logs\` |
| Template VMX | `F:\CI\Templates\WinBuild\CI-WinBuild.vmx` |
| Snapshot name | `BaseClean` |
| Clone base dir | `F:\CI\BuildVMs\` |
| Artifact dir | `F:\CI\Artifacts\` |
| Log dir | `F:\CI\Logs\` (retention: 30 giorni) |
| Gitea URL (LAN) | `http://10.10.20.11:3100` |
| Gitea URL (ext) | `https://gitea.emulab.it` |
| Runner name | `local-windows-runner` (ID: 1) |
| Build VM subnet | `192.168.79.0/24` (VMnet8 — NAT, internet access per build) |
| Credential Manager target | `BuildVMGuest` |
| Guest username | `ci_build` — configurato e verificato |