L'integrazione e il rilascio continui, CI/CD, ribaltano la logica. I rilasci diventano piccoli, frequenti e automatizzati, ed è proprio questo a renderli sicuri.
Integrazione continua: un'unica linea principale, sempre funzionante
Integrazione continua significa che ogni sviluppatore unisce piccole modifiche al codice comune spesso, almeno una volta al giorno, e che ogni modifica viene compilata e testata automaticamente. I problemi emergono in pochi minuti, quando la modifica è ancora fresca nella memoria di chi l'ha fatta, e non settimane dopo in una fase di integrazione.
Gli ingredienti pratici:
- Branch di breve durata, uniti in fretta, invece di lunghe linee di lavoro parallele.
- Una build automatica che compila, impacchetta ed esegue i test a ogni modifica.
- La regola che la linea principale resti verde: quando la build si rompe, sistemarla viene prima di tutto.
- Code review su ogni modifica, abbastanza piccola da poter essere rivista davvero.
Rilascio continuo: sempre pronti ad andare in produzione
Il rilascio continuo (continuous delivery) estende la pipeline in modo che ogni modifica che supera i controlli sia pronta per la produzione: installata automaticamente negli ambienti di test, verificata e rilasciata con un unico passaggio ripetibile. Il deployment continuo fa un passo in più e rilascia in automatico. Quale dei due scegliere dipende dal contesto; negli ambienti regolamentati si mantiene spesso un'approvazione umana prima della produzione, ed è perfettamente compatibile con l'approccio.
Una pipeline tipica:
- Build e test unitari.
- Controlli statici: qualità del codice, vulnerabilità note nelle dipendenze, segreti inseriti per errore nel codice.
- Installazione in un ambiente di test creato dallo stesso codice infrastrutturale della produzione.
- Test di integrazione ed end-to-end.
- Approvazione, se prevista.
- Rilascio in produzione, con controlli automatici successivi.
La piramide dei test
I test automatici sono ciò che rende possibili rilasci frequenti, ma non tutti i test sono uguali. La piramide dei test è una guida utile:
- Molti test unitari alla base: veloci, precisi, verificano singole funzioni e regole.
- Meno test di integrazione nel mezzo: componenti insieme a un database vero, a una coda di messaggi, a un'API esterna o a un suo sostituto.
- Pochi test end-to-end in cima: i percorsi critici degli utenti attraverso l'interfaccia reale, come accedere, inserire un ordine, approvare una fattura.
I test end-to-end sono preziosi ma lenti e fragili; una suite che si basa soprattutto su di essi diventa un collo di bottiglia. L'obiettivo è una pipeline che dia una risposta affidabile in minuti, non in ore.
Per i sistemi esistenti senza test, si comincia scrivendo test attorno alle parti che si stanno per modificare. È così che la rete di sicurezza cresce dove serve, lo stesso principio della modernizzazione del software legacy un passo alla volta.
Ambienti e infrastruttura come codice
"In test funzionava" di solito significa che test e produzione sono diversi. Descrivere l'infrastruttura come codice (con strumenti come Terraform o OpenTofu, o con i template del provider cloud) rende gli ambienti riproducibili: le stesse definizioni creano test, staging e produzione, con differenze limitate a dimensioni e configurazione. Rende anche le modifiche all'infrastruttura verificabili come il codice, ed è parte di ogni migrazione in cloud che seguiamo.
Rilasciare senza paura
I rilasci piccoli riducono il rischio; alcune tecniche lo riducono ancora:
- I feature flag separano l'installazione del codice dall'attivazione di una funzionalità. Una novità si può accendere prima per gli utenti interni, poi per tutti, e spegnere senza un nuovo rilascio.
- I rilasci blue-green e canary fanno girare la nuova versione accanto alla vecchia e spostano il traffico gradualmente, con rollback automatico se gli errori aumentano.
- Modifiche al database in passi compatibili: si aggiunge la nuova colonna, si rilascia codice che usa entrambe, si migrano i dati, poi si elimina la vecchia. Ogni passo si può rilasciare e annullare da solo.
- Monitoraggio legato ai rilasci, così che una variazione di errori o tempi di risposta sia collegata al rilascio che l'ha causata.
Misurare se la delivery migliora
Il programma di ricerca DORA, oggi parte di Google Cloud, ha individuato quattro metriche che insieme descrivono le prestazioni nella consegna del software:
- Frequenza di rilascio: quante volte si va in produzione.
- Lead time delle modifiche: quanto impiega una modifica a raggiungere la produzione.
- Tasso di rilasci con problemi: la quota di rilasci che causa un problema in produzione.
- Tempo di ripristino: quanto in fretta si torna operativi quando qualcosa va storto.
La loro conclusione principale è che velocità e stabilità vanno insieme, non una contro l'altra. Misurate il vostro punto di partenza e seguite l'andamento nel tempo, invece di confrontarvi con altre organizzazioni.
Da dove partire
Automatizzate build e rilascio di un'applicazione da cima a fondo, aggiungete test attorno alla prossima modifica prevista e iniziate a misurare le quattro metriche. Ogni applicazione che sviluppiamo nel nostro servizio di software engineering nasce con questa pipeline fin dalla prima settimana, perché il vostro team erediti un processo di rilascio e non solo del codice.