Passa al contenuto principale

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:

  1. crea release/X.Y.Z da develop;
  2. aggiorna la versione in ogni manifest;
  3. fonde il branch di rilascio in master (--no-ff) e tagga vX.Y.Z;
  4. rifonde in develop ed elimina il branch di rilascio;
  5. esegue il push di master, develop e 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 # vNext in cima al file, come punti di una riga (cosa è cambiato più la superficie toccata).
  • Ogni # vNext deve contenere una checklist ## Pre-deploy e 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 # vNext in 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 è:

  1. scarica l'immagine, attendendo la build CI del commit HEAD del branch (timeout di default 20 minuti, ridefinibile con --ci-timeout <min>);
  2. avvia il container del colore inattivo;
  3. attende il suo health check;
  4. sposta su di esso l'instradamento Traefik;
  5. 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 --force per 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​

  1. Segui la checklist ## Post-deploy in ReleaseNotes.md.
  2. Salute: flo instance health <tenant> (database, API, disco, container), oppure interroga /health dall'esterno.
  3. Versione: conferma che il container in esecuzione riporti APP_VERSION e GIT_COMMIT_HASH attesi (flo instance ls, flo instance inspect <tenant>).
  4. Storico: flo deploy history <tenant> mostra la nuova voce; le notifiche di distribuzione riportano successo o fallimento.
  5. 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.
  6. Tieni a portata di mano il comando di rollback finché la finestra del canary non è chiusa.