Integrazione continua

Da Wikipedia, l'enciclopedia libera.

Nell'ingegneria del software, l'integrazione continua (continuous integration in inglese, spesso abbreviato in CI) è una pratica che si applica in contesti in cui lo sviluppo del software avviene attraverso un sistema di versioning. Consiste nell'allineamento frequente (ovvero "molte volte al giorno") dagli ambienti di lavoro degli sviluppatori verso l'ambiente condiviso (mainline).[1] Il concetto è stato originariamente proposto nel contesto dell'extreme programming (XP), come contromisura preventiva per il problema dell'"integration hell" (le difficoltà dell’integrazione di porzioni di software sviluppati in modo indipendente su lunghi periodi di tempo e che di conseguenza potrebbero essere significativamente divergenti). Il CI può essere considerato come una estremizzazione di idee già presenti in altre metodologie precedenti all’XP, per esempio il metodo Booch.

Il CI è stato originariamente concepito per essere complementare rispetto ad altre pratiche, in particolare legate al Test Driven Development (sviluppo guidato dai test, TDD). In particolare, si suppone generalmente che siano stati predisposti test automatici che gli sviluppatori possono eseguire immediatamente prima di rilasciare i loro contributi verso l’ambiente condiviso, in modo da garantire che le modifiche non introducano errori nel software esistente. Per questo motivo, il CI viene spesso applicato in ambienti in cui siano presenti sistemi di build automatico e/o esecuzione automatica di test, come Jenkins. Tuttavia, l’identificazione del CI con l’uso di strumenti di questo tipo, frequente in letteratura, è scorretta: di per sé, la pratica del CI può essere applicata anche a prescindere da sistemi di testing automatico.

Teoria[modifica | modifica sorgente]

Prima di effettuare una modifica sul codice sorgente, uno sviluppatore prende una copia del codice corrente sulla quale lavorare. Man mano che gli altri sviluppatori fanno delle modifiche sul repository, la copia smette di rappresentare il codice del repository. Le modifiche non si riflettono unicamente sul codice, ma anche sulle librerie ed altre risorse che possono creare dipendenze e potenziali conflitti.

Più è lungo il tempo durante il quale un branch di codice rimane scaricato, maggiore è il rischio di conflitti di integrazione quando il branch viene reintegrato nel repository. Quando gli sviluppatori vogliono sottomettere il codice, devono prima aggiornare le proprie copie locali del codice con i cambiamenti che sono stati fatti al repository dal momento in cui loro hanno aggiornato la copia locale. Più modifiche sono state fatte e più lavoro è necessario fare prima di sottomettere le proprie modifiche.

È possibile che il repository sia diventato così diverso dalla copia locale dello sviluppatore che il tempo necessario per integrare le proprie modifiche con quelle fatte dagli altri supera il tempo necessario a fare le modifiche. Questo fenomeno viene descritto come inferno dell'integrazione (integration hell in inglese) o inferno dei merge (merge hell). In uno scenario estremamente negativo, gli sviluppatori potrebbero dover annullare le proprie modifiche e rifare le proprie modifiche da capo.

L'integrazione continua è un processo che consiste nell'integrare presto e spesso, limitando le possibilità dell'inferno dell'integrazione. La pratica cerca di minimizzare il lavoro inutile e risparmiare tempo.

Principî[modifica | modifica sorgente]

Di seguito vengono riportati i principî introdotti da Martin Fowler[2] che permettono di svolgere l'integrazione continua.

Mantieni un repository del codice sorgente[modifica | modifica sorgente]

Questo elemento è propedeutico a tutti gli altri principi, perché senza avere un repository del codice è impossibile automatizzare il build ed i test.

Automatizza il build[modifica | modifica sorgente]

Per build si intende il processo che trasforma il codice sorgente in un artefatto. Deve essere possibile eseguire la compilazione e la creazione dei pacchetti da mettere sui server in modo completamente automatizzato, senza alcun intervento umano.

Rendi il build auto-testante[modifica | modifica sorgente]

Ogni volta che il codice sorgente viene buildato ed impacchettato, è importante che vengano eseguiti dei test sul sorgente affinché la qualità del codice venga tenuta sotto controllo ed eventuali bug vengano scoperti il prima possibile.

Tutti eseguono commit alla baseline tutti i giorni[modifica | modifica sorgente]

È inutile buildare e testare il sorgente se gli sviluppatori sviluppano codice sui propri computer senza sincronizzarsi spesso col codice scritto da altri.

Ogni commit fa partire una build[modifica | modifica sorgente]

Ogni modifica al codice sorgente condiviso potrebbe generare dei bug e quindi compilare e testare subito dà la possibilità di intervenire immediatamente su eventuali bug.

Questo principio è importante a seguito di un altro principio, detto in inglese fail fast[3], ovvero se un commit di uno sviluppatore è tale da far fallire un test, bisogna intervenire immediatamente prima che si crei una sequenza di errori successivi a valanga.

Fai in modo che il build sia veloce[modifica | modifica sorgente]

Un build troppo lento può rendere poco agevole il far partire i build automatici dopo i commit, e potrebbe costringere gli sviluppatori ad aspettare la fine del build prima di effettuare un commit o di verificarne l'esito.

Eseguire i test in un clone dell'ambiente di produzione[modifica | modifica sorgente]

Se l'ambiente su cui vengono eseguiti i test non è assolutamente identico all'ambiente di produzione, c'è il rischio che qualcosa che è stato testato generi dei bug inspiegabili una volta rilasciato in produzione, con conseguenti danni economici.

Fai in modo che sia facile prendere le ultime versioni dei pacchetti[modifica | modifica sorgente]

Questo principio serve quando si hanno tanti ambienti che devono essere tenuti allineati.

Ognuno può vedere i risultati dell'ultimo build[modifica | modifica sorgente]

La trasparenza permette di stabilire il livello di qualità raggiunto da ogni modulo e capire quali sono i moduli che hanno bisogno di maggiore attenzione.

Automatizza il dispiegamento[modifica | modifica sorgente]

Per dispiegamento si intendono tutte le operazioni che fanno in modo che su un ambiente sia installato e funzionante l'applicativo. Anche il rilascio del software sugli ambienti di test o sull'ambiente di produzione deve essere automatizzato.

Note[modifica | modifica sorgente]

  1. ^ Martin Fowler, Continuous Integration
  2. ^ Martin Fowler, Practices of Continuous Integration. URL consultato il 27 gennaio 2014.
  3. ^ Jim Gray, Why Do Computers Stop And What Can Be Done About It?.

Bibliografia[modifica | modifica sorgente]

  • Grady Booch, Edward M. Eykholt, Best of Booch: Designing Strategies for Object Technology, Cambridge, Combridge University Press, 1998.