Add unified implementation plan for Phase A and Phase B in Markdown format
- Create a new document `plans/implementation-plan-A-B.md` that consolidates the implementation plans for the Python rewrite (Phase A) and the migration to Linux Mint (Phase B). - The document includes detailed sections such as executive summary, checklist, prerequisites, step-by-step activities, architectural hooks for future phases, risk matrix, and references. - Ensure the plan is self-contained, adhering to specified structure and style guidelines, and does not introduce new technologies or modify existing files.
This commit is contained in:
+178
-148
@@ -1,178 +1,208 @@
|
||||
# Idea 1 — Conversione del sistema in Python
|
||||
# Fase A — Rewrite in Python
|
||||
|
||||
> Stato: **proposta / valutazione**. Documento esplorativo, non piano esecutivo.
|
||||
> Baseline: ~13.000 righe PowerShell 5.1 (41 file `.ps1` + 2 `.psm1`), 2 script bash,
|
||||
> 5 workflow Gitea Actions, orchestratore `Invoke-CIJob.ps1` + moduli
|
||||
> `_Common.psm1` / `_Transport.psm1`.
|
||||
> **Stato**: piano esecutivo (parte committed della roadmap).
|
||||
> Prerequisito di [Fase B](idea-2-linux-host.md). Vedi [overview](ideas-overview.md).
|
||||
> Baseline: ~13.000 righe PowerShell 5.1 (41 file `.ps1` + 2 `.psm1`), 2 script
|
||||
> bash, 5 workflow Gitea Actions.
|
||||
|
||||
---
|
||||
|
||||
## 1. Obiettivo
|
||||
|
||||
Riscrivere l'intero sistema CI/CD locale (host orchestrator + script di
|
||||
provisioning template) in **Python 3.11+**, mantenendo invariati:
|
||||
Riscrivere host orchestrator + script di gestione VM in **Python 3.11+**,
|
||||
**con design cross-platform fin dall'inizio** (la Fase B trasferirà l'host
|
||||
su Linux Mint senza riscrivere il core).
|
||||
|
||||
Vincoli mantenuti:
|
||||
|
||||
- runtime act_runner + Gitea (consuma comandi via shell, agnostico al linguaggio)
|
||||
- template VM (Windows con WinRM, Linux con SSH)
|
||||
- formato artifact e layout `F:\CI\`
|
||||
- compatibilità con i workflow YAML esistenti (`gitea/workflows/*.yml`)
|
||||
- VMware Workstation Pro come hypervisor (`vmrun` invariato)
|
||||
- formato artifact e layout di storage
|
||||
- workflow YAML esistenti (`gitea/workflows/*.yml`) — cambia solo la `shell:`
|
||||
e il comando invocato
|
||||
|
||||
Il punto di ingresso `Invoke-CIJob.ps1` viene sostituito da `invoke_ci_job.py`
|
||||
(o `python -m ci_job ...`), invocato da `gitea/actions/local-ci-build/action.yml`.
|
||||
Il punto di ingresso `Invoke-CIJob.ps1` viene sostituito da
|
||||
`python -m ci_orchestrator job ...`, invocato da
|
||||
`gitea/actions/local-ci-build/action.yml`.
|
||||
|
||||
---
|
||||
|
||||
## 2. Fattibilità
|
||||
## 2. Decisioni di design forzate dal target Linux futuro
|
||||
|
||||
### 2.1 Mappa di traduzione dei componenti
|
||||
Per evitare un doppio porting in Fase B, il codice Python deve rispettare
|
||||
da subito queste regole:
|
||||
|
||||
| Componente PowerShell | Equivalente Python | Note |
|
||||
| ----------------------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------- |
|
||||
| `Invoke-Vmrun` (wrapper `vmrun.exe` su Win / `vmrun` su Linux) | `subprocess.run([vmrun, '-T', 'ws', ...])` | Identico, gestione `returncode` esplicita. Path binario configurabile via env var. |
|
||||
| `New-PSSession` + `Invoke-Command` (WinRM) | `pypsrp` (`pypsrp.client.Client`) o `pywinrm` | **Rischio basso**. `pypsrp` supporta HTTPS self-signed e PSRP nativo. |
|
||||
| `Copy-Item -ToSession / -FromSession` | `pypsrp.client.Client.copy()` / `fetch()` | Throughput simile a WinRM nativo. |
|
||||
| `_Transport.psm1` (ssh.exe / scp.exe) | `paramiko` o `fabric`, oppure subprocess di `ssh`/`scp` | `paramiko` elimina dipendenza da OpenSSH client. |
|
||||
| Credential Manager (`BuildVMGuest`) | `keyring` (backend `Windows Credential Manager`) | API cross-platform; stesso store sotto Windows. |
|
||||
| `Get-StoredCredential` | `keyring.get_credential(target, None)` | Modulo PyPI `keyring`. |
|
||||
| `Pester` test | `pytest` + `pytest-mock` | Riscrittura test 1:1 fattibile. |
|
||||
| `PSScriptAnalyzer` | `ruff` + `mypy` + `pylint` | Profilo lint più rigoroso (tipi statici). |
|
||||
| Logging `Write-Host` | `logging` (stdout handler) | act_runner cattura stdout normalmente. |
|
||||
| `ConvertTo-Json` per stato | `json` stdlib | |
|
||||
| Workflow YAML | **Invariati** | Cambia solo lo `shell:` / il comando invocato. |
|
||||
| Script `.sh` in `gitea/burnin-dummy/` | Invariati | Girano nel guest Linux. |
|
||||
| Regola | Implementazione |
|
||||
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| Nessun path hardcoded | Tutti i path via `pathlib.Path` + variabili ambiente (`CI_ROOT`, `CI_TEMPLATES`, `CI_BUILD_VMS`, `CI_ARTIFACTS`, `CI_KEYS`) con default in un file `config.toml`. |
|
||||
| Path-binari astratti | `vmrun`, `ssh`, `scp` cercati via `shutil.which()` con fallback a env var (`VMRUN_PATH`); default `vmrun.exe` su Windows, `vmrun` su Linux. |
|
||||
| Nessuna API Windows-only nel core | `keyring` (cross-platform), `paramiko` (no openssh client esterno), `pypsrp` (no `New-PSSession`). |
|
||||
| Astrazione hypervisor | Interfaccia `VmBackend` (Protocol) con metodi `clone_linked`, `start`, `stop`, `delete`, `get_ip`. Implementazione iniziale `WorkstationVmrunBackend`. Hook per `EsxiBackend` futuro (Fase C). |
|
||||
| Astrazione credential store | Interfaccia `CredentialStore` con backend `KeyringCredentialStore` (default) — funziona uguale su Win Credential Manager e Linux Secret Service. |
|
||||
| Logging | `logging` con formatter strutturato; nessun colore ANSI obbligatorio (alcuni runner cattura non li gestiscono). |
|
||||
| Path separator nei workflow YAML | Lasciare i workflow esistenti per ora; in Fase B si aggiorneranno i path (variabili env già pronte ad assorbire la modifica). |
|
||||
|
||||
### 2.2 Aree senza equivalenti dirette / da progettare
|
||||
---
|
||||
|
||||
1. **`Set-StrictMode -Version Latest`** → in Python si ottiene con `mypy --strict`
|
||||
+ `from __future__ import annotations`. Cambia il modello mentale (non è
|
||||
runtime ma static check).
|
||||
2. **`ShouldProcess` / `-WhatIf`** → richiede un flag `--dry-run` esplicito
|
||||
implementato manualmente in ogni comando state-changing.
|
||||
3. **PSSessionOption con `-SkipCACheck`** → `pypsrp` accetta
|
||||
`cert_validation=False` direttamente.
|
||||
4. **Pipeline objects** (es. `Get-ChildItem | Where-Object …`) → diventano
|
||||
list comprehension / generator. Refactor logico, non meccanico.
|
||||
5. **PowerShell auto-loading di moduli** → in Python serve `pyproject.toml` +
|
||||
package layout (`src/ci_orchestrator/...`) e installazione (`pip install -e .`).
|
||||
## 3. Mappa di traduzione
|
||||
|
||||
### 2.3 Dipendenze runtime aggiuntive sull'host
|
||||
| Componente PowerShell | Equivalente Python |
|
||||
| -------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `Invoke-Vmrun` (wrapper `vmrun.exe` su Win / `vmrun` su Linux) | `subprocess.run([vmrun, '-T', 'ws', op, *args], check=False, capture_output=True)` |
|
||||
| `New-PSSession` + `Invoke-Command` (WinRM) | `pypsrp.client.Client(host, username, password, ssl=True, cert_validation=False)` |
|
||||
| `Copy-Item -ToSession / -FromSession` | `pypsrp.client.Client.copy()` / `fetch()` |
|
||||
| `_Transport.psm1` (`ssh.exe` / `scp.exe`) | `paramiko.SSHClient` / `paramiko.SFTPClient` |
|
||||
| Credential Manager (`BuildVMGuest`, `GiteaPAT`) | `keyring.get_credential('BuildVMGuest', None)` |
|
||||
| Pester | `pytest` + `pytest-mock` |
|
||||
| PSScriptAnalyzer | `ruff` + `mypy --strict` |
|
||||
| `Write-Host` | `logging.getLogger(__name__).info(...)` |
|
||||
| `ConvertTo-Json` per stato job | `json.dumps()` su dataclass |
|
||||
| Workflow YAML | invariati in Fase A |
|
||||
| Script `.sh` in `gitea/burnin-dummy/` | invariati (girano nel guest Linux) |
|
||||
|
||||
- Python 3.11+ (Microsoft Store o python.org installer)
|
||||
- pacchetti: `pypsrp[credssp]`, `paramiko`, `keyring`, `pyyaml`, `click`
|
||||
(CLI), `rich` (output colorato), `pytest`, `ruff`, `mypy`
|
||||
- Tutti installabili in un `venv` isolato (`F:\CI\python\venv\`) →
|
||||
zero impatto sul Python di sistema.
|
||||
---
|
||||
|
||||
### 2.4 Compatibilità con act_runner
|
||||
## 4. Cosa NON viene portato in Python
|
||||
|
||||
act_runner invoca uno step `run:` con `shell: powershell` oggi. Cambia in:
|
||||
Gli script `template/` (`Prepare-*.ps1`, `Deploy-*.ps1`,
|
||||
`Install-CIToolchain-*.ps1`) restano in PowerShell:
|
||||
|
||||
```yaml
|
||||
- shell: cmd
|
||||
run: F:\CI\python\venv\Scripts\python.exe -m ci_orchestrator job ...
|
||||
- girano una tantum (ricostruzione template)
|
||||
- sono fortemente legati a Windows (autounattend.xml, registry, sysprep, WinRM enable)
|
||||
- gli script `Install-CIToolchain-WinBuild*.ps1` girano **dentro** il guest
|
||||
Windows e PS è il linguaggio nativo lì
|
||||
|
||||
In Fase B questi script restano richiamabili da host Linux con `pwsh` 7
|
||||
quando serve ricostruire un template Windows (operazione rara, anche manuale).
|
||||
|
||||
---
|
||||
|
||||
## 5. Strategia di migrazione: strangler fig in 4 step
|
||||
|
||||
Sequenza obbligata. Ad ogni step, gli script PS non ancora portati continuano
|
||||
a funzionare; la coesistenza è garantita dalla stessa CLI `python -m ci_orchestrator`
|
||||
chiamata internamente dagli script `.ps1` man mano che vengono "scavati".
|
||||
|
||||
### Step A1 — Bootstrap progetto + moduli core (`_Common`, `_Transport`)
|
||||
|
||||
Output:
|
||||
- `pyproject.toml`, package `src/ci_orchestrator/`
|
||||
- `venv` in `F:\CI\python\venv\`
|
||||
- moduli: `config.py` (env + TOML), `vmrun.py` (wrapper), `winrm.py` (pypsrp),
|
||||
`ssh.py` (paramiko), `credentials.py` (keyring), `backends/workstation.py`
|
||||
- protocollo `VmBackend` definito
|
||||
- test pytest per ognuno (mock `subprocess`, `paramiko`, `pypsrp`)
|
||||
|
||||
Validazione: `lint.yml` e `self-test.yml` continuano a passare; nuovi job
|
||||
pytest aggiunti al workflow `lint.yml`.
|
||||
|
||||
### Step A2 — Script "foglia" (no state condiviso con orchestratore)
|
||||
|
||||
Portare in Python (CLI subcommands `python -m ci_orchestrator <cmd>`):
|
||||
|
||||
- `Wait-VMReady` → `wait-ready`
|
||||
- `Remove-BuildVM` → `vm remove`
|
||||
- `Cleanup-OrphanedBuildVMs` → `vm cleanup`
|
||||
- `Watch-DiskSpace` → `monitor disk`
|
||||
- `Watch-RunnerHealth` → `monitor runner`
|
||||
- `Get-CIJobSummary` → `report job`
|
||||
|
||||
Per ognuno: il file `.ps1` viene sostituito da uno **shim** di 3 righe che
|
||||
chiama `python -m ci_orchestrator <cmd> ...`, così i call site esterni
|
||||
(scheduled tasks, ecc.) non si rompono.
|
||||
|
||||
### Step A3 — Pipeline di build
|
||||
|
||||
Portare in Python:
|
||||
|
||||
- `New-BuildVM` → `vm new`
|
||||
- `Invoke-RemoteBuild` → `build run`
|
||||
- `Get-BuildArtifacts` → `artifacts collect`
|
||||
|
||||
Stessa strategia shim per i `.ps1` esistenti.
|
||||
|
||||
### Step A4 — Orchestratore + switch workflow
|
||||
|
||||
Portare `Invoke-CIJob.ps1` → `python -m ci_orchestrator job`.
|
||||
Aggiornare `gitea/actions/local-ci-build/action.yml` per chiamare Python
|
||||
direttamente (non più via shim, per ridurre overhead startup).
|
||||
|
||||
A questo punto i `.ps1` shim restano come fallback; eliminarli al primo
|
||||
ciclo di pulizia successivo.
|
||||
|
||||
### Step trasversale A5 — Test e documentazione
|
||||
|
||||
Parallelo agli step A1-A4:
|
||||
- ogni feature portata ha test pytest che coprono almeno gli scenari
|
||||
documentati negli "errori frequenti" di `AGENTS.md` (#9, #10, #11, #12)
|
||||
- `AGENTS.md` aggiornato con sezione "Python development" (venv, stile,
|
||||
pytest, ruff)
|
||||
- `docs/ARCHITECTURE.md` aggiornato con il nuovo layout package
|
||||
- `README.md` aggiornato con setup Python
|
||||
|
||||
---
|
||||
|
||||
## 6. Layout repository post-Fase A
|
||||
|
||||
```
|
||||
src/ci_orchestrator/
|
||||
__init__.py
|
||||
__main__.py # entry point CLI (click)
|
||||
config.py # env vars + config.toml loader
|
||||
credentials.py # CredentialStore protocol + KeyringStore
|
||||
backends/
|
||||
__init__.py
|
||||
protocol.py # VmBackend Protocol
|
||||
workstation.py # WorkstationVmrunBackend
|
||||
transport/
|
||||
__init__.py
|
||||
winrm.py # pypsrp client wrapper
|
||||
ssh.py # paramiko client wrapper
|
||||
commands/
|
||||
job.py # ex Invoke-CIJob
|
||||
vm.py # new / remove / cleanup
|
||||
build.py # build run
|
||||
artifacts.py # collect
|
||||
wait.py # wait-ready
|
||||
monitor.py # disk / runner
|
||||
report.py # job summary
|
||||
tests/
|
||||
test_backends_workstation.py
|
||||
test_transport_winrm.py
|
||||
test_transport_ssh.py
|
||||
test_commands_job.py
|
||||
...
|
||||
pyproject.toml
|
||||
config.example.toml
|
||||
scripts/ # PS legacy (shim sottili durante migrazione)
|
||||
template/ # PS invariati (provisioning template)
|
||||
gitea/ # workflow + actions invariati
|
||||
```
|
||||
|
||||
oppure si lascia un wrapper `.ps1` minimale che chiama Python (più graduale).
|
||||
---
|
||||
|
||||
### 2.5 Rischi specifici
|
||||
## 7. Rischi e mitigazioni
|
||||
|
||||
| Rischio | Severità | Mitigazione |
|
||||
| -------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------- |
|
||||
| `pypsrp` ha edge case con prompt UAC / loopback HTTPS | Media | PoC isolato su `Wait-VMReady` equivalente prima di committare alla rewrite. |
|
||||
| `keyring` sotto SYSTEM account (act_runner service) può non vedere credenziali utente | Alta | Già un problema oggi con Credential Manager; stessa mitigazione (DPAPI machine scope o vault file). |
|
||||
| Perdita di know-how dei `#11`, `#12` di `AGENTS.md` durante refactor | Media | Riportare ogni "errore frequente" come **test pytest** prima di portare il codice. |
|
||||
| Doppio mantenimento durante la migrazione | Alta | Migrazione "big bang" per branch sconsigliata; usare strategia 2.6. |
|
||||
|
||||
### 2.6 Strategia di migrazione consigliata
|
||||
|
||||
**Strangler fig**, in 4 fasi:
|
||||
|
||||
1. Estrarre `_Common.psm1` + `_Transport.psm1` in `ci_orchestrator/transport.py`
|
||||
e `ci_orchestrator/vmrun.py`; mantenere gli script `.ps1` esistenti che
|
||||
chiamano Python via `python -c` per le primitive critiche. Validazione:
|
||||
workflow `lint.yml` e `self-test.yml` continuano a passare.
|
||||
2. Portare gli script "foglia" senza state condiviso: `Wait-VMReady`,
|
||||
`Remove-BuildVM`, `Cleanup-OrphanedBuildVMs`, `Watch-DiskSpace`,
|
||||
`Watch-RunnerHealth`. Ognuno con i suoi test pytest.
|
||||
3. Portare `New-BuildVM` + `Get-BuildArtifacts` + `Invoke-RemoteBuild`.
|
||||
4. Portare `Invoke-CIJob` (orchestratore) per ultimo, switchando il workflow
|
||||
YAML solo a quel punto.
|
||||
|
||||
Gli script di **template setup** (`template/Prepare-*.ps1`,
|
||||
`Deploy-*.ps1`, `Install-CIToolchain-*.ps1`) restano in PowerShell perché
|
||||
girano una tantum e sono fortemente legati a Windows
|
||||
(autounattend.xml, registry, sysprep). Convertirli ha ROI basso.
|
||||
| Rischio | Severità | Mitigazione |
|
||||
| ---------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `pypsrp` ha edge case con WinRM HTTPS self-signed | Media | PoC su `wait-ready` come primo deliverable di Step A1 prima di committare al resto. |
|
||||
| `keyring` sotto SYSTEM account (act_runner service) può non vedere credenziali utente | Alta | Già un problema oggi con Credential Manager; documentare l'uso di credenziali a livello machine (DPAPI machine scope su Win, file vault con `age` su Linux). |
|
||||
| Perdita di know-how degli "errori frequenti" `AGENTS.md` durante refactor | Media | Convertire ognuno (#9, #10, #11, #12) in un test pytest **prima** di rimuovere il `.ps1` corrispondente. |
|
||||
| Doppio mantenimento durante la migrazione | Alta | Strategia shim minimizza la finestra; `lint.yml` deve passare per **entrambi** i mondi (PSSA + ruff). |
|
||||
| Astrazione `VmBackend` over-engineered se Fase C non parte mai | Bassa | Una sola implementazione concreta + Protocol = ~50 righe extra; costo trascurabile. |
|
||||
| act_runner cattura male l'output Python (encoding UTF-8 vs cp1252 su Win) | Media | Forzare `PYTHONIOENCODING=utf-8` in `runner/config.yaml` env. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Stima volumi / sforzo (relativa)
|
||||
## 8. Definizione di "fatto" (Fase A)
|
||||
|
||||
| Fase | Indicatori dimensione | Complessità |
|
||||
| ----------------------------------------------------- | ------------------------------------ | ----------- |
|
||||
| F1 — Moduli `_Common` + `_Transport` | ~540 righe PS → ~600 righe Py + test | Media |
|
||||
| F2 — Script foglia (6 file) | ~1.500 righe PS | Bassa |
|
||||
| F3 — Build pipeline (3 file core) | ~2.000 righe PS | Media |
|
||||
| F4 — Orchestrator + switch workflow | ~800 righe PS | Alta |
|
||||
| F5 — Riscrittura test Pester → pytest | 4 file test esistenti + nuovi | Media |
|
||||
| F6 — Documentazione (AGENTS.md, README, docs/) | 24 file md | Bassa |
|
||||
|
||||
Le fasi F1→F4 devono essere sequenziali; F5 si fa in parallelo a ciascuna fase
|
||||
(test della fase prima del merge). F6 si fa a fine F4.
|
||||
|
||||
---
|
||||
|
||||
## 4. Pro / Contro
|
||||
|
||||
### Pro
|
||||
|
||||
- **Cross-platform di base**: rimuove il vincolo PS 5.1 (vedi Idea 2).
|
||||
- Ecosistema test/typing/lint più ricco (`pytest`, `mypy`, `ruff`).
|
||||
- Type hints + dataclass riducono la classe di bug `Set-StrictMode` non cattura.
|
||||
- Libreria `pypsrp` è attivamente manutenuta; `paramiko` standard de facto.
|
||||
- Più sviluppatori conoscono Python che PS 5.1.
|
||||
|
||||
### Contro
|
||||
|
||||
- **Costo migrazione alto** rispetto al beneficio se il sistema resta
|
||||
Windows-only e funziona già (oggi è in production-ready).
|
||||
- Doppio mantenimento per ~tutta la durata della migrazione.
|
||||
- `pypsrp` su Windows Server target richiede tuning (CredSSP, message
|
||||
encryption) — possibili sorprese non visibili oggi con WinRM nativo PS.
|
||||
- Gli `Install-CIToolchain-WinBuild2025.ps1` restano comunque in PS
|
||||
(girano nel guest Windows) → la codebase non sarà mai 100% Python.
|
||||
- Documentazione (`AGENTS.md`, `docs/BEST-PRACTICES.md`) tutta da riscrivere.
|
||||
|
||||
---
|
||||
|
||||
## 5. Decision checklist
|
||||
|
||||
Procedere **solo se** almeno 2 dei seguenti sono veri:
|
||||
|
||||
- [ ] È prevista l'Idea 2 (host Linux) o l'Idea 3 (ESXi) entro 6 mesi.
|
||||
- [ ] Si vogliono assumere/coinvolgere sviluppatori non-Windows.
|
||||
- [ ] Si pianifica integrazione con tool Python (es. Ansible per
|
||||
provisioning, librerie pyVmomi per ESXi).
|
||||
- [ ] Il debito tecnico di PS 5.1 (no async, no ternari, dipendenza da
|
||||
Credential Manager) sta bloccando feature concrete.
|
||||
|
||||
Se nessuna è vera, **non vale la pena**: investire piuttosto in test e
|
||||
osservabilità sul codice PS attuale.
|
||||
|
||||
---
|
||||
|
||||
## 6. Sinergia con Idee 2 e 3
|
||||
|
||||
- **Idea 2 (host Linux)**: la riscrittura Python è **utile ma non strettamente
|
||||
obbligata**. VMware Workstation Pro esiste nativamente per Linux con lo
|
||||
stesso `vmrun`, quindi il transport può restare identico (PS 7 su Linux
|
||||
può continuare a chiamare `vmrun`). Python rende comunque il porting più
|
||||
semplice se si valuta di passare a un hypervisor diverso (es. KVM con
|
||||
`libvirt`).
|
||||
- **Idea 3 (ESXi)**: `pyVmomi` (SDK ufficiale VMware per ESXi/vCenter) è
|
||||
**solo Python**. Equivalenti PowerShell sono PowerCLI (richiede
|
||||
PS 7+ moduli VMware.PowerCLI installabili anche su PS 5.1, ma con limiti).
|
||||
Andare su Python apre la strada al supporto ESXi in modo idiomatico.
|
||||
|
||||
**Raccomandazione**: se si vuole davvero perseguire Idee 2 o 3, la riscrittura
|
||||
Python diventa quasi obbligata. Se invece il sistema resta su Windows + VMware
|
||||
Workstation, la conversione è **opzionale** e non urgente.
|
||||
- [ ] Tutti gli script in `scripts/` portati a Python o ridotti a shim
|
||||
- [ ] `Invoke-CIJob.ps1` non più presente nei workflow YAML
|
||||
- [ ] `pytest` verde con coverage minima 70% su `src/ci_orchestrator/`
|
||||
- [ ] `ruff check` + `mypy --strict` puliti su tutto `src/`
|
||||
- [ ] `lint.yml` aggiornato: PSSA per file PS legacy + ruff/mypy per Python
|
||||
- [ ] Workflow `build-nsInnoUnp.yml` PASS su matrice Windows + Linux
|
||||
- [ ] Smoke test (`Test-Smoke.ps1` o equivalente Python) PASS
|
||||
- [ ] Capacity burn-in 4 job concorrenti PASS
|
||||
- [ ] `README.md`, `AGENTS.md`, `docs/ARCHITECTURE.md`, `docs/HOST-SETUP.md` aggiornati
|
||||
|
||||
Reference in New Issue
Block a user