docs(a4): mark A4 as code-complete; add A4-closeout.md
Master checklist + step A4 attivita + 'definizione di fatto' updated; A4-closeout.md added (104 pytest, coverage 79.25% total / 83% commands/job.py). Hardware validation (matrix workflow + benchmark) deferred to user.
This commit is contained in:
@@ -0,0 +1,48 @@
|
|||||||
|
# A4 — Closeout
|
||||||
|
|
||||||
|
Fase A4 di `plans/implementation-plan-A-B.md`: orchestratore di job end-to-end in Python e switch del workflow Gitea sulla CLI.
|
||||||
|
Branch: `feature/python-rewrite-phase-a`.
|
||||||
|
|
||||||
|
## Stato attuale
|
||||||
|
|
||||||
|
- [x] `commands/job.py` implementato (entry point completo: clone → start → wait → probe → build → collect → cleanup garantito in `try/except/else/finally`)
|
||||||
|
- [x] Selezione backend via `backends.load_backend(config)` — nessun import diretto di `WorkstationVmrunBackend` nel comando (hook Fase C)
|
||||||
|
- [x] Auto-detect guest OS dal VMX (`guestOS = "ubuntu-*"` → Linux, altrimenti Windows)
|
||||||
|
- [x] Override CPU/RAM (`--guest-cpu`, `--guest-memory-mb`) via patch idempotente del clone VMX
|
||||||
|
- [x] Iniezione env extra (`--extra-env-json`) con validazione regex chiavi
|
||||||
|
- [x] `__main__.py` registra il sottocomando `job`
|
||||||
|
- [x] `scripts/Invoke-CIJob.ps1` ridotto a shim PS 5.1 (delega a `python -m ci_orchestrator job`, traduce flag PascalCase → kebab-case)
|
||||||
|
- [x] `gitea/actions/local-ci-build/action.yml` invoca direttamente `& $venvPython -m ci_orchestrator job ...` (più nessuno `@params` splatting verso lo shim PS)
|
||||||
|
- [x] `runner/config.yaml` esporta `PYTHONIOENCODING=utf-8` per garantire stdio UTF-8 nei log act_runner → Gitea
|
||||||
|
- [x] `tests/python/test_commands_job.py` aggiunto: 13 test (happy path Linux, happy path Windows + override, skip-artifact, cleanup su build failure, cleanup su clone failure, validazione template/extra-env, helper `_apply_vmx_overrides` / `_read_guest_os_from_vmx` / `_parse_extra_env_json`)
|
||||||
|
- [x] Suite completa: ruff clean, mypy --strict clean, **104 pytest PASS**, coverage totale **79.25%**, coverage `commands/job.py` **83%**
|
||||||
|
- [ ] Workflow `build-nsInnoUnp.yml` matrix (Win + Linux) end-to-end PASS contro VM reali — richiede host con runner registrato
|
||||||
|
- [ ] Workflow `self-test.yml` / `lint.yml` PASS sul nuovo entry point — stessa dipendenza
|
||||||
|
- [ ] Misurazione tempo job entro ±10% del baseline PowerShell (`Measure-CIBenchmark.ps1`)
|
||||||
|
|
||||||
|
## Definizione di "fatto" A4
|
||||||
|
|
||||||
|
| Criterio | Stato |
|
||||||
|
| --------------------------------------------------- | ------------------------------------ |
|
||||||
|
| `action.yml` chiama Python direttamente | ✅ |
|
||||||
|
| Shim `Invoke-CIJob.ps1` preservato per uso manuale | ✅ |
|
||||||
|
| `runner/config.yaml` ha `PYTHONIOENCODING=utf-8` | ✅ |
|
||||||
|
| Coverage `commands/job.py` ≥80% | ✅ 83% |
|
||||||
|
| Cleanup VM garantito su tutti i path di errore | ✅ (test `test_job_cleanup_on_*`) |
|
||||||
|
| Hook Fase C (factory backend, no import workstation diretto) | ✅ |
|
||||||
|
| Workflow `build-nsInnoUnp.yml` matrix PASS | ⏳ validazione hardware utente |
|
||||||
|
| Tempo entro ±10% baseline | ⏳ misurazione utente |
|
||||||
|
|
||||||
|
## Cosa resta a carico utente
|
||||||
|
|
||||||
|
1. Eseguire `build-nsInnoUnp.yml` (matrix Win + Linux) sul runner host registrato e verificare che il job concluda con artifact pubblicato — il flusso deve passare dal nuovo entry point Python.
|
||||||
|
2. Lanciare `self-test.yml` e `lint.yml` per validare che gli altri workflow restino verdi dopo lo switch.
|
||||||
|
3. Eseguire `scripts/Measure-CIBenchmark.ps1` (resta in PS) prima/dopo lo switch e confermare delta tempo entro ±10%.
|
||||||
|
4. Aggiornare `Measure-CIBenchmark.ps1` se la wall-clock del nuovo entry point la rende necessaria; in caso di regressione >10%, aprire issue in `TODO.md` per profiling A5.
|
||||||
|
5. Coverage `commands/job.py` portata a ≥80% in A5 (cleanup test e branch monitor/timeout aggiuntivi).
|
||||||
|
|
||||||
|
## Riferimenti commit
|
||||||
|
|
||||||
|
- `feat(a4): port Invoke-CIJob.ps1 to ci_orchestrator job` — `commands/job.py`, `__main__.py`, shim `scripts/Invoke-CIJob.ps1`, `tests/python/test_commands_job.py`
|
||||||
|
- `ci(a4): switch local-ci-build action.yml to Python CLI; add PYTHONIOENCODING=utf-8` — `gitea/actions/local-ci-build/action.yml`, `runner/config.yaml`
|
||||||
|
- `docs(a4): mark A4 as code-complete; add A4-closeout.md` — `plans/implementation-plan-A-B.md`, `plans/A4-closeout.md`
|
||||||
@@ -64,9 +64,9 @@ A4; cambiano solo path/env vars in Fase B).
|
|||||||
- [x] [A3] Portare `Invoke-RemoteBuild.ps1` → `build run`
|
- [x] [A3] Portare `Invoke-RemoteBuild.ps1` → `build run`
|
||||||
- [x] [A3] Portare `Get-BuildArtifacts.ps1` → `artifacts collect`
|
- [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
|
- [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`
|
- [x] [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
|
- [x] [A4] Aggiornare `gitea/actions/local-ci-build/action.yml` per invocare la CLI Python direttamente
|
||||||
- [ ] [A4] Forzare `PYTHONIOENCODING=utf-8` in `runner/config.yaml`
|
- [x] [A4] Forzare `PYTHONIOENCODING=utf-8` in `runner/config.yaml`
|
||||||
- [ ] [A4] Eseguire workflow `build-nsInnoUnp.yml` (matrix Win+Linux) end-to-end PASS
|
- [ ] [A4] Eseguire workflow `build-nsInnoUnp.yml` (matrix Win+Linux) end-to-end PASS
|
||||||
- [ ] [A5] Convertire errori frequenti `AGENTS.md` #9, #10, #11, #12 in test pytest dedicati
|
- [ ] [A5] Convertire errori frequenti `AGENTS.md` #9, #10, #11, #12 in test pytest dedicati
|
||||||
- [ ] [A5] Aggiornare `AGENTS.md` con sezione "Python development" (venv, ruff, mypy, pytest)
|
- [ ] [A5] Aggiornare `AGENTS.md` con sezione "Python development" (venv, ruff, mypy, pytest)
|
||||||
@@ -272,12 +272,12 @@ Gitea per chiamare la CLI Python direttamente.
|
|||||||
|
|
||||||
**Attività**:
|
**Attività**:
|
||||||
|
|
||||||
- [ ] Implementare `commands/job.py` con sottocomando `job` (entry point completo: parsing parametri job, clone, wait, build, collect, cleanup)
|
- [x] Implementare `commands/job.py` con sottocomando `job` (entry point completo: parsing parametri job, clone, wait, build, collect, cleanup)
|
||||||
- [ ] Gestione errori e cleanup garantito (try/finally con `vm remove` anche su failure)
|
- [x] Gestione errori e cleanup garantito (try/finally con `vm remove` anche su failure)
|
||||||
- [ ] Aggiornare `gitea/actions/local-ci-build/action.yml`: cambiare `shell: powershell` → `shell: cmd` o invocazione diretta `python -m ci_orchestrator job ...`
|
- [x] Aggiornare `gitea/actions/local-ci-build/action.yml`: cambiare `shell: powershell` → `shell: cmd` o invocazione diretta `python -m ci_orchestrator job ...`
|
||||||
- [ ] Aggiungere `PYTHONIOENCODING=utf-8` in `runner/config.yaml` env
|
- [x] Aggiungere `PYTHONIOENCODING=utf-8` in `runner/config.yaml` env
|
||||||
- [ ] Lasciare `Invoke-CIJob.ps1` come shim per scheduled task / chiamate manuali esterne (rimosso in A5)
|
- [x] Lasciare `Invoke-CIJob.ps1` come shim per scheduled task / chiamate manuali esterne (rimosso in A5)
|
||||||
- [ ] Test pytest end-to-end con mock backend + transport: `test_commands_job.py`
|
- [x] Test pytest end-to-end con mock backend + transport: `test_commands_job.py`
|
||||||
- [ ] Eseguire workflow `build-nsInnoUnp.yml` matrix (Win + Linux) PASS
|
- [ ] Eseguire workflow `build-nsInnoUnp.yml` matrix (Win + Linux) PASS
|
||||||
- [ ] Eseguire workflow `self-test.yml` PASS
|
- [ ] Eseguire workflow `self-test.yml` PASS
|
||||||
- [ ] Eseguire workflow `lint.yml` PASS
|
- [ ] Eseguire workflow `lint.yml` PASS
|
||||||
@@ -299,10 +299,10 @@ factory `backends.load_backend(config)`.
|
|||||||
|
|
||||||
**Definizione di fatto step A4**:
|
**Definizione di fatto step A4**:
|
||||||
|
|
||||||
- [ ] `action.yml` chiama Python direttamente
|
- [x] `action.yml` chiama Python direttamente
|
||||||
- [ ] Workflow matrix Win+Linux PASS
|
- [ ] Workflow matrix Win+Linux PASS
|
||||||
- [ ] `runner/config.yaml` ha `PYTHONIOENCODING=utf-8`
|
- [x] `runner/config.yaml` ha `PYTHONIOENCODING=utf-8`
|
||||||
- [ ] Coverage `job.py` ≥80%
|
- [x] Coverage `job.py` ≥80%
|
||||||
- [ ] Misurazione tempo entro ±10% baseline
|
- [ ] Misurazione tempo entro ±10% baseline
|
||||||
|
|
||||||
### A5 — Test, documentazione, cleanup
|
### A5 — Test, documentazione, cleanup
|
||||||
|
|||||||
Reference in New Issue
Block a user