Continuous Integration: cos'è l'integrazione continua

Chi lavora nel settore dello sviluppo di software conosce i problemi dell'integrazione: quando il codice nuovo è compilato, il compito assegnato è stato svolto e rimane solo da integrare il codice sorgente nel progetto generale, ecco che emergono i problemi. Per evitare che una lunga fase di sviluppo finisca in tragedia per problemi di compatibilità, molti team scelgono la Continuous Integration: questa prevede infatti che le modifiche vengano integrate nel progetto almeno una volta al giorno, se non di più.

La Continuous Integration, proprio come la Continuous Delivery, viene apprezzata soprattutto nello sviluppo agile di software. L'obiettivo di questo moderno metodo è quello di suddividere il lavoro in porzioni più piccole per rendere il processo stesso di sviluppo più efficiente e poter reagire con maggiore flessibilità alle modifiche. La Continuous Integration è stata nominata per la prima volta nella descrizione della metodologia agile Extreme Programming di Kent Beck. In linea di principio, tuttavia, l'idea dell'integrazione continua esisteva già in precedenza. Ad esempio, l'integrazione continua è importante anche per il metodo Booch.

In che cosa consiste la Continuous Integration?

L'integrazione continua offre una soluzione a scenari come questo: l'azienda sta lavorando a un progetto importante. Il cliente deve ricevere un software ampio e complesso. I singoli team sviluppano solo alcuni aspetti dell'applicazione mentre gli sviluppatori a loro volta programmano soltanto funzioni singole. Dopo mesi, se non anni, di lavoro, è arrivato il momento di unificare il tutto ed è qui che emergono i problemi. In casi come questo possono volerci altrettanti mesi per individuare e risolvere gli errori e unificare tutte le porzioni di codice prima di poter passare alle fasi finali di testing e deployment.

Con la Continuous Integration l'integrazione di un codice nuovo avviene molto prima e non quando tutti i collaboratori hanno già terminato il lavoro sulla propria parte. Gli sviluppatori infatti caricano il proprio codice ultimato una o più volte al giorno sulla mainline, ovvero il codice sorgente a cui hanno accesso tutti i programmatori. Dal momento che si tratta di porzioni di codice relativamente ridotte, anche l'integrazione richiede meno tempo. Uno sviluppatore dovrebbe impiegare qualche minuto per condividere il risultato del suo lavoro con il resto del team. Nel caso in cui venga individuato un errore è possibile identificarlo e risolverlo in modo relativamente veloce.

Definizione

La Continuous Integration (definita in italiano anche "integrazione continua") è una tecnica di sviluppo agile di software. Con questo metodo di integrazione gli sviluppatori integrano porzioni di codice finiti nell'applicazione anche più volte al giorno, piuttosto che integrarle tutte soltanto alla fine del progetto.

Procedura

In pratica la Continuous Integration funziona in questo modo: uno sviluppatore ha il compito di sviluppare una determinata funzione. Prima che cominci il lavoro di programmazione, deve scaricare la versione attuale del codice completo dell'applicazione, la cosiddetta mainline. Lo sviluppatore potrà ora lavorare su questa versione (chiamata anche Working Copy), che ha scaricato sul suo computer personale. Una volta terminato il suo lavoro, deve testare il programma, risolvere eventuali errori e caricare la nuova versione sulla mainline.

Bisogna ricordare, tuttavia, che lo sviluppatore non lavora da solo sul programma. Mentre lui ha apportato le sue modifiche, molto probabilmente i suoi colleghi avranno svolto altri compiti, quindi ciascun sviluppatore del team possiede una versione differente sul proprio computer. Anche la versione della mainline sarà sicuramente cambiata nel frattempo, fatto che costringe il programmatore a integrare tutte le modifiche innanzitutto nella sua Working Copy. Se a questo punto emerge un errore, dovrà risolverlo.

Solo allora il programmatore potrà aggiungere le sue modifiche alla mainline e testare nuovamente il programma. Se non emergono altri errori, che possono presentarsi nel caso in cui non abbia aggiornato correttamente la sua Working Copy, la procedura è conclusa e lo sviluppatore può dedicarsi al compito successivo.

Principi

Chi vuole seguire questo metodo deve rispettare alcune regole: nella maggior parte dei casi i programmatori abbracciano i principi sviluppati da Martin Fowler (anch'egli sviluppatore di software) per una Continuous Integration di successo. Innanzitutto devono assicurarsi che tutti i collaboratori lavorino sullo stesso livello e che non si crei confusione a causa di deviazioni dalle regole.

Una sola sorgente

Sembra ovvio, ma questo è uno dei fattori più importanti: tutti i membri del team devono utilizzare la stessa sorgente (lo stesso repository) quando lavorano sul codice. Questo non vale soltanto per il codice sorgente di per sé, perché per garantire il corretto funzionamento di un'applicazione sono necessari anche altri elementi come le banche dati. Anche queste devono essere raggruppate in un'unica posizione. Per questo Martin Fowler consiglia di strutturare un repository in modo tale che anche uno sviluppatore con un computer nuovo possa collaborare e che tutti i file necessari siano depositati in una posizione centrale.

Consiglio

Per garantire un funzionamento efficiente di una sorgente di questo tipo si consiglia un sistema di gestione delle versioni. Con un software adeguato è molto più facile tenere sotto controllo anche un numero elevato di collaboratori.

Build automatizzati

Per creare un programma funzionante dal codice sorgente è necessario compilarlo, attualizzare le banche dati e spostare i file nelle posizioni corrette. Questo processo può essere automatizzato. Idealmente dovrebbe essere possibile eseguire un processo di build con un solo comando.

Sistemi di testing automatico

L'integrazione di meccanismi di testing nel processo di build consente al team di automatizzare, e dunque velocizzare ulteriormente, la Continuous Integration. Proprio come il processo di build, anche i test devono poter essere eseguiti nel modo più efficiente possibile (la cosa migliore è implementare una serie di meccanismi di controllo diversi).

N.B.

Il testing è l'elemento centrale del metodo agile Test Driven Development (TDD). Secondo Martin Fowler, tuttavia, non è necessario eseguire il TDD completamente per poter adottare la Continuous Integration.

Integrazione giornaliera

L'integrazione continua può funzionare solo se tutti i membri del team condividono il sistema. È sufficiente che un membro del team non integri costantemente il suo codice nella mainline perché tutti gli altri partano da presupposti sbagliati. Tutti presumono di lavorare su un sistema stabile, ma se uno di loro non dovesse condividere il suo codice per un periodo prolungato (più di un giorno), la ricerca di errori può diventare una vera sfida. Come accade spesso nella vita, anche nella Continuous Integration la comunicazione gioca un ruolo fondamentale, infatti se tutti gli sviluppatori restano aggiornati sul lavoro degli altri, molte difficoltà possono essere prevenute.

Mainline funzionante

Il codice di programmazione contenuto nella mainline deve essere sempre testato e funzionante. Per questo ogni sviluppatore deve integrare il suo codice unicamente in questo ramo principale e non in uno secondario. In tal senso ogni sviluppatore deve inoltre verificare che il suo codice sia funzionante quindi, dopo l'integrazione, dovrà testare nuovamente il codice insieme al build. Se vengono riscontrati degli errori dovrà risolverli. In questo modo viene garantito che il codice è privo di difetti.

Riparazione immediata

Nella Continuous Integration è di fondamentale importanza che la mainline non contenga mai una versione difettosa. Questo significa per gli sviluppatori che la riparazione non deve mai essere rimandata. Secondo Martin Fowler il fatto che i build non funzionino e che sia necessario rivedere il codice non è un problema, ma il sistema dell'integrazione continua prevede una riparazione immediata. Tutti gli sviluppatori devono infatti poter contare sul fatto che il codice nella mainline sia funzionante, altrimenti l'intero team effettua programmazioni in sistemi instabili innescando una valanga di errori.

Tempi brevi di integrazione

La vera e propria integrazione del codice (incluso il testing) deve avvenire piuttosto velocemente. L'Extreme Programming (XP) prevede appena 10 minuti per questo compito. Considerando che uno sviluppatore effettua in genere più di un'integrazione al giorno, tempi di build più lunghi provocherebbero delle perdite di tempo consistenti. Per questo motivo è essenziale adottare meccanismi che permettano di velocizzare il processo.

Per poter raggiungere tempi così ridotti bisogna anche accettare il fatto che non tutti i test potranno essere eseguiti direttamente. Per questo viene adottato un sistema a due fasi: nella prima fase, che si svolge durante il lavoro quotidiano, si eseguono test in modo da ridurre i tempi di build. La seconda fase di test, invece, dura diverse ore e prevede anche verifiche più approfondite.

Ambiente di prova copiato

Si consiglia generalmente di eseguire i test in un ambiente esterno e sicuro, che deve comunque essere configurato esattamente come l'ambiente di produzione. Questo può talvolta diventare abbastanza dispendioso, dal momento che la macchina deve essere configurata in maniera identica. La virtualizzazione di interi computer consente tuttavia di ridurre sempre di più questi costi.

Accesso semplice

Tutti i collaboratori devono poter accedere facilmente all'ultima versione ed essere in grado di eseguire il programma. Garantire questa condizione non presenta difficoltà particolari: considerando che la Continuous Integration prevede in ogni caso che tutti i file vengano depositati in un repository, è sufficiente assicurare che tutti conoscano questa posizione. I motivi a favore sono diversi: i tester possono iniziare test aggiuntivi mentre il processo di programmazione è ancora in corso, gli stakeholder possono utilizzare i file eseguibili per dimostrazioni e i manager della qualità possono controllare le cifre.

Comunicazione chiara e comprensibile

Sapere chi ha introdotto quali modifiche è tanto importante quanto garantire l'accesso di tutti i collaboratori al codice sorgente e al file eseguibile. Come parte integrante della comunicazione, è fondamentale che gli sviluppatori si informino a vicenda su chi sta lavorando su quale processo di build. A tale scopo alcuni team sfruttano display separati o raffigurazioni visive che evidenzino che si è attualmente impegnati con un’integrazione.

Suddivisione automatizzata

Infine è fondamentale automatizzare la suddivisione del software. I file devono essere trasferiti da un ambiente all'altro, passaggio che può richiedere molto tempo. Per questo è consigliato l'utilizzo degli script che automatizzano e velocizzano questo processo.

Vantaggi e svantaggi della Continuous Integration

Nonostante le sue caratteristiche positive, nel lavoro quotidiano la Continuous Integration non offre solo dei vantaggi. Infatti, è vero che consente di evitare un'ampia e prolungata fase di integrazione alla fine del processo e permette di risolvere i problemi tempestivamente, ma per un team ben coordinato l'adattamento alla Continuous Integration può risultare difficile. In questi casi il metodo può persino provocare l'effetto contrario e risultare più dispendioso in termini di tempo.

Vantaggi Svantaggi
Individuazione precoce degli errori Adattamento a processi nuovi
Feedback continuo Richiede server e ambienti aggiuntivi
Nessun sovraffaticamento a causa di un'unica grande fase di integrazione alla fine Richiede processi di testing adeguati
Annotazione precisa delle modifiche Possono crearsi code se più sviluppatori desiderano integrare i propri codici contemporaneamente
Disponibilità costante della versione attuale e funzionante  
Promuove il lavoro progressivo  

Panoramica degli strumenti di Continuous Integration

In linea di principio è possibile gestire l'integrazione continua anche senza strumenti specifici, dato che tutte le fasi di lavoro possono essere eseguite anche manualmente. Questo approccio richiederebbe comunque molta disciplina e un impegno ancora maggiore. L'utilizzo di strumenti appositi può dunque semplificare notevolmente il lavoro. Questi strumenti in genere mettono a disposizione un server e aiutano nel building e nel controllo delle versioni.

  • Jenkins: si tratta di un programma molto popolare scritto in linguaggio Java, nato come alternativa di Hudson, il cui sviluppo è stato interrotto. Questo software open source lavora con diversi strumenti di building e sistemi di gestione delle versioni.
  • Travis CI: questo strumento per l'integrazione continua è così apprezzato perché è perfettamente compatibile con GitHub. Il repository online informa Travis sulle modifiche del codice. Il software è disponibile gratuitamente per progetti open source o in una versione a pagamento per tutti gli altri utilizzi.
  • Bamboo: il server Bamboo consente agli sviluppatori di svolgere l'integrazione, il deployment e la gestione delle release. Il produttore Atlassian offre il software sotto forma di piattaforma web basata su Java. Bamboo è molto apprezzato dagli sviluppatori per l'automatizzazione ed è compatibile con diversi strumenti di building. Il software, solitamente a pagamento, è disponibile anche gratuitamente per i progetti open source.
  • Gitlab CI: GitLab offre un proprio programma per l'integrazione continua, compatibile con la gestione nota delle versioni. La pipeline può essere personalizzata e adattata a ogni singolo progetto. GitLab supporta inoltre CI Docker.
  • CircleCI: di questo programma per la Continuous Integration esistono due versioni differenti. È possibile scegliere una versione direttamente nel Cloud dell'operatore o creare un proprio server locale per il suo utilizzo.
  • CruiseControl: sviluppato originariamente da ThoughtWorks (un'azienda incentrata su Martin Fowler), oggi CruiseControl è diventato un progetto indipendente. Il software gratuito è basato su Java ed è dunque indipendente dalle piattaforme. Tra l'altro CruiseControl offre agli sviluppatori una dashboard (un proprio sito Internet) sul quale è possibile verificare lo stato dei build.
  • Codeship: l'obiettivo di Codeship è offrire agli sviluppatori una soluzione semplice per la Continuous Integration. Grazie alla tecnologia basata su container, è molto semplice creare automatismi. L'azienda offre a tale scopo due versioni: Basic e Pro.
  • TeamCity: il software commerciale TeamCity punta particolarmente sull'interoperabilità con altri strumenti. Già nella versione standard vengono supportati molti programmi, ma questa gamma può essere ulteriormente ampliata mediante i plug-in. Una particolarità sta senz'altro nel Pre-Tested Commit. TeamCity verifica autonomamente il codice appena compilato ancora prima dell'integrazione nella mainline e segnala eventuali errori allo sviluppatore.
N.B.

Nel nostro articolo di approfondimento potete scoprire di più sui vantaggi e svantaggi dei singoli strumenti per la Continuous Integration.

Per offrirti una migliore esperienza di navigazione online questo sito web usa dei cookie, propri e di terze parti. Continuando a navigare sul sito acconsenti all’utilizzo dei cookie. Scopri di più sull’uso dei cookie e sulla possibilità di modificarne le impostazioni o negare il consenso.