Processo di rilascio
I rilasci di Flo seguono un Gitflow da develop a master, quindi distribuiscono l'immagine risultante sui tenant con la CLI blue-green. Questa pagina copre lo schema di versione, il runbook delle note di rilascio, i percorsi di distribuzione, la modalità manutenzione, il rollback e la verifica post-distribuzione.
Schema di versione
Le versioni di rilascio sono semver X.Y.Z; flo release create rifiuta qualsiasi altro formato.
flo release create 1.38.0 # branch di rilascio -> master + tag v1.38.0 -> ritorno su develop
flo release create 1.38.0 --no-push # come sopra, senza push verso il remote
Il comando richiede un working tree pulito, che il branch corrente sia develop e che il tag vX.Y.Z non esista ancora. Quindi:
- crea
release/X.Y.Zdadevelop; - aggiorna la versione in ogni manifest;
- fonde il branch di rilascio in
master(--no-ff) e taggavX.Y.Z; - rifonde in
developed elimina il branch di rilascio; - esegue il push di
master,develope dei tag (saltato con--no-push).
I file di versione sincronizzati sono Flo.FE/package.json, cli/package.json, cli/package-lock.json, Flo.BE/Flo.BE.csproj e i tre file Flo.FE/src/environments/environment*.ts.
Tra un rilascio e l'altro, develop porta una versione con suffisso di build: <major>.<minor>.<patch>-<build> (ad esempio 1.37.0-501). Il suffisso è un contatore di build che non regredisce mai; un container in esecuzione lo espone come APP_VERSION insieme al GIT_COMMIT_HASH incorporato.
flo release check (eseguito sui branch release/*) valida i controlli di processo: la struttura delle note di rilascio, un punto - Release X.Y.Z: ... sotto # vNext e l'assenza di artefatti SDD sul branch di rilascio.
Note di rilascio
ReleaseNotes.md nella radice del repository è obbligatorio prima di ogni commit o rilascio.
- Il lavoro non ancora rilasciato finisce sotto
# vNextin cima al file, come punti di una riga (cosa è cambiato più la superficie toccata). - Ogni
# vNextdeve contenere una checklist## Pre-deploye una## Post-deploy: il runbook che l'operatore segue attorno alla distribuzione. - Gli hotfix aggiungono un blocco
# hotfix/<nome> (AAAA-MM-GG)sotto# vNext. - Chiudere un rilascio trasforma il contenuto accumulato di
# vNextin un blocco datato# vX.Y.Z (AAAA-MM-GG); i rilasci più recenti restano in cima.
Le checklist vanno scritte come passi reali, non come changelog: variabili d'ambiente da impostare prima della distribuzione, migrazioni una tantum che non girano all'avvio, controlli su disco e quote, ordine dei canary, verifica di salute e versione, smoke check e comando di rollback. Se un rilascio non richiede nulla di manuale, dirlo esplicitamente (ad esempio "nessun passo manuale; le migrazioni EF girano all'avvio").
Distribuzione
Single-tenant (Docker Compose e Nginx)
Segui Distribuzione Single-Tenant. Un aggiornamento è un git pull seguito dallo script di distribuzione:
cd ~/Flo
git pull
./deploy.sh --lite # ricompila con la cache
./deploy.sh --rebuild # ricompilazione completa senza cache
--force ricrea i container per aggiornare le configurazioni, --restart riavvia il container dell'app (rieseguendo i seeder) e --all avvia ogni servizio dopo uno stop completo.
Multi-tenant (CLI blue-green)
Segui CLI Multi-Tenant. Una distribuzione di produzione è:
flo --vps production deploy <tenant> --branch master -y
La sequenza blue-green è:
- scarica l'immagine, attendendo la build CI del commit HEAD del branch (timeout di default 20 minuti, ridefinibile con
--ci-timeout <min>); - avvia il container del colore inattivo;
- attende il suo health check;
- sposta su di esso l'instradamento Traefik;
- mantiene il vecchio container in esecuzione come standby HA (nessuno stop).
Se l'health check fallisce, il registro del tenant non viene commutato e il container precedentemente attivo continua a servire traffico. Un avvio fallito di un'istanza di test a container singolo lascia quell'istanza ferma finché non viene ridistribuita un'immagine nota-buona.
Regole per i tenant live:
--branch masterè obbligatorio. Un branch di sviluppo su un tenant live viene rifiutato, a meno che l'operatore passi--forceper quella specifica operazione.- Il preflight remoto delle risorse blocca la distribuzione quando l'host manca di margine di memoria o spazio disco; non esiste flag di bypass.
--no-wait-ciè solo per emergenze: scarica qualsiasi immagine già presente nel registry e potrebbe distribuire un commit obsoleto.- Imposta le nuove variabili d'ambiente prima della distribuzione; un rilascio che legge una variabile mancante può mandare in crash-loop il nuovo container.
- I tenant arruolati in DR sincronizzano anche l'immagine immutabile sullo standby dopo il cutover. Una sincronizzazione fallita riporta "primary attivo, DR non pronta" e può essere ritentata con
flo failover sync-image <tenant>.
Rilascio sulla flotta
flo release deploy 1.38.0 # ogni tenant di produzione, in sequenza
flo release deploy --no-backup # salta il backup pre-distribuzione per tenant
flo release deploy risolve ogni tenant con location: production dall'indice dei tenant, quindi distribuisce master su ciascuno uno alla volta con backup pre-distribuzione del database (attivo di default) e health check per tenant. Si ferma al primo fallimento. È un comando di orchestrazione locale, non una forma remota --vps.
Per un rollout manuale sulla flotta, inizia con un canary a basso rischio e osserva la salute tra un tenant e l'altro.
Modalità manutenzione
La modalità manutenzione può essere commutata live, senza riavvio del container:
flo --vps production instance maintenance <tenant> status
flo --vps production instance maintenance <tenant> on -y
flo --vps production instance maintenance <tenant> off
Il comando chiama l'API di manutenzione dentro il container (/api/v1/maintenance/mode) su ogni backend del tenant, autenticandosi con la chiave di manutenzione del tenant. La variabile d'ambiente MAINTENANCE_MODE resta il default al boot; l'API la sovrascrive per il processo in esecuzione. Con la manutenzione attiva, le API protette rispondono 503 con errors.general.maintenanceMode, mentre gli endpoint di manutenzione restano raggiungibili. Attivare la manutenzione richiede conferma, salvo -y. Quando MON controlla il tenant, l'attivazione è bloccata finché flo failover auto disarm non è completato.
Il comando verifica lo stato risultante su ogni backend. Se la verifica fallisce, ripristina lo stato precedente; se fallisce anche quello, ferma i backend per bloccare il traffico, e la situazione va trattata come incidente operativo.
Su un'installazione single-tenant con Compose, chiama lo stesso endpoint dall'interno del container. La CLI lo fa con:
docker exec <container> wget -q -O- \
--header='X-Maintenance-Key: <key>' \
'http://localhost:10001/api/v1/maintenance/mode'
Rollback
flo deploy rollback <tenant> -y
Il rollback riporta l'instradamento Traefik sul colore precedente: nessuna ricompilazione, quasi istantaneo. Entrambi i container restano in esecuzione e il rollback è registrato nello storico delle distribuzioni. Richiede un previousColor (almeno una precedente distribuzione blue-green). Le istanze di test a container singolo non hanno standby e rifiutano il rollback; ridistribuisci invece l'immagine precedente (flo deploy <tenant> --tag <immagine-precedente>).
flo deploy history <tenant> # distribuzioni e rollback: branch, commit, immagine, colore
flo deploy upgrade <tenant> # scarica l'ultima immagine di default e ridistribuisci
Verifica post-distribuzione
- Segui la checklist
## Post-deployinReleaseNotes.md. - Salute:
flo instance health <tenant>(database, API, disco, container), oppure interroga/healthdall'esterno. - Versione: conferma che il container in esecuzione riporti
APP_VERSIONeGIT_COMMIT_HASHattesi (flo instance ls,flo instance inspect <tenant>). - Storico:
flo deploy history <tenant>mostra la nuova voce; le notifiche di distribuzione riportano successo o fallimento. - Tenant DR: verifica la parità delle immagini sullo standby e ritenta con
flo failover sync-image <tenant>se la sincronizzazione post-cutover è fallita. Vedi Failover e Disaster Recovery. - Tieni a portata di mano il comando di rollback finché la finestra del canary non è chiusa.