L'integrazione continua (CI, Continuous Integration) è una pratica di sviluppo software in cui gli sviluppatori integrano regolarmente nuovo codice e modifiche al codice in un repository di codice centrale durante tutto il ciclo di sviluppo. È una componente chiave delle metodologie DevOps e Agile.
L'integrazione continua è la prima parte della pipeline CI/CD, un workflow DevOps automatizzato che semplifica il processo di distribuzione del software. L'integrazione continua consente ai team DevOps di migliorare continuamente le proprie applicazioni software, ricevere feedback omogenei, rilevare e correggere gli errori prima che influiscano sulle prestazioni del software, e fornire software di qualità elevata con programmi di consegna più prevedibili.
Quando uno sviluppatore esegue modifiche al codice in un ramo principale o condiviso di un sistema di controllo di versione, l'azione attiva uno strumento CI per eseguire una «build» della base di codice aggiornata. Il sistema CI acquisisce il nuovo codice, lo compila con il codice esistente e lo impacchetta con eventuali dipendenze, come file di configurazione, librerie o altre risorse. Questo costituisce la "build".
Vengono eseguiti test automatici per convalidare questa build prima che venga prodotto un "artefatto di build", il file risultante che viene inviato a ulteriori collaudi o all'ambiente di produzione. Questa parte successiva della pipeline è definita "distribuzione continua".
Il processo di integrazione continua è stato concepito come soluzione ai problemi associati allo sviluppo del software tradizionale, vale a dire i processi di integrazione e distribuzione. Nei paradigmi di sviluppo tradizionali, ogni sviluppatore è responsabile dell'integrazione manuale di nuovo codice in nuove iterazioni di un'app o di un servizio. Ciò rende l'integrazione un processo oneroso in termini di tempo e soggetto a errori, soprattutto per i grandi team di sviluppo.
Diversi pezzi di codice non sempre funzionavano bene insieme e gli sviluppatori integravano le loro modifiche in tempistiche diverse, e talvolta all'ultimo minuto, perciò il feedback sui problemi di integrazione veniva spesso ritardato. Quando si sono verificati dei problemi, i ritardi nel feedback hanno reso più difficile per i team capire quale modifica avesse introdotto il problema e hanno reso il debug un processo più arduo.
Inoltre, i test del software erano poco frequenti. I team in genere implementavano aggiornamenti in batch di grandi dimensioni tutti in una volta, il che portava i bug a passare inosservati e accumularsi nella base di codice. Di conseguenza, i team di sviluppo hanno dovuto affrontare attività di risoluzione dei problemi più impegnative, tassi di errore più elevati e release di codice più lenti; le aziende hanno perso ricavi a causa di inefficienze di processo e gli utenti hanno riscontrato più errori e problemi software.
L'integrazione continua, un componente fondamentale delle moderne pratiche DevOps, delle pipeline di integrazione continua/distribuzione continua (CI/CD) e delle architetture di microservizi, aiuta a semplificare il processo di compilazione fornendo un feedback rapido sulle performance di integrazione.
Con un sistema CI, il nuovo codice viene aggiunto a un repository centrale (in genere, più volte al giorno), dove rimane per le fasi di creazione e test. Se il sistema rileva un errore provvede a inviare notifiche, corregge il codice e conferma che il codice aggiornato è corretto prima di unirlo completamente alla code base del software.
Newsletter di settore
Resta al passo con le tendenze più importanti e interessanti del settore relative ad AI, automazione, dati e oltre con la newsletter Think. Leggi l' Informativa sulla privacy IBM.
L'abbonamento sarà fornito in lingua inglese. Troverai un link per annullare l'iscrizione in tutte le newsletter. Puoi gestire i tuoi abbonamenti o annullarli qui. Per ulteriori informazioni, consulta l'Informativa sulla privacy IBM.
Mentre la configurazione esatta di un sistema di integrazione continua varia da team a team e da azienda ad azienda, ogni sistema di integrazione continua utilizza determinati componenti e processi per ottimizzare le attività di integrazione.
La CI inizia con un repository centrale e condiviso in cui tutti gli sviluppatori eseguono il commit del codice. I repository centrali costituiscono il fondamento delle pratiche di CI. I sistemi di controllo delle versioni (VCS) come Git e Bitbucket spesso gestiscono questi repository. Quando gli sviluppatori inviano le modifiche, il repository centrale ne tiene traccia creando una cronologia completa delle modifiche al codice, che i team di sviluppo possono utilizzare per collaborare in modo più efficiente.
I repository utilizzano anche tecniche di "branching", o ramificazione, che creano linee di sviluppo separate per isolare le modifiche al codice in corso dalla base di codice principale (il ramo principale), e facilitare lo sviluppo in parallelo. La ramificazione consente agli sviluppatori di creare rami di funzione (per isolare specifiche funzionalità dell'app) e rami di breve durata per separare il lavoro prima di unirlo nuovamente al ramo del codice principale.
Gitflow, ad esempio, è un modello di ramificazione basato su Git che assegna ruoli (come "principale", "in evidenza", "sviluppo" e "rilascio") a diversi rami per regolamentare il modo in cui interagiscono tra loro. I rami di Gitflow richiedono agli sviluppatori di creare rami di caratteristiche e attendere il completamento della caratteristica per unire le modifiche al codice nel ramo principale.
I server CI sono strumenti che centralizzano e gestiscono tutte le operazioni CI. Essi fungono da hub di automazione dell'intero processo CI. I server CI monitorano i repository per rilevare le modifiche al codice, e avviano e gestiscono pipeline CI predefinite quando rilevano queste modifiche. I server eseguono build, test e rilasci di software automatici; orchestrano protocolli di controllo versione; gestiscono il reporting degli stati e supportano plug-in capaci di migliorare la funzionalità del sistema.
Molti server CI sono dotati di interfacce utente che aiutano i team a modellare e visualizzare i workflow e a costruire le loro pipeline di distribuzione continua (CD).
I sistemi CI incoraggiano gli sviluppatori a inviare modifiche al codice più volte al giorno, dando priorità a piccole modifiche mirate a attività o funzionalità specifiche. I tool CI consentono ai team di avviare revisioni del codice e discutere sugli eventuali problemi, prima di fondere il nuovo codice, in modo che gli errori possano essere individuati nelle prime fasi del processo di sviluppo.
Un sistema CI basato su Git può, ad esempio, avviare richieste pull per recuperare le modifiche al codice da una filiale locale memorizzata localmente sul computer di un singolo sviluppatore e integrarle nel ramo remoto corrente memorizzato in remoto e condiviso dall'intero team di sviluppo. E le richieste di unione consentono agli sviluppatori di integrare le modifiche proposte da una filiale locale a un'altra per la revisione, la discussione e l'approvazione del team prima di unirle alla filiale remota.
I server e gli strumenti di integrazione continua (compresi i più diffusi strumenti open source come Jenkins, CircleCI, GitHub, AWS CodePipeline e GitLab CI) monitorano il repository centrale per rilevare eventuali modifiche al codice. Quando ne rilevano una, i server CI attivano il processo di compilazione ed eseguono workflow e script predefiniti, compilando e impacchettando il codice in preparazione per il test e, infine, per la distribuzione.
Gli strumenti CI eseguono una serie di test per convalidare il codice prima che venga unito alla base di codice. I test unitari convalidano singoli componenti o funzioni, fornendo un feedback immediato sul comportamento del codice. I test di integrazione valutano le interazioni tra componenti e moduli software per assicurarsi che funzionino insieme correttamente e per individuare eventuali problemi che potrebbero sfuggire ai test unitari.
In alcuni workflow CI, il test end-to-end convalida il software simulando le interazioni dell'utente per verificare che il software si comporti correttamente dal punto di vista dell'utente. I team possono anche eseguire test di qualità del codice e analisi statiche per verificare la reattività e la stabilità dell'applicazione sotto carico e per identificare le violazioni degli standard di codifica e le vulnerabilità di sicurezza.
I server CI notificano immediatamente agli sviluppatori se un build o un test fallisce. In caso di errore, gli sviluppatori possono dare la priorità alla riparazione del codice per garantire che il ramo principale rimanga distribuibile.
Se una build software ha esito positivo, i server producono artefatti (file, come codice compilato, immagini Docker e librerie, creati durante il processo di build) che vengono sottoposti a controllo delle versioni e archiviati in repository per poi essere sottoposti a collaudi e, infine, distribuiti. Indipendentemente dal risultato, i principali sistemi CI registrano i tentativi di integrazione, le percentuali di successo e altre metriche per assicurarsi che i membri del team possano sempre accedere alla documentazione completa delle versioni.
I test sono una componente essenziale dei processi di integrazione continua. I test costituiscono com minimo circa un terzo delle attività di CI, ma questo è vero solo quando i team eseguono una singola fase di test. Spesso, le attività di test costituiscono il maggior gravame di lavoro per i tool CI.
I test continui in un ambiente CI iniziano quando uno sviluppatore esegue il commit di un nuovo codice in una base di codice. Questa azione attiva una build e un processo di test automatizzato. In molti casi, vengono eseguiti test aggiuntivi dopo la creazione di un artefatto di build (prima che il codice entri in produzione). È inoltre importante che gli sviluppatori eseguano tutti i test e sottoinsiemi di test nel loro ambiente locale, per assicurarsi di impegnare il codice sorgente nel controllo di versione solo dopo che le nuove modifiche al codice hanno superato i test.
Questa attività di test multiforme delle varie funzioni, casi d'uso e integrazioni viene definito collettivamente "suite di test". Questo approccio massimizza la portata dei collaudi, previene la regressione del codice e prepara il terreno per la distribuzione continua.
Lo sviluppo basato sui test (TDD) è un altro approccio allo sviluppo del software. Il TDD è un approccio in cui gli sviluppatori "lavorano a ritroso", scrivendo un test prima di scrivere la prima riga di codice. In questo approccio, gli sviluppatori scrivono un test case a livello di unità, poi scrivono la quantità di codice minima che serve per superarlo. Una volta fatto ciò, sia il codice di test che quello di produzione possono essere ripuliti e migliorati.
Questo approccio aiuta gli sviluppatori a concentrarsi su requisiti ben definiti ed evitare codici estranei. Sottolinea inoltre il feedback continuo e può essere una tecnica efficace per accelerare i cicli di sviluppo.
Le pipeline DevOps accelerano la distribuzione di software di alta qualità automatizzando e combinando gli sforzi dei team di sviluppo e delle operazioni IT, che tradizionalmente esistevano nei propri silo.
I processi e culture DevOps di successo si estendono oltre lo sviluppo e le operazioni per includere l'ingegneria di piattaforma e infrastruttura, la sicurezza, la conformità, la governance, la gestione del rischio, le linee di business, gli utenti finali e i clienti. In altre parole, un buon DevOps dovrebbe incorporare gli input di tutti gli stakeholder delle applicazioni nel ciclo di vita dello sviluppo software.
Nel framework DevOps, l'integrazione continua si trova all'inizio del processo di sviluppo software e della pipeline CI/CD. La CI consente agli sviluppatori di controllare frequentemente il codice per evitare che le copie locali si discostino troppo dal ramo principale della build. Questo approccio aiuta i team a evitare conflitti di fusione che potrebbero "spaccare" la build nelle fasi di delivery e distribuzione.
La CI consente inoltre agli sviluppatori di inviare piccoli e frequenti aggiornamenti che promuovono cicli di feedback rapidi e coerenti e un miglioramento continuo in base alla priorità delle esigenze dei clienti, principi chiave della filosofia DevOps.
L'integrazione continua è la prima tappa della pipeline CI/CD ed è in genere seguita dai processi di distribuzione continua e distribuzione. L'integrazione continua si riferisce alle frequenti fusioni di codice e alle build e agli unit test che seguono.
La consegna continua (CD) riprende da dove si ferma l'integrazione continua, automatizzando la delivery delle modifiche convalidate alla base di codice (inclusi aggiornamenti, correzioni e persino nuove funzionalità) in ambienti o repository di codice selezionati. I team DevOps ricevono notifiche sulle build più recenti e possono spostare manualmente gli aggiornamenti in un ambiente di produzione attivo. L'obiettivo della pipeline di consegna continua è quello di implementare nuovo codice con il minimo sforzo, consentendo comunque un certo livello di supervisione umana prima che il codice venga pubblicato.
La distribuzione continua implementa automaticamente le modifiche al codice agli utenti finali dopo aver superato una serie di test predefiniti, come gli integration test che testano il codice in un ambiente di emulazione per contribuire a garantire l'integrità del codice. Sia la fornitura continua che la distribuzione continua si occupano di automatizzare ulteriormente la pipeline rispetto alla CI e sono spesso usate in modo intercambiabile.
La differenza tra consegna e implementazione continui risiede nel livello di automazione utilizzato nelle versioni del software o dell'app. Nella distribuzione continua, il codice si sposta automaticamente in ambienti simili a quelli di produzione per ulteriori test e controlli della qualità, come la valutazione dei rischi e l'identificazione delle vulnerabilità del codice sorgente. Dopo il superamento dei test, è necessario l'intervento umano per spostare il codice in produzione.
Nell'implementazione continua, l'automazione ha un ruolo ancora maggiore. Una volta che il codice ha superato il test, la distribuzione in produzione avviene automaticamente: l'approvazione umana non è necessaria.1
Lo sviluppo Agile è un approccio iterativo all'ingegneria del software che dà priorità alla flessibilità, alla collaborazione, al miglioramento continuo e al rapido adattamento ai cambiamenti. È una pratica che organizza lo sviluppo in piccoli gruppi di lavoro, o "sprint", per semplificare la collaborazione tra sviluppatori e stakeholder e accelerare la distribuzione del software.
Allo stesso modo, la CI richiede aggiornamenti frequenti e incrementali del codice e una sua validazione continua. Si tratta di un approccio iterativo allo sviluppo che consente agli sviluppatori di aggiornare e scalare rapidamente le soluzioni software nel tempo e di fornire più rapidamente prodotti di alta qualità agli utenti. In quanto tale, l'integrazione continua è una pratica intrinsecamente agile.
L'integrazione continua aiuta i team di sviluppo a iterare più velocemente e a fornire software migliori agli utenti, ma ci sono ulteriori misure che un'azienda può adottare per ottimizzare il processo. Le pratiche di CI comunemente implementate includono:
Una base di codice consolidata e centralizzata può semplificare la distribuzione e la visibilità. Molte organizzazioni utilizzano la gestione del controllo del codice sorgente per gestire un unico repository che tiene traccia e controlla tutti i file associati alla build di un prodotto.
Le organizzazioni possono creare una cultura di omogeneità richiedendo agli sviluppatori di eseguire il commit delle loro modifiche nel flusso di sviluppo principale almeno una volta al giorno, per verificare che la loro copia di lavoro sia allineata.
L'ottimizzazione degli script di compilazione, la parallelizzazione dei compiti e l'utilizzo di meccanismi di caching possono ridurre i tempi di compilazione. I team possono anche configurare le pipeline CI in modo che le nuove integrazioni siano verificate nelle prime fasi del processo di iterazione. Questo approccio proattivo consente agli sviluppatori di affrontare i problemi in modo rapido e di dedicare meno tempo al debug.
La creazione di un ambiente di test il più simile possibile a quello di produzione finale assicura che i risultati dei test forniscano una rappresentazione accurata delle prestazioni del software nel mondo reale.
L'implementazione di flag di funzione per controllare il rilascio di nuove funzioni consente ai sistemi CI di unire funzionalità incomplete o sperimentali nel ramo principale senza influire sulla produzione complessiva.
La revisione e l'aggiornamento frequenti della pipeline di CI per incorporare nuovi strumenti, tecnologie e best practice aiutano i team DevOps a rafforzare la pipeline e ad aggiornare le pratiche di sviluppo man mano che le esigenze del progetto si evolvono.
Con TDD, i test vengono scritti prima dell'implementazione di qualsiasi codice di caratteristiche. I team di sviluppo e di prodotto collaborano per delineare le specifiche del prodotto, i requisiti vengono trasformati in una lista di controllo di asserzioni di codice e gli sviluppatori scrivono codice che soddisfi i test. Un approccio TTD consente ai team di integrare in modo proattivo modifiche al codice affidabili e di alta qualità nelle pipeline CI.
Le pratiche di integrazione continua, e più in generale i framework DevOps, aiutano le aziende a semplificare la collaboratività e l'integrazione del codice, e a mantenere pipeline di delivery continue. Queste pratiche migliorano la qualità del software e ne velocizzano i processi di rilascio. I moderni strumenti CI incorporano una gamma di tecnologie emergenti che corroborano queste pratiche e ne incrementano il valore.
Ad esempio, l'uso dell'intelligenza artificiale (AI) e del machine learning (ML) nei processi di integrazione continua sta diventando una pratica di sviluppo standard. Gli strumenti basati sull'AI possono aiutare gli sviluppatori a creare sistemi di ingegneria della piattaforma che identificano e correggono automaticamente e autonomamente il codice problematico prima che influisca sul flusso di sviluppo principale. I sistemi CI basati sull'apprendimento automatico possono anche generare automaticamente casi di test personalizzati in base all'invio e alle modifiche del codice, in modo che gli sviluppatori dedichino meno tempo alla creazione manuale di test di codice.
Con le minacce informatiche sempre più sofisticate,2 gli sviluppatori stanno integrando sempre più le pratiche di sicurezza direttamente nel processo di sviluppo del software. Queste strategie di sicurezza "shift-left" introducono i controlli di sicurezza nelle prime fasi di sviluppo, compresi i processi CI, per garantire che le vulnerabilità vengano rilevate durante la codifica piuttosto che dopo la distribuzione.
Oggi, Kubernetes e l'ampio ecosistema di tecnologie di containerizzazione sono gli elementi costitutivi dei moderni ambienti IT. DevSecOps integra la sicurezza in ogni fase di DevOps per fare fronte ai problemi di sicurezza che accompagnano questi ecosistemi dinamici.
I contenitori sono unità software eseguibili che "impacchettano" il codice dell'applicazione insieme alle relative librerie e dipendenze, facendo in modo che il codice possa essere eseguito in qualsiasi ambiente informatico. Kubernetes, noto anche come k8s o kube, è una piattaforma di orchestrazione di container open source per la pianificazione e l'automatizzazione dell'implementazione, la gestione e la scalabilità delle applicazioni containerizzate.
Tradizionalmente, i team DevOps si affidavano a un team di sicurezza separato per identificare le vulnerabilità e poi utilizzavano il feedback per implementare le modifiche al codice nel ciclo successivo di aggiornamenti delle app. Ora, ci si aspetta che gli sviluppatori proteggano i container e i cluster Kubernetes e applichino i principi zero trust in tutte le loro applicazioni software e nel processo di sviluppo, il che riflette un nuovo paradigma operativo.3 L'adozione delle pratiche DevSecOps significa che la codifica e lo sviluppo del software non riguardano più solo la creazione di caratteristiche, ma anche l'anticipazione dei rischi.
Anche l'elaborazione serverless e le architetture cloud-native sono una priorità per i team DevOps di oggi.
Il serverless computing è un modello di sviluppo ed esecuzione di applicazioni che consente agli sviluppatori di creare ed eseguire il codice delle applicazioni senza eseguire il provisioning o gestire server o infrastrutture di back-end. I server in una configurazione serverless esistono, ma sono gestiti interamente da un provider di servizi cloud (cloud service provider, CSP). Nelle pipeline CI, le piattaforme serverless esonerano gli sviluppatori dalle preoccupazioni relative all'infrastruttura di backend, in modo che possano concentrarsi sulla codifica front-end e sulla logica di business.
Con la proliferazione di applicazioni serverless e dell'AI, le architetture basate sugli eventi (event-driven architectures, EDA) svolgono un ruolo centrale nell'aiutare i team ad affrontare la crescente complessità del cloud computing. Gli EDA supportano la comunicazione in tempo reale tra sistemi front-end e backend blandamente accoppiati, consentendo ai sistemi di funzionare in modo indipendente ed elaborare gli eventi (qualsiasi modifica o azione che si verifica all'interno di un sistema) in modo asincrono.
Nelle pipeline CI ciò significa che gli sviluppatori possono scalare i singoli componenti dell'app senza influire sull'intera applicazione, il che aiuta i team a creare basi di codice e processi di integrazione più agili, reattivi e scalabili.
che includa la scelta degli strumenti giusti, la definizione dei workflow di compilazione e test e la configurazione dell'infrastruttura. Le pipeline CI richiedono anche una manutenzione regolare per adattarsi alle modifiche alla base del codice, alle dipendenze (come le API) e all'infrastruttura.
Tuttavia, l'implementazione della CI può offrire ai team di sviluppo software una serie di vantaggi, tra cui:
I processi CI consentono ai team di risolvere gli errori in anticipo, a volte entro pochi minuti dall'invio del codice.
Tutti i membri del team possono modificare il codice, unire le modifiche al codice e identificare le incompatibilità del codice e gli errori di integrazione, semplificando la condivisione delle conoscenze e migliorando la qualità del codice e del software attraverso il feedback tra pari.
Poiché il nuovo codice viene integrato continuamente, i team dedicano meno tempo all'integrazione e al test di grandi batch di codice. E il ciclo di feedback accelerato offerto dagli strumenti CI aiuta gli sviluppatori a iterare e fornire aggiornamenti software e nuovi prodotti agli utenti finali più velocemente.
Commit di codice frequenti comportano modifiche più piccole e incrementali, più facili da comprendere, rivedere e testare. In questo modo si riduce il rischio di introdurre problemi importanti nella base del codice durante lo sviluppo.
Automatizza la distribuzione del software per qualsiasi applicazione on premise, cloud o mainframe.
Utilizza il software e gli strumenti DevOps per creare, distribuire e gestire app cloud-native su più dispositivi e ambienti.
Sblocca nuove funzionalità e promuovi l'agilità aziendale con i servizi di consulenza cloud di IBM. Scopri come creare insieme soluzioni, accelerare la trasformazione digitale e ottimizzare le prestazioni attraverso strategie di hybrid cloud e partnership di esperti.