feat(template): add Deploy-WinBuild2025.ps1 + autounattend; update TODO

template/Deploy-WinBuild2025.ps1:
  New host-side script that drives the unattended Windows install phase:
  creates the VM, injects autounattend.xml (disabling Defender/firewall/UAC
  before Setup-WinBuild2025.ps1 runs), boots from ISO, waits for first-boot.

template/autounattend.template.xml:
  WiM-based answer file template for Windows Server 2025 unattended install.
  Sets DisableAntiSpyware GPO + RTP off so Defender is fully off at first
  logon (prerequisite for Setup-WinBuild2025.ps1 Step-2 validation-only path).

TODO.md:
  - Date + wording updated (2026-05-10)
  - §1.1: file refs updated to post-refactor line numbers (Step 3 WinRM,
    Deploy-WinBuild2025 Enable-PSRemoting, Invoke-RemoteBuild, Get-BuildArtifacts)
  - §1.2: TrustedHosts audit status corrected (Setup-Host.ps1 never sets '*';
    Prepare appends IP and restores in finally)
  - §1.3: Python/dotnet/VS Build Tools line refs updated
  - §1.5: PAT security constraints expanded with grep-on-log safety net rule
  - §1.6: Defender/Firewall/UAC state updated to reflect Deploy vs Setup split
  - §3.3 deploy reference: VMX path corrected to CI-WinBuild.vmx
  - §3.3 doc ref: WINDOWS-TEMPLATE-SETUP updated to list Deploy step
This commit is contained in:
Simone
2026-05-10 01:01:43 +02:00
parent ab636a0ec1
commit 96b65d40de
3 changed files with 1324 additions and 38 deletions
+191 -38
View File
@@ -1,14 +1,13 @@
# TODO — Local CI/CD System
<!-- Last updated: 2026-05-09TODO+CONSIGLI uniti, priorità P0..P3 + rationale per ogni voce aperta -->
<!-- Last updated: 2026-05-10 — line refs e wording allineati al refactor 2026-05-09 -->
> Documento unico di lavoro: roadmap, audit trail dei task completati, e backlog post-v1.0
> con priorità e razionale (assorbito da `CONSIGLI.md`). Le voci aperte sono raggruppate
> per area e marcate **P0..P3**:
> con priorità e razionale. Le voci aperte sono raggruppate per area e marcate **P0..P3**:
>
> **Doc di setup operativi**:
> - [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 (Prepare + Setup-WinBuild2025)
> - [docs/WINDOWS-TEMPLATE-SETUP.md](docs/WINDOWS-TEMPLATE-SETUP.md) — provisioning template Windows (Deploy + Prepare + Setup-WinBuild2025)
> - [docs/LINUX-TEMPLATE-SETUP.md](docs/LINUX-TEMPLATE-SETUP.md) — bozza/TODO template Linux (non implementato)
>
> - **P0** — sicurezza o affidabilità: affrontare prima di estendere il sistema
@@ -55,7 +54,7 @@
### 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`
- VMX path: `F:\CI\Templates\WinBuild\CI-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
@@ -150,7 +149,7 @@
## 1. Sicurezza & hardening
### 1.1 [P0] Migrare WinRM da HTTP/Basic a HTTPS/5986
File: [template/Setup-WinBuild2025.ps1:179-198](template/Setup-WinBuild2025.ps1), [scripts/Invoke-RemoteBuild.ps1:82-91](scripts/Invoke-RemoteBuild.ps1).
File: [template/Setup-WinBuild2025.ps1:204-241](template/Setup-WinBuild2025.ps1) (Step 3 WinRM), [template/Deploy-WinBuild2025.ps1:524-534](template/Deploy-WinBuild2025.ps1) (Enable-PSRemoting + AllowUnencrypted/Basic), [scripts/Invoke-RemoteBuild.ps1:83-91](scripts/Invoke-RemoteBuild.ps1), [scripts/Get-BuildArtifacts.ps1:66-75](scripts/Get-BuildArtifacts.ps1).
**Motivazione**: la combo `AllowUnencrypted=true` + `Auth/Basic=true` invia credenziali del
`ci_build` (admin) in chiaro su VMnet8. Anche in lab isolato, l'host può essere compromesso
@@ -164,16 +163,20 @@ manca solo l'esecuzione.
- [ ] Tenere `-SkipCACheck` lato host: per cert lab self-signed è accettabile, ma documentare la motivazione inline.
- [ ] Regole firewall — limitare WinRM alla subnet build VM (`192.168.79.0/24` — VMnet8 NAT).
### 1.2 [P0] Restringere `TrustedHosts` lato host
File: probabile `Setup-Host.ps1` (e in vari run setup) — pattern `*` è incompatibile con altri carichi sull'host Windows 11.
### 1.2 [P0] Restringere `TrustedHosts` lato host (audit-only — già coperto)
File: nessuno script imposta `*` sull'host. Stato corrente:
- `Setup-Host.ps1` non tocca TrustedHosts (verificato 2026-05-10)
- [template/Prepare-WinBuild2025.ps1:270-294](template/Prepare-WinBuild2025.ps1:270) appende `$VMIPAddress` e ripristina nel `finally` (riga 617)
- [docs/HOST-SETUP.md:121-126](docs/HOST-SETUP.md:121) raccomanda `'192.168.79.*'` in setup manuale
Sostituire con la subnet build:
**Azione residua**: audit eventuali host già configurati con `*` (eredità manuale) e
sostituire con la subnet build:
```powershell
Set-Item WSMan:\localhost\Client\TrustedHosts -Value '192.168.79.*' -Force -Concatenate
```
### 1.3 [P0] Pinning hash SHA256 degli installer
File: [template/Setup-WinBuild2025.ps1:332-399](template/Setup-WinBuild2025.ps1), [template/Setup-WinBuild2025.ps1:401-502](template/Setup-WinBuild2025.ps1).
File: [template/Setup-WinBuild2025.ps1:707-755](template/Setup-WinBuild2025.ps1) (Step 8 Python), [template/Setup-WinBuild2025.ps1:757-885](template/Setup-WinBuild2025.ps1) (Step 9 VS Build Tools), [template/Setup-WinBuild2025.ps1:660-705](template/Setup-WinBuild2025.ps1) (Step 7 dotnet-install.ps1).
**Motivazione**: Python, `dotnet-install.ps1`, `vs_buildtools.exe` vengono scaricati senza
verifica integrità. Un MITM nella rete dell'host (anche temporaneo) può iniettare binari
@@ -200,16 +203,24 @@ $ipv4 = '^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?
Estrarre la costante in un modulo condiviso `scripts/_Common.psm1` per evitare drift fra i 4 file (vedi §5.2).
### 1.5 [P1] PAT mai persistito quando si abilita `-UseGitClone`
Quando arriva il momento di implementare il clone in-VM (vedi §3.3 / sezione "In-VM Git Clone"):
- [ ] Recuperare il PAT da Credential Manager dell'host **subito prima** della WinRM session, mai prima.
- [ ] Iniettare via `$using:cred` in `Invoke-Command` e cancellare la variabile in un `finally` interno alla scriptblock.
- [ ] Aggiungere un grep automatico nei log job: se il PAT compare grezzo, fallire la build.
Requisiti di sicurezza per l'implementazione del clone in-VM. La sequenza operativa
(quando, dove, come) è dettagliata nella sezione "In-VM Git Clone (Ottimizzazione) — riferimento §3.3".
Vincoli da rispettare in qualsiasi implementazione di `-UseGitClone`:
- [ ] PAT recuperato da Credential Manager **subito prima** della WinRM session, mai prima.
- [ ] Iniettato via `$using:cred` o env var di sessione, mai in argv né in log/transcript.
- [ ] Cancellato in `finally` interno alla scriptblock guest.
- [ ] **Grep automatico post-job sui log**: se il PAT compare grezzo in `$jobLog` o
`transcript.txt`, marcare la build come fallita e ruotare il PAT (regola di safety net,
non sostituisce le precedenti).
### 1.6 [P2] Defender + Firewall + UAC tutti disattivati nel template — documentare il modello di minaccia
File: [template/Setup-WinBuild2025.ps1:200-329](template/Setup-WinBuild2025.ps1).
File: [template/Deploy-WinBuild2025.ps1:485-551](template/Deploy-WinBuild2025.ps1) (UAC, ServerManager, DisableCAD, OOBE — set da Deploy), [template/Setup-WinBuild2025.ps1:176-336](template/Setup-WinBuild2025.ps1) (Firewall Step 1, Defender Step 2 validation-only post-refactor 2026-05-09, WinRM Step 3, User Step 4, UAC Step 4b, Dirs Step 5).
Attualmente: `Set-NetFirewallProfile ... -Enabled False`, `EnableLUA=0`, `DisableAntiSpyware=1`,
`DisableRealtimeMonitoring=1`, `LocalAccountTokenFilterPolicy=1`.
Stato attuale (post-refactor §7):
- **Defender**: disabled da Deploy (`DisableAntiSpyware=1` GPO + RTP off) — Setup Step 2 è validation-only
- **Firewall**: disabled da Setup Step 1 (`Set-NetFirewallProfile ... -Enabled False`); §7.1 prevede spostamento a Deploy
- **UAC**: `EnableLUA=0`, `LocalAccountTokenFilterPolicy=1` — duplicato Deploy + Setup Step 4b (§7.1 lo riduce a Assert-Step in Setup)
Le scelte sono ragionevoli per un template lab efimero, ma vanno raccolte in un'unica sezione
`BEST-PRACTICES.md §X — Threat Model & Hardening Trade-offs` che indichi:
@@ -237,6 +248,9 @@ senza tracciamento.
### 2.1 [P0] Race su IP allocation con `capacity: 4`
File: [runner/config.yaml:17](runner/config.yaml), [scripts/Invoke-CIJob.ps1:244-253](scripts/Invoke-CIJob.ps1).
**Stato osservato**: race non riprodotta in e2e-008/009 (un job alla volta). `capacity: 4`
resta attivo in produzione — bug teorico finché non si esegue stress test parallelo.
**Motivazione**: con 4 job paralleli e DHCP VMnet8, due VM possono ottenere lo stesso IP se
la lease pool è stretta o se due `vmrun start` rispondono troppo vicini.
`getGuestIPAddress` ritorna l'IP visto dalla VM stessa, quindi la collisione non viene
@@ -337,7 +351,8 @@ $env:PIP_CACHE_DIR = '\\vmware-host\Shared Folders\pip-cache'
Dopo lo snapshot refresh la cache va riscaldata una volta — accettabile.
### 3.2 [P1] Sostituire `Compress-Archive` con 7-Zip o robocopy
File: [scripts/Invoke-RemoteBuild.ps1:109-122](scripts/Invoke-RemoteBuild.ps1).
File: [scripts/Invoke-RemoteBuild.ps1:112,148,185](scripts/Invoke-RemoteBuild.ps1) (3 chiamate `Compress-Archive`).
Prerequisito: 7-Zip nel template — vedi §6.6 e sezione "In-VM Git Clone".
**Motivazione**: `Compress-Archive` è single-threaded e su repo medio-grandi (>100 MB sorgente)
può prendere 20-40 s.
@@ -354,7 +369,8 @@ può prendere 20-40 s.
Misurare con un repo reale: probabile risparmio 10-20 s/build su `nsis-plugin-nsinnounp`.
### 3.3 [P2] In-VM clone (`-UseGitClone`)
Implementazione disegnata di seguito (sezione "In-VM Git Clone Ottimizzazione").
Implementazione disegnata di seguito (sezione "In-VM Git Clone (Ottimizzazione)").
Vincoli sicurezza PAT: vedi §1.5. Tool prerequisiti (Git, 7-Zip): vedi §6.6.
Beneficio reale solo per repo > 200 MB con submoduli grandi; misurare prima.
### 3.4 [P3] Pre-warm pool di cloni
@@ -481,7 +497,7 @@ e centralizza retry/log.
File: [gitea/workflows/lint.yml](gitea/workflows/lint.yml) (già esiste).
Aggiungere regole specifiche progetto (`PSScriptAnalyzerSettings.psd1` in root):
- `PSAvoidUsingPlainTextForPassword` — rilevante per `Setup-WinBuild2025.ps1:55`.
- `PSAvoidUsingPlainTextForPassword` — rilevante per [Setup-WinBuild2025.ps1:123](template/Setup-WinBuild2025.ps1:123) (`[string] $BuildPassword``ConvertTo-SecureString -AsPlainText` riga 253).
- `PSAvoidUsingInvokeExpression`.
- `PSUseShouldProcessForStateChangingFunctions`.
- Regole custom: vietare hardcoded `F:\CI\` fuori da config (forzare param/env).
@@ -545,6 +561,153 @@ runs-on: ${{ matrix.target }}-build
Per chiavi di firma (Authenticode, GPG), usare i Gitea secrets nel workflow e passarli a
`Invoke-CIJob.ps1` come param + env, mai loggati. Stesso modello di §1.5 per il PAT.
### 6.6 [P2] Toolchain Tier-1 in Setup-WinBuild2025
File: [template/Setup-WinBuild2025.ps1](template/Setup-WinBuild2025.ps1).
**Motivazione**: toolchain attuale (`.NET SDK`, `Python`, `VS Build Tools`) copre solo C#/Python/MSBuild.
Aggiungere tools generici-CI riduce il bisogno di installazione ad-hoc nei workflow e abilita
build più ampi senza toccare il template.
Tool da aggiungere come step `Setup-WinBuild2025` (ognuno con `Assert-Step`):
| Tool | Versione | Razionale |
| ------------------- | ----------- | ------------------------------------------------------------ |
| **Git for Windows** | latest LTS | Self-clone in VM (alt a host-zip-transfer), submodule fetch |
| **7-Zip** | latest | Universale unpack/zip; molti installer e workflow ne dipendono |
| **PowerShell 7.x** | latest LTS | Più veloce di 5.1, parallel pipelines, operatori moderni |
| **NSIS** | latest | Test build installer (es. `nsis-plugin-nsinnounp`) |
| **CMake** | latest | Build system cross-platform per progetti C/C++ nativi |
| **Node.js LTS** | latest LTS | Frontend/Electron pipelines, JS toolchain (npm) |
| **WiX Toolset** | v4 stable | MSI building da .NET projects |
| **gh CLI** | latest | Upload artifact a release Gitea/GitHub, comment PR |
| **Sysinternals** | sysinternals.com `live` | Diagnostica process/handle quando build flaky |
| **vcpkg** | latest | Package manager C++ per dipendenze native |
**Approccio**:
- Pinning hash SHA256 per ogni installer (vedi §1.3)
- Convenzione path guest: tool in `C:\BuildTools\<tool>\` (separato da `C:\CI\` runtime
`C:\CI\` resta per artefatti job e worker temp; `C:\BuildTools\` per software statico).
Documentare in `docs/BEST-PRACTICES.md` prima di implementare.
- Aggiungere a `PATH` machine-wide
- Defender già off → no scan overhead durante install
- Step esegue in seriale dopo `Toolchain cross-check` esistente, prima di `Cleanup`
- `Final pre-snapshot gate`: aggiungere check `where.exe` per ogni tool
- Cross-link: Git for Windows e 7-Zip sono richiesti anche da §3.2 e dalla sezione
"In-VM Git Clone" — implementare qui per evitare doppio lavoro
**Validazione per-tool**:
- Eseguibile risolvibile via `where.exe`
- Versione exact match al param `-<Tool>Version`
- (per gh) `gh --version` returns 0
- (per vcpkg) `vcpkg.exe version`
**Param da aggiungere** a Setup + Prepare:
- `-GitVersion`, `-7ZipVersion`, `-Pwsh7Version`, `-NSISVersion`, `-CMakeVersion`,
`-NodeJSVersion`, `-WiXVersion`, `-GhCliVersion`, `-VcpkgRev` (rev SHA del repo)
**Tier-2 (opzionali, separati)**: Java JDK, Maven/Gradle, Rust, Go, LLVM, Docker, Azure/AWS CLI, WinDbg.
Non includere in Setup base — workflow-level via `choco install` o download diretto.
---
## 7. Refactor confine Deploy ↔ Setup
**Obiettivo**: separazione netta delle responsabilità — Deploy produce **template OS**
stand-alone, Setup fa **build customization** (user, dirs, toolchain). Eliminare drift e
duplicazioni; ogni concern ha **una sola** sorgente di verità.
**Stato attuale (duplicati)**: UAC, Explorer LaunchTo, Server Manager off, DisableCAD,
OOBE telemetry, WU services disable — entrambi gli script li toccano.
### 7.1 [P1] Spostare base OS hardening da Setup a Deploy
File: [template/Deploy-WinBuild2025.ps1](template/Deploy-WinBuild2025.ps1),
[template/Setup-WinBuild2025.ps1](template/Setup-WinBuild2025.ps1).
**Da MUOVERE Setup → Deploy**:
| Concern Setup | Step attuale Setup | Azione Deploy |
| ----------------------------- | ------------------ | ------------------------------------------- |
| Firewall off all profiles | Step 1 | Aggiungere `Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled False` in post-install (ora Deploy aggiunge solo regole RDP/ICMP) |
| WinRM tuning memoria/timeout | Step 3 (parziale) | Aggiungere `MaxMemoryPerShellMB=2048`, `IdleTimeOut=7200000`, `MaxProcessesPerShell=25` in post-install dopo Enable-PSRemoting |
**Da CONVERTIRE in Setup a Assert-Step (validation-only)**:
| Step Setup | Diventa |
| ---------- | ------- |
| Step 1 Firewall | `Assert-Step` 3 profili Enabled=False (richiede prima la riga "Da MUOVERE" → Deploy: Set-NetFirewallProfile -Enabled False) |
| Step 2 Defender | Già validation-only (refactor 2026-05-09) |
| Step 3 WinRM tuning | `Assert-Step` MaxMemoryPerShellMB, IdleTimeOut, AllowUnencrypted, Basic |
| Step 4b UAC | `Assert-Step` EnableLUA=0, LocalAccountTokenFilterPolicy=1 |
| Step 5b Explorer LaunchTo | `Assert-Step` HKCU LaunchTo=1 |
| Step 5c Server Manager / DisableCAD / OOBE | `Assert-Step` HKLM machine policy + DisableCAD=1 + OOBE policy |
**Da MANTENERE in Setup (build env, non base OS)**:
- Step 4: build user `ci_build` + admin
- Step 5: `C:\CI\{build,output,scripts}` dirs
- Step 7-9: .NET SDK, Python, VS Build Tools
- Step 10: Toolchain cross-check
- Cleanup, Final pre-snapshot gate
**Test acceptance**:
- Deploy stand-alone produce VM con tutte le validation Setup che passano (no Setup run)
- Setup run dopo Deploy: tutte Assert-Step pass `[OK]` immediato (no work)
- Test `--Skip` orthogonali (no regressione)
### 7.2 [P1] WU lifecycle — strategia B (Deploy: GPO + Manual; Setup: lifecycle)
File: [template/Deploy-WinBuild2025.ps1](template/Deploy-WinBuild2025.ps1),
[template/Setup-WinBuild2025.ps1](template/Setup-WinBuild2025.ps1).
**Stato attuale (conflitto ordering)**:
- Deploy: `sc.exe config wuauserv start= disabled` + `sc.exe stop wuauserv` (idem UsoSvc, WaaSMedicSvc) + GPO `NoAutoUpdate=1`
- Setup Step 6: necessita servizi UP per SchTask SYSTEM run WU
- Setup Step 6b: re-disabilita servizi → doppio lavoro, fragile
**Strategia B — separazione pulita**:
**Deploy** (post-install.ps1):
- Lascia servizi WU `start=demand` (Manual, default Windows) — NON `disabled`, NON `stop`
- Setta solo GPO `NoAutoUpdate=1`, `DisableWindowsUpdateAccess=1` → no background scheduled WU
- Risultato: WU è invocabile on-demand ma non parte mai da solo
**Setup** (Step 6 / 6b):
- Step 6 (skip se `-SkipWindowsUpdate`): `sc.exe config wuauserv start= demand` (idempotent), avvia SchTask SYSTEM, attende exit code, parse 0/2/3/3010
- Step 6b (sempre, anche con `-Skip`): `sc.exe config wuauserv start= disabled` + `sc.exe stop wuauserv` (idem UsoSvc, WaaSMedicSvc), conferma GPO presenti — snapshot capture WU permanently off
**Pattern run periodico patches** (allineato §2.5 snapshot versionato):
- Re-deploy template `BaseClean_<yyyyMMdd>` ogni N mesi via Deploy + Prepare (no `-Skip`) → patch applicate al template fresh
**Validazione finale** (Setup Final gate):
- `wuauserv.StartType == Disabled`
- `UsoSvc.StartType == Disabled`
- GPO `NoAutoUpdate=1`, `DisableWindowsUpdateAccess=1`
**Test acceptance**:
- Deploy stand-alone: `Get-Service wuauserv | Select StartType``Manual`, `Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU' -Name NoAutoUpdate` → 1
- Setup `-SkipWindowsUpdate`: Final gate vede `StartType=Disabled` (impostato da Step 6b)
- Setup senza `-Skip`: WU runs, exit 0/2/3, poi servizi disabled
### 7.3 [P2] Update header docs di entrambi gli script
- [template/Deploy-WinBuild2025.ps1](template/Deploy-WinBuild2025.ps1) `.DESCRIPTION`:
enumerare tutte le hardening voci che Deploy ora possiede (firewall, WinRM tuning,
WU GPO non disable)
- [template/Setup-WinBuild2025.ps1](template/Setup-WinBuild2025.ps1) `.DESCRIPTION`:
marcare Step 1/3/4b/5b/5c come "validation-only — set by Deploy"
- [docs/WINDOWS-TEMPLATE-SETUP.md](docs/WINDOWS-TEMPLATE-SETUP.md): aggiornare descrizione
"Cosa fa Setup-WinBuild2025" — riflettere nuovo confine
### 7.4 [P2] Test e2e refactor
- Run Deploy stand-alone su VM test → verifica tutte le hardening voci presenti
(`reg query` per chiavi UAC/OOBE/Server Manager, `Get-NetFirewallProfile`, `Get-Service WMUauserv`)
- Run Prepare-WinBuild2025 dopo Deploy → tutti `Assert-Step` pass `[OK]` senza work
- Run Prepare con `-SkipWindowsUpdate` → comportamento invariato
- Run Prepare senza `-Skip` → WU runs, services lifecycled correttamente
### 7.5 [P3] Rinomina Setup → Setup-CITools (opzionale, futuro)
Una volta che Setup fa solo build customization, nome `Setup-WinBuild2025` è impreciso —
non setup-a la build VM, **estende** un template OS già pronto con toolchain CI.
Rinominare in `Setup-CITools.ps1` o `Install-CIToolchain.ps1` rifletterebbe meglio la
responsabilità ridotta. Tracciare in TODO post-7.1/7.2.
---
## In-VM Git Clone (Ottimizzazione) — riferimento §3.3
@@ -574,28 +737,18 @@ VM avviata → WinRM: git clone --recurse-submodules https://<token>@gitea/...
### Task
- [ ] **Setup-WinBuild2025.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-WinBuild2025.ps1
- [ ] **Setup-WinBuild2025.ps1 — altri tool utili**
- [ ] **7-Zip**: installer silenzioso — molto più veloce di `Compress-Archive`/`Expand-Archive`
per archivi grandi (es. npm/NuGet cache warm). Necessario anche per §3.2.
- [ ] **curl.exe**: già presente in Windows 11/Server 2025 (v7.x) — verificare disponibilità
- [ ] Valutare: `jq` (parsing JSON in script PowerShell o bash) — opzionale
- [ ] **Tool prerequisiti nel template** — implementati in §6.6 (Tier-1 Toolchain):
- Git for Windows + 7-Zip + gh CLI installati con hash pinning e `Assert-Step`
- Rimuovere il commento "Git is NOT installed" dal docblock di Setup-WinBuild2025.ps1
una volta applicato §6.6
- curl.exe: già presente in Windows Server 2025 — verificare con `where.exe curl`
- [ ] **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)
- Passare PAT a `Invoke-RemoteBuild.ps1` rispettando i vincoli sicurezza di §1.5
- [ ] Comportamento default invariato (`-UseGitClone` = `$false`) — nessuna regressione
- [ ] **Invoke-RemoteBuild.ps1 — modalità in-VM clone**
@@ -608,8 +761,8 @@ VM avviata → WinRM: git clone --recurse-submodules https://<token>@gitea/...
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')`
- [ ] Implementare iniezione/pulizia PAT secondo §1.5 (env var sessione, no argv, no log,
cleanup `[System.Environment]::SetEnvironmentVariable('CI_GIT_PAT', $null, 'Process')`)
- [ ] **Test e2e con `-UseGitClone`**
- [ ] Aggiornare snapshot `BaseClean` con Git installato