Tecnologia DevOps: integrazione continua

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

I sistemi software sono complessi e una modifica apparentemente semplice e indipendente a un singolo file può avere effetti collaterali indesiderati sul sistema complessivo. Quando un numero elevato di sviluppatori lavora su sistemi correlati, coordinare gli aggiornamenti del codice è un problema difficile e le modifiche da sviluppatori diversi possono essere incompatibili.

Per risolvere questi problemi è stata creata la pratica dell'integrazione continua (CI). CI segue il principio secondo il quale, se qualcosa richiede molto tempo ed energia, è necessario applicarlo più spesso, rendendolo meno doloroso. Con la creazione di cicli di feedback rapidi e l'assicuramento degli sviluppatori che lavorano in piccoli batch, CI consente ai team di produrre software di alta qualità, ridurre il costo per lo sviluppo e la manutenzione continui del software e aumentare la produttività dei team.

Come implementare CI

Quando la tua organizzazione adotta CI, i tuoi sviluppatori integrano tutto il lavoro nella versione principale del codebase (noto come trunk, main o mainline) a intervalli regolari. La ricerca (DORA) DevOps Research and Assessment (PDF) mostra che i team hanno un rendimento migliore quando gli sviluppatori uniscono il loro lavoro nel trunk almeno quotidianamente. Per verificare che le modifiche non apportino bug di regressione, viene eseguito un insieme di test automatici prima e dopo l'unione. Se questi test automatici non riescono, il team interrompe le operazioni eseguite per risolvere immediatamente il problema.

CI garantisce che il software sia sempre in stato di funzionamento e che le filiali degli sviluppatori non differiscono in modo significativo dal trunk. I vantaggi di CI sono significativi: la ricerca (PDF) dimostra che porta a una frequenza di deployment più elevata, a sistemi più stabili e a software di qualità superiore.

Gli elementi chiave per implementare correttamente l'integrazione continua sono i seguenti:

  • Ogni commit dovrebbe attivare una build del software.
  • Ogni commit dovrebbe attivare una serie di test automatici che forniscono feedback in pochi minuti.

Per implementare questi elementi, hai bisogno di:

  • Un processo di compilazione automatizzato. Il primo passaggio per la CI consiste nello creare uno script automatico che crei pacchetti di cui sia possibile eseguire il deployment in qualsiasi ambiente. I pacchetti creati dalla build CI devono essere autorevoli e utilizzati da tutti i processi downstream. Queste build devono essere numerate e ripetibili. Il processo di compilazione deve essere eseguito almeno una volta al giorno.
  • Una suite di test automatizzati. Se non ce l'hai, inizia scrivendo un paio di test di accettazione (unità di misura) per coprire la funzionalità di alto valore del tuo sistema. Assicurati che i test siano affidabili. In questo modo, quando si verifica un errore, sai che esiste un problema serio e che, quando li superano, hai la certezza che non ci siano problemi gravi con il sistema. Assicurati che tutte le nuove funzionalità siano coperte dai test. Questi test dovrebbero essere eseguiti rapidamente, per fornire agli sviluppatori il feedback il prima possibile. I test dovrebbero essere eseguiti correttamente almeno una volta al giorno. In definitiva, se hai dei test di prestazioni e accettazione, gli sviluppatori dovrebbero ricevere feedback ogni giorno.
  • Un sistema CI che esegue la build e i test automatici a ogni check-in. Il sistema dovrebbe anche rendere lo stato visibile al team. Puoi divertirti un po': ad esempio, puoi utilizzare klaxon o semafori per indicare quando la build è inaccessibile. Non utilizzare notifiche email: molte persone ignorano le notifiche email o creano un filtro che nasconde le notifiche. Le notifiche in un sistema di chat sono un modo migliore e più popolare per raggiungere questo risultato.

L'integrazione continua, come definita da Kent Beck e dalla community di programmazione estrema in cui il termine è stato generato, include anche altre due pratiche, che sono anche predittive di prestazioni di distribuzione del software più elevate:

CI richiede test delle unità automatizzate. Questi test dovrebbero essere abbastanza completi da darti la certezza che il software funzioni come previsto. Anche i test devono essere eseguiti in pochi minuti o meno. Se l'esecuzione dei test delle unità automatizzate richiede più tempo, gli sviluppatori non li eseguiranno spesso. Se i test non vengono eseguiti raramente, un errore di test può avere origine da molte modifiche diverse, rendendo difficile il debug. I test eseguiti raramente sono difficili da mantenere.

La creazione di suite gestibili di test automatici delle unità è complessa. Un buon modo per risolvere questo problema è fare pratica con lo sviluppo basato su test (TDD), in cui gli sviluppatori scrivono test automatici che inizialmente non vanno a buon fine, prima di implementare il codice per il superamento dei test. TDD presenta diversi vantaggi, uno dei quali è che garantisce agli sviluppatori la scrittura di codice modulare e facile da testare, riducendo il costo di manutenzione delle suite di test automatizzate risultanti. Molte organizzazioni non dispongono di suite gestibili di test automatici delle unità e, nonostante questo approccio, non esercitano ancora il TDD.

Obiezioni a CI

Come descritto in precedenza, CI è talvolta considerata una pratica controversa. CI richiede agli sviluppatori di suddividere le funzionalità di grandi dimensioni e altre modifiche in passaggi più piccoli che possono essere integrati di frequente nel trunk. Si tratta di un cambiamento per gli sviluppatori che non sono abituati a lavorare in questo modo. Inoltre, quando i team passano all'utilizzo di piccoli passaggi, il completamento delle funzionalità di grandi dimensioni potrebbe richiedere più tempo. Tuttavia, in generale, non vuoi ottimizzare la velocità con cui gli sviluppatori possono dichiarare una funzionalità di grandi dimensioni come completata in un ramo. Preferisci invece essere in grado di esaminare le modifiche, integrarle, testarle e implementarle il più rapidamente possibile. Questo processo si traduce in uno sviluppo e una distribuzione del software più rapidi e stabili (PDF) quando le modifiche sono piccole e autonome e i rami in cui risiedono sono di breve durata. Inoltre, lavorare in piccoli batch fa sì che gli sviluppatori ricevano regolarmente feedback sull'impatto del proprio lavoro sul sistema nel suo complesso, da altri sviluppatori, tester e clienti, nonché da test automatici delle prestazioni e della sicurezza. Questo, a sua volta, rende più facile e veloce rilevare, assegnare una priorità e risolvere eventuali problemi.

Nonostante queste obiezioni, aiutare i team di sviluppo software a implementare l'integrazione continua dovrebbe essere la priorità numero per qualsiasi organizzazione che voglia iniziare il percorso di distribuzione continua.

Errori comuni

Ecco alcuni errori comuni che impediscono un'ampia adozione di CI:

  • Non inserire tutto nel repository del codice. Tutto ciò che è necessario per creare e configurare l'applicazione e il sistema deve essere nel tuo repository. Questo potrebbe sembrare fuori ambito di CI, ma è una base importante.
  • Non automatizzare il processo di compilazione. I passaggi manuali creano opportunità per gli errori e lasciano i passaggi senza documenti.
  • Non attivano test rapidi a ogni modifica. Sono necessari test end-to-end completi, ma è importante anche eseguire dei test rapidi (generalmente test di unità) per consentire un feedback rapido.
  • Non correggi immediatamente le build inaccessibili. Un obiettivo chiave di CI è avere una build stabile da cui tutti possono sviluppare. Se la build non può essere corretta in pochi minuti, la modifica che ha causato l'interruzione della build deve essere identificata e ripristinata.
  • L'esecuzione dei test richiede troppo tempo. L'esecuzione dei test non dovrebbe richiedere più di qualche minuto, con un limite massimo di circa 10 minuti secondo la ricerca di DORA (PDF). Se la tua build richiede più tempo, dovresti migliorare l'efficienza dei tuoi test, aggiungere più risorse di calcolo in modo da eseguirle in parallelo o suddividere i test con tempi di esecuzione più lunghi in una build separata utilizzando il pattern di pipeline di deployment.
  • Non vengono unite abbastanza spesso nel trunk. Molte organizzazioni eseguono test e build automatizzati, ma non applicano un'unione giornaliera nel trunk. Questo si traduce in rami di lunga durata molto più difficili da integrare e in lunghi cicli di feedback per gli sviluppatori.

Modi per misurare CI

I concetti di CI descritti in precedenza descrivono i modi per misurare l'efficacia di CI nei tuoi sistemi e nell'ambiente di sviluppo, come mostrato nella tabella seguente. La raccolta di queste metriche ti consente di ottimizzare i tuoi processi e gli strumenti per raggiungerli. Ciò porta a migliori prassi CI e a ciclo di feedback più breve per i tuoi sviluppatori.

Fattori da sottoporre a test Che cosa misurare
Le commit del codice attivano una build del software La percentuale di commit del codice che risultano in una build del software senza interventi manuali.
Le commit del codice attivano una serie di test automatici La percentuale di commit del codice che danno luogo a una suite di test automatici eseguiti senza intervento manuale.
Build e test automatici vengono eseguiti correttamente ogni giorno La percentuale di build automatizzate e la percentuale di test automatici eseguiti correttamente ogni giorno.
Le build attuali sono disponibili per i tester a fini di test esplorativo La disponibilità delle build per i tester, o viceversa, cioè l'indisponibilità delle build per i tester.
Gli sviluppatori ricevono feedback ogni giorno dai test di accettazione e delle prestazioni La disponibilità di feedback per gli sviluppatori dall'accettazione e dai test sulle prestazioni, ovvero la percentuale di test che forniscono il feedback disponibile agli sviluppatori entro un giorno.
Le build non funzionanti vengono corrette immediatamente Il tempo necessario per eseguire l'interruzione della build e per risolvere il problema, con un check-in che risolve il problema o ripristinando la modifica dell'interruzione.

Passaggi successivi