Simone 8595fbaf45 fix(burn-in): default BuildCommand creates artifact dir to exercise full pipeline
'exit 0' left C:\CI\build\dist non-existent -> packaging skipped -> Get-BuildArtifacts
could not find artifacts.zip -> all 4 jobs FAIL at artifact collection phase.

New default: 'if not exist dist mkdir dist & echo burnin_ok > dist\marker.txt'
This creates dist\marker.txt relative to C:\CI\build (GuestWorkDir), so the
packaging step finds it, creates artifacts.zip, and Get-BuildArtifacts succeeds.

Also updated docblock: clarify command runs via cmd /c; replace Start-Sleep example
(PS cmdlet, does not work via WinRM cmd) with ping delay equivalent.
2026-05-12 21:21:56 +02:00

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); §3.3 in-VM git clone attivabile via -UseGitClone (e2e PASS, -25.7% vs baseline)


Panoramica

Il runner 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\<jobid>\
      └─ 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\WinBuild2025\WinBuild2025.vmx (path in runner/config.yamlGITEA_CI_TEMPLATE_PATH)
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 HTTPS/5986, Basic auth, self-signed cert (SkipCACheck — lab-only)

Variante Windows Server 2022: usare i corrispettivi *WinBuild2022.ps1 e VMX F:\CI\Templates\WinBuild2022\WinBuild2022.vmx.


Struttura repository

├── Setup-Host.ps1                # Bootstrap host: dirs F:\CI\, credenziali, act_runner service
├── PSScriptAnalyzerSettings.psd1 # Regole linting condivise (§5.4)
│
├── scripts/
│   ├── _Common.psm1              # Shared module (vmrun wrapper, session opts) §5.2
│   ├── Invoke-CIJob.ps1          # Orchestratore principale (-UseGitClone opt-in §3.3)
│   ├── New-BuildVM.ps1           # Linked clone da template
│   ├── Wait-VMReady.ps1          # Polling WinRM HTTPS readiness
│   ├── Invoke-RemoteBuild.ps1    # Zip transfer (o git clone in VM) + build via WinRM
│   ├── Get-BuildArtifacts.ps1    # Copia artifacts dall'host
│   ├── Remove-BuildVM.ps1        # Stop + rimozione VM clone (-WhatIf)
│   ├── Cleanup-OrphanedBuildVMs.ps1   # Cleanup VM orfane (§2.2)
│   ├── Invoke-RetentionPolicy.ps1     # Retention artifact + log (§2.3)
│   ├── Watch-DiskSpace.ps1            # Alert spazio libero F: (§4.3)
│   ├── Watch-RunnerHealth.ps1         # Health check runner (§2.7)
│   ├── Backup-CITemplate.ps1          # Backup VMDK template (§2.6)
│   ├── Set-TemplateSharedFolders.ps1  # Cache NuGet/pip via shared folders (§3.1)
│   ├── Measure-CIBenchmark.ps1        # Benchmark fasi pipeline (§3.6)
│   └── Register-CIScheduledTasks.ps1  # Task Scheduler bootstrap
│
├── template/
│   ├── autounattend.template.xml  # Template XML per installazione Windows unattended
│   ├── Deploy-WinBuild2025.ps1   # Deploy VM + install Windows 2025 unattended (HOST)
│   ├── Prepare-WinBuild2025.ps1  # Provisioning toolchain 2025 via WinRM (HOST-side)
│   ├── Install-CIToolchain-WinBuild2025.ps1    # Toolchain CI 2025 nella VM (GUEST-side)
│   ├── Deploy-WinBuild2022.ps1   # Deploy VM + install Windows 2022 unattended (HOST)
│   ├── Prepare-WinBuild2022.ps1  # Provisioning toolchain 2022 via WinRM (HOST-side)
│   ├── Install-CIToolchain-WinBuild2022.ps1    # Toolchain CI 2022 nella VM (GUEST-side)
│   ├── Validate-DeployState.ps1  # Validazione stato post-Deploy (2025 e 2022)
│   └── Validate-SetupState.ps1   # Validazione stato post-Setup (pre-snapshot)
│
├── tests/                        # Pester v5 unit tests (§5.1)
│
├── gitea/
│   ├── workflows/
│   │   ├── build-nsis.yml        # Workflow live per nsis-plugin-nsinnounp
│   │   └── lint.yml              # PSScriptAnalyzer su push/PR (§5.4)
│   └── workflow-example.yml      # Template generico adattabile
│
├── runner/
│   ├── config.yaml               # Configurazione act_runner (no secrets)
│   └── Install-Runner.ps1
│
├── docs/
│   ├── ARCHITECTURE.md           # Diagramma sistema e componenti
│   ├── CI-FLOW.md                # Flusso dettagliato passo-passo
│   ├── HOST-SETUP.md             # Bootstrap macchina host
│   ├── WINDOWS-TEMPLATE-SETUP.md # Provisioning template Windows
│   ├── LINUX-TEMPLATE-SETUP.md   # Bozza template Linux (§6.1, non implementato)
│   ├── OPTIMIZATION.md           # Layout disco, snapshot, cache, tuning
│   ├── BEST-PRACTICES.md         # Sicurezza, WinRM, credenziali, threat model
│   ├── RUNBOOK.md                # Triage incident comuni (§4.4)
│   ├── TEST-PLAN-v1.3-to-HEAD.md # Test plan completo features post-v1.3
│   ├── Setup-GiteaSSH.md         # Configurazione SSH alias per Gitea
│   └── archived/                 # Doc storici / sign-off
│
└── TODO.md                       # Roadmap, audit trail task completati, backlog

Setup rapido

1. Template VM

Opzione A — Deploy automatico (crea VM + installa Windows unattended da ISO):

cd N:\Code\Workspace\Local-CI-CD-System\template
# Windows Server 2025 (corrente):
.\Deploy-WinBuild2025.ps1 -ISOPath F:\CI\ISO\WinSrv2025.iso `
    -VMPath F:\CI\Templates\WinBuild2025\WinBuild2025.vmx
# Windows Server 2022 (alternativa):
.\Deploy-WinBuild2022.ps1 -ISOPath F:\CI\ISO\WinSrv2022.iso `
    -VMPath F:\CI\Templates\WinBuild2022\WinBuild2022.vmx

Opzione B — installazione manuale: installa Windows nella VM, abilita WinRM (winrm quickconfig -q + Enable-PSRemoting -Force), annota l'IP VMnet8.

Provisioning toolchain (dopo A o B, dalla directory template/):

# Windows Server 2025:
.\Prepare-WinBuild2025.ps1 -VMIPAddress 192.168.79.x -StoreCredential
# Windows Server 2022:
.\Prepare-WinBuild2022.ps1 -VMIPAddress 192.168.79.x -StoreCredential

Poi spegni la VM e prendi lo snapshot con nome esatto BaseClean.

2. Credenziali guest

# PowerShell elevato — una volta sola sull'host
Import-Module CredentialManager
New-StoredCredential -Target "BuildVMGuest" -UserName "ci_build" `
    -Password "<your-build-password>" -Persist LocalMachine

3. act_runner

# 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\WinBuild2025\WinBuild2025.vmx

Dettagli completi: docs/HOST-SETUP.md.

4. SSH per Gitea

Vedi docs/Setup-GiteaSSH.md per configurare l'alias gitea-ci (SSH port 2222, usato dai workflow live in git clone ssh://gitea-ci/...).


Uso — build manuale (test)

& '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\WinBuild2025\WinBuild2025.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.

Aggiungi -UseGitClone per clonare direttamente in VM (skip host-zip-transfer; richiede Git+7-Zip in template — già inclusi nel Tier-1 Toolchain §6.6).


Workflow Gitea

Il file 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 e aggiorna -RepoUrl, -BuildCommand e -GuestArtifactSource.


Documentazione

File Contenuto
docs/ARCHITECTURE.md Diagramma componenti e flusso dati
docs/CI-FLOW.md Descrizione dettagliata di ogni fase del pipeline
docs/HOST-SETUP.md Bootstrap macchina host (Setup-Host.ps1)
docs/WINDOWS-TEMPLATE-SETUP.md Provisioning template Windows (Deploy + Prepare + Setup)
docs/LINUX-TEMPLATE-SETUP.md Bozza template Linux (§6.1, non implementato)
docs/OPTIMIZATION.md Layout NVMe, snapshot strategy, cache, tuning
docs/BEST-PRACTICES.md Sicurezza WinRM, threat model, credenziali
docs/RUNBOOK.md Triage incident comuni (runner offline, clone fail, ecc.)
docs/TEST-PLAN-v1.3-to-HEAD.md Test plan completo features post-v1.3
docs/Setup-GiteaSSH.md Configurazione SSH alias gitea-ci
TODO.md Roadmap, audit trail task completati, backlog

Note di sicurezza

WinRM usa HTTPS/5986 con certificato self-signed e Basic auth. -SkipCACheck/-SkipCNCheck sono accettabili in lab isolato (il cert non è di una CA trusted). Per ambienti condivisi o di produzione, usare un certificato CA valida e rimuovere -SkipCACheck. Vedi docs/BEST-PRACTICES.md.

S
Description
Local CI/CD system: VMware Workstation + Gitea Actions + act_runner. Ephemeral build VMs via linked clones.
Readme 6.6 MiB
Languages
Python 50.8%
PowerShell 46.1%
Shell 3.1%