feat(a3): port build pipeline (vm new, build run, artifacts collect)

Implements Phase A3 of plans/implementation-plan-A-B.md:

- commands/vm.py: vm new (replaces New-BuildVM.ps1)

- commands/build.py: build run (replaces Invoke-RemoteBuild.ps1) with WinRM/SSH dispatch and stdout streaming for act_runner

- commands/artifacts.py: artifacts collect (replaces Get-BuildArtifacts.ps1) using transport.fetch()

- 3 PS scripts reduced to shims preserving \0

- Pester tests/{New-BuildVM,Wait-VMReady,Remove-BuildVM}.Tests.ps1 removed; equivalent cases covered in pytest

- Phase C hook: build/artifacts accept opaque VmHandle/vmx; no Windows path assumptions

Tests: 91 pytest, ruff clean, mypy --strict clean, coverage 78.27% (>=70 gate).

Master checklist + step A3 attivita + 'definizione di fatto' updated; A3-closeout.md added.
This commit is contained in:
2026-05-14 17:20:34 +02:00
parent 096ba7fe16
commit 816a15503e
15 changed files with 1900 additions and 1061 deletions
+16 -16
View File
@@ -60,10 +60,10 @@ A4; cambiano solo path/env vars in Fase B).
- [x] [A2] Portare `Watch-RunnerHealth.ps1``monitor runner`
- [x] [A2] Portare `Get-CIJobSummary.ps1``report job`
- [x] [A2] Sostituire ognuno dei `.ps1` portati con shim a 3 righe verso la CLI Python
- [ ] [A3] Portare `New-BuildVM.ps1``vm new`
- [ ] [A3] Portare `Invoke-RemoteBuild.ps1``build run`
- [ ] [A3] Portare `Get-BuildArtifacts.ps1``artifacts collect`
- [ ] [A3] Convertire test Pester `New-BuildVM.Tests.ps1`, `Wait-VMReady.Tests.ps1`, `Remove-BuildVM.Tests.ps1` in pytest
- [x] [A3] Portare `New-BuildVM.ps1``vm new`
- [x] [A3] Portare `Invoke-RemoteBuild.ps1``build run`
- [x] [A3] Portare `Get-BuildArtifacts.ps1``artifacts collect`
- [x] [A3] Convertire test Pester `New-BuildVM.Tests.ps1`, `Wait-VMReady.Tests.ps1`, `Remove-BuildVM.Tests.ps1` in pytest
- [ ] [A4] Portare `Invoke-CIJob.ps1``python -m ci_orchestrator job`
- [ ] [A4] Aggiornare `gitea/actions/local-ci-build/action.yml` per invocare la CLI Python direttamente
- [ ] [A4] Forzare `PYTHONIOENCODING=utf-8` in `runner/config.yaml`
@@ -229,15 +229,15 @@ Python preservando il comportamento dei `.ps1` esistenti.
**Attività**:
- [ ] Implementare `vm new` in `commands/vm.py` (parametri `--template`, `--snapshot`, `--name`, `--guest-os`)
- [ ] Integrare `WorkstationVmrunBackend.clone_linked` + `start` + attesa IP via `get_ip`
- [ ] Implementare `commands/build.py` con `build run` (parametri `--vmx`, `--script`, `--workdir`, `--guest-os`); usa `transport.winrm` per Windows, `transport.ssh` per Linux
- [ ] Gestione streaming output build verso stdout (act_runner cattura stdout — preservare comportamento `Write-Host`)
- [ ] Implementare `commands/artifacts.py` con `artifacts collect` (parametri `--vmx`, `--remote-path`, `--local-dir`)
- [ ] Sostituire `scripts/New-BuildVM.ps1`, `Invoke-RemoteBuild.ps1`, `Get-BuildArtifacts.ps1` con shim
- [ ] Convertire `tests/New-BuildVM.Tests.ps1` in `tests/test_commands_vm_new.py`
- [ ] Aggiungere test pytest per `build run` (mock transport + capture stdout)
- [ ] Aggiungere test pytest per `artifacts collect` (mock SFTP/WinRM file copy + tmp_path)
- [x] Implementare `vm new` in `commands/vm.py` (parametri `--template`, `--snapshot`, `--name`, `--guest-os`)
- [x] Integrare `WorkstationVmrunBackend.clone_linked` + `start` + attesa IP via `get_ip`
- [x] Implementare `commands/build.py` con `build run` (parametri `--vmx`, `--script`, `--workdir`, `--guest-os`); usa `transport.winrm` per Windows, `transport.ssh` per Linux
- [x] Gestione streaming output build verso stdout (act_runner cattura stdout — preservare comportamento `Write-Host`)
- [x] Implementare `commands/artifacts.py` con `artifacts collect` (parametri `--vmx`, `--remote-path`, `--local-dir`)
- [x] Sostituire `scripts/New-BuildVM.ps1`, `Invoke-RemoteBuild.ps1`, `Get-BuildArtifacts.ps1` con shim
- [x] Convertire `tests/New-BuildVM.Tests.ps1` in `tests/test_commands_vm_new.py`
- [x] Aggiungere test pytest per `build run` (mock transport + capture stdout)
- [x] Aggiungere test pytest per `artifacts collect` (mock SFTP/WinRM file copy + tmp_path)
- [ ] Validare end-to-end: clone WinBuild2025 → build script PowerShell trivial → collect artifact ZIP
**Hook futuri Fase C**: `build run` deve ricevere un `VmHandle` opaco,
@@ -257,10 +257,10 @@ Python; nessuna modifica ai workflow YAML in A3 (solo shim).
**Definizione di fatto step A3**:
- [ ] Pipeline build completa accessibile via Python CLI
- [ ] Shim PS preservano l'API per i caller esistenti
- [x] Pipeline build completa accessibile via Python CLI
- [x] Shim PS preservano l'API per i caller esistenti
- [ ] Smoke build PASS contro VM reale Windows e Linux
- [ ] Pester `New-BuildVM.Tests.ps1` rimosso e sostituito
- [x] Pester `New-BuildVM.Tests.ps1` rimosso e sostituito
### A4 — Orchestratore + switch workflow