# Local CI/CD System Sistema CI/CD self-hosted su Windows per build isolati in VM efimere VMware. **Stato**: production-ready — e2e verificato (e2e-009 SUCCESS) --- ## Panoramica Il runner [act_runner](https://gitea.com/gitea/act_runner) riceve i job da Gitea Actions. Per ogni job, lo script `Invoke-CIJob.ps1` orchestra l'intero ciclo: ``` Gitea push/tag │ ▼ act_runner (Windows service, label: windows-build) │ ▼ Invoke-CIJob.ps1 │ ├─ 1. git clone repo su host (con submoduli) ├─ 2. Linked clone da snapshot BaseClean ├─ 3. Avvio VM headless ├─ 4. Attesa WinRM ready ├─ 5. Zip transfer → build via WinRM → raccolta artifacts ├─ 6. Copia artifacts in F:\CI\Artifacts\\ └─ finally: stop + rimozione VM clone ``` Ogni build gira in una VM Windows Server 2025 **usa e getta**, ripristinata dallo snapshot `BaseClean` ad ogni run. --- ## Requisiti Host | Componente | Versione / Dettaglio | |---|---| | OS | Windows 11 | | CPU/RAM | i9-10900X, 64 GB RAM | | VMware Workstation Pro | installato, `vmrun.exe` disponibile | | PowerShell | 5.1 | | 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` | ## Template VM (snapshot `BaseClean`) | Componente | Versione | |---|---| | OS | Windows Server 2025 | | VMX | `F:\CI\Templates\WinBuild\CI-WinBuild.vmx` | | VS Build Tools | 2026 (MSBuild 18.5.4 / toolset v145) | | .NET SDK | 10.0.203 | | Python | 3.13.3 | | Rete | VMnet8 NAT — `192.168.79.0/24` | | WinRM | HTTP/5985, Basic auth (lab-only) | --- ## Struttura repository ``` ├── Setup-Host.ps1 # Bootstrap host: dirs F:\CI\, credenziali, act_runner service │ ├── scripts/ │ ├── Invoke-CIJob.ps1 # Orchestratore principale │ ├── New-BuildVM.ps1 # Linked clone da template │ ├── Wait-VMReady.ps1 # Polling WinRM readiness │ ├── Invoke-RemoteBuild.ps1 # Zip transfer + esecuzione build in VM │ ├── Get-BuildArtifacts.ps1 # Copia artifacts dall'host │ └── Remove-BuildVM.ps1 # Stop + rimozione VM clone │ ├── template/ │ ├── Prepare-TemplateSetup.ps1 # Provisioning automatico template VM (HOST-side) │ └── Setup-TemplateVM.ps1 # Installazione toolchain nella VM (GUEST-side) │ ├── gitea/ │ ├── workflows/ │ │ └── build-nsis.yml # Workflow live per nsis-plugin-nsinnounp │ └── workflow-example.yml # Template generico adattabile │ ├── runner/ │ └── config.yaml # Configurazione act_runner (no secrets) │ ├── docs/ │ ├── ARCHITECTURE.md # Diagramma sistema e componenti │ ├── CI-FLOW.md # Flusso dettagliato passo-passo │ ├── OPTIMIZATION.md # Layout disco, snapshot, cache, tuning │ ├── BEST-PRACTICES.md # Sicurezza, WinRM, credenziali │ └── Setup-GiteaSSH.md # Configurazione SSH alias per Gitea │ ├── PLAN.md # Stato implementazione e decisioni tecniche └── TODO.md # Task completati e roadmap futura ``` --- ## Setup rapido ### 1. Template VM ```powershell # Dalla directory template/, dopo aver installato Windows Server 2025 nella VM # e annotato il suo IP DHCP su VMnet8: .\Prepare-TemplateSetup.ps1 -VMIPAddress 192.168.79.x -SkipWindowsUpdate ``` Poi spegni la VM e prendi lo snapshot con nome esatto **`BaseClean`**. ### 2. Credenziali guest ```powershell # PowerShell elevato — una volta sola sull'host Import-Module CredentialManager New-StoredCredential -Target "BuildVMGuest" -UserName "ci_build" ` -Password "CIBuild!ChangeMe2026" -Persist LocalMachine ``` ### 3. act_runner ```powershell # Registra il runner con Gitea (interattivo, usa il registration token da Gitea Admin) F:\CI\act_runner\act_runner.exe register # Installa come servizio Windows nssm install act_runner "F:\CI\act_runner\act_runner.exe" daemon nssm start act_runner ``` Imposta `GITEA_CI_TEMPLATE_PATH` nelle variabili d'ambiente del servizio: `F:\CI\Templates\WinBuild\CI-WinBuild.vmx` ### 4. SSH per Gitea Vedi [docs/Setup-GiteaSSH.md](docs/Setup-GiteaSSH.md) per configurare l'alias `gitea-ci` (SSH port 2222, necessario per `git clone ssh://gitea-ci/...` durante i build). --- ## Uso — build manuale (test) ```powershell & 'N:\Code\Workspace\Local-CI-CD-System\scripts\Invoke-CIJob.ps1' ` -JobId 'test-001' ` -RepoUrl 'ssh://gitea-ci/Simone/nsis-plugin-nsinnounp.git' ` -Branch 'main' ` -Commit '' ` -TemplatePath 'F:\CI\Templates\WinBuild\CI-WinBuild.vmx' ` -Submodules ` -BuildCommand 'python build_plugin.py --final --dist-dir dist' ` -GuestArtifactSource 'dist' ` -GuestCredentialTarget 'BuildVMGuest' ``` Artifacts raccolti in: `F:\CI\Artifacts\test-001\artifacts.zip` --- ## Workflow Gitea Il file [gitea/workflows/build-nsis.yml](gitea/workflows/build-nsis.yml) è il workflow attivo per `Simone/nsis-plugin-nsinnounp`. Si attiva su push di tag `v*` o manualmente. Per adattarlo ad altri repository, copia [gitea/workflow-example.yml](gitea/workflow-example.yml) e aggiorna `-RepoUrl`, `-BuildCommand` e `-GuestArtifactSource`. --- ## Documentazione | File | Contenuto | |---|---| | [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/OPTIMIZATION.md](docs/OPTIMIZATION.md) | Layout NVMe, snapshot strategy, cache, tuning WinRM | | [docs/BEST-PRACTICES.md](docs/BEST-PRACTICES.md) | Sicurezza WinRM, gestione credenziali, isolamento | | [docs/Setup-GiteaSSH.md](docs/Setup-GiteaSSH.md) | Configurazione SSH alias `gitea-ci` | --- ## Note di sicurezza WinRM in modalità HTTP/Basic è **accettabile solo in ambiente lab isolato**. Per ambienti di produzione o condivisi, migrare a HTTPS/5986 con certificato self-signed e rimuovere `AllowUnencrypted=true`. Vedi [docs/BEST-PRACTICES.md](docs/BEST-PRACTICES.md).