CI/CD reale: perché la tua pipeline probabilmente non lo è
Software DeliveryArchitettura

CI/CD reale: perché la tua pipeline probabilmente non lo è

Avere Jenkins o GitHub Actions non significa fare continuous delivery. La differenza tra una pipeline che automatizza il teatro e una che rilascia davvero, in modo continuo e sicuro.

QMates· Software Advisory14 aprile 202611 min

La maggior parte delle organizzazioni software ha una pipeline CI/CD. Jenkins, GitHub Actions, GitLab CI, CircleCI: lo strumento c'è. Eppure i rilasci restano rari, rischiosi e stressanti. I branch vivono settimane, i merge generano conflitti, i test girano per ore e falliscono in modo imprevedibile. Il venerdì nessuno rilascia.

Il problema non è il tool. Il problema è che avere una pipeline non significa fare continuous integration, né tantomeno continuous delivery. Molte organizzazioni hanno automatizzato il teatro: la pipeline esiste, ma il processo di rilascio resta sostanzialmente manuale, lento e fragile.

La CI/CD non è uno strumento da installare; è una pratica da adottare. E la differenza tra chi la pratica davvero e chi ha solo il tool è la stessa differenza tra chi rilascia con fiducia ogni giorno e chi trema a ogni rilascio mensile.

Cos'è davvero la continuous integration

Continuous integration ha una definizione precisa, formulata da Martin Fowler e Matthew Foemmel nel 2000 e ancora valida oggi: ogni sviluppatore integra il proprio codice nel trunk (il ramo principale) almeno una volta al giorno, e ogni integrazione viene verificata da una build automatizzata con test. Fowler ha poi rivisto e approfondito l'articolo nel 2006, ma il principio fondamentale risale all'originale.

Le parole chiave sono tre:

  • Trunk: un singolo ramo condiviso. Non un branch per feature che vive settimane; il trunk, dove tutti integrano
  • Almeno una volta al giorno: integrazioni piccole e frequenti. Ogni commit è piccolo abbastanza da essere capito, rivisto e verificato in pochi minuti
  • Build automatizzata con test: ogni integrazione attiva una pipeline che compila, testa e verifica. Se fallisce, il team si ferma e corregge prima di continuare

Se i branch durano più di un giorno, non è continuous integration. Se i test non girano a ogni commit, non è continuous integration. Se la build fallisce e nessuno la corregge entro un'ora, non è continuous integration. È qualcos'altro: utile forse, ma non CI.

Il teatro della CI/CD

Questo è il pattern che vediamo più spesso nelle organizzazioni in crescita:

  • Ogni sviluppatore lavora su un branch separato per giorni o settimane
  • Il merge avviene alla fine, genera conflitti, richiede ore di risoluzione
  • La pipeline gira sul branch, passa, ma quando il codice arriva nel trunk i test falliscono
  • I test end-to-end sono lenti (30-60 minuti), fragili e spesso vengono ignorati quando falliscono
  • Il rilascio richiede un "release manager" che coordina, testa manualmente e decide quando è sicuro
  • Il deploy avviene di giovedì mattina, mai di venerdì, mai dopo le 16

La pipeline esiste; il processo è manuale. L'automazione copre i passi facili (compilare, eseguire test) ma non affronta i problemi reali: branch di lunga durata, test inaffidabili, mancanza di fiducia nel rilascio.

Il segnale più chiaro che la CI/CD è teatro: il team ha paura di rilasciare. Se rilasciare genera ansia, il processo non funziona, indipendentemente da quanto sia sofisticata la pipeline.

Perché il tool non è il problema

Jenkins, GitHub Actions, GitLab CI: sono tutti strumenti capaci. La differenza tra un'organizzazione che rilascia con fiducia ogni giorno e una che rilascia con terrore ogni mese non è nel tool; è in tre fattori.

Primo: la strategia di branching. Il trunk-based development, dove tutti lavorano sullo stesso ramo con integrazioni frequenti, è il prerequisito per la CI reale. I feature branch di lunga durata sono l'anti-pattern più diffuso e più dannoso: ritardano l'integrazione, amplificano i conflitti e rendono ogni merge un evento rischioso.

Secondo: la strategia di test. Una pipeline con test lenti e fragili è peggio di una pipeline senza test, perché genera falsa sicurezza. I test devono essere veloci (sotto i 10 minuti per la suite completa), affidabili e significativi (testano il comportamento, non l'implementazione). L'obiettivo dei team ad alta maturità è tendere a zero test flaky: ogni test instabile si indaga e si risolve invece di essere escluso o ignorato. Se la suite di test richiede più di 15 minuti, nessuno aspetterà il risultato prima di andare avanti.

Terzo: la cultura del rilascio. Rilasciare spesso riduce il rischio di ogni singolo rilascio. Un rilascio che contiene una modifica è facile da capire, verificare e, se necessario, revertire. Un rilascio che contiene tre settimane di lavoro di cinque team è una bomba a orologeria. La cultura del rilascio frequente si costruisce con la pratica: si inizia rilasciando due volte a settimana, poi ogni giorno, poi più volte al giorno.

Come si passa dalla pipeline al rilascio continuo

La transizione non è un progetto: è un percorso incrementale. Ogni passo riduce il rischio del passo successivo.

Passo 1: ridurre la durata dei branch. Da settimane a giorni, da giorni a ore. Le feature flag permettono di integrare codice incompleto nel trunk senza esporlo agli utenti: il codice è in produzione, ma la funzionalità è spenta fino a quando non è pronta. Questo elimina il problema alla radice: non ci sono branch da mergiare perché tutto è già nel trunk.

Passo 2: rendere i test veloci e affidabili. Eliminare i test flaky (quelli che falliscono in modo casuale): ogni test flaky tollerato erode la fiducia nella pipeline. Spostare il peso dai test end-to-end (lenti e fragili) verso i test unitari e di integrazione (veloci e affidabili). L'obiettivo è una suite che gira sotto i 10 minuti e che, quando fallisce, indica un problema reale.

Passo 3: automatizzare il rilascio. Se i test passano e la build è verde, il rilascio dovrebbe essere un click, non una cerimonia. Rimuovere i passaggi manuali uno alla volta: prima il deploy in staging diventa automatico, poi il deploy in produzione diventa un click, poi anche quello diventa automatico. Ogni passaggio manuale rimosso è un punto di attrito eliminato.

Passo 4: rilasciare piccolo e spesso. La frequenza di rilascio è la metrica più importante. Rilasci piccoli e frequenti riducono il rischio, accelerano il feedback e rendono il rollback banale. Se qualcosa va storto con un rilascio che contiene una modifica, la causa è ovvia. Se va storto con un rilascio che contiene 47 modifiche, buona fortuna a trovare il problema.

L'impatto sul business

La CI/CD reale non è un miglioramento tecnico: è un vantaggio competitivo. Le organizzazioni che rilasciano con fiducia ogni giorno possono reagire al mercato in ore, non in mesi; possono sperimentare con feature flag e misurare l'impatto prima di investire; possono correggere problemi in produzione in minuti anziché in giorni.

Le DORA metrics (deployment frequency, lead time for changes, change failure rate, time to restore) sono il modo più diretto per misurare l'efficacia della CI/CD. Le organizzazioni "elite" nel report DORA rilasciano più volte al giorno con un change failure rate tra il 5 e il 15%. Non è un obiettivo irrealistico: è il risultato naturale delle pratiche descritte in questo articolo.

Cosa fare concretamente

Tre azioni da fare questa settimana:

Quando entriamo in un team con il servizio di Innesto, quasi sempre troviamo la stessa situazione: una pipeline configurata, ma test che vengono saltati perché "non passano in CI", o branch che vivono per settimane perché "aspettiamo di integrare tutto insieme". Il teatro della CI/CD non nasce da pigrizia — nasce dall'assenza di un accordo condiviso su cosa significa build verde. Il primo passo che facciamo è stabilire quel contratto: zero test ignorati, build rossa significa stop, nessuna eccezione. Sembra banale. Non lo è: richiede che il team smetta di trattare la pipeline come un ostacolo da aggirare e inizi a trattarla come il termometro della salute del sistema.

  1. Misurare la frequenza di rilascio attuale: quante volte il team rilascia in produzione? Se la risposta è "meno di una volta a settimana", c'è spazio per migliorare. Il calcolatore di impatto aiuta a stimare quanto costa ogni giorno di ritardo nel rilascio
  2. Identificare il branch più vecchio: da quanto tempo il branch più longevo è aperto? Ogni giorno in più è rischio accumulato. L'obiettivo è che nessun branch viva più di 24 ore
  3. Cronometrare la pipeline: quanto tempo passa dal commit al feedback dei test? Se supera i 15 minuti, gli sviluppatori smetteranno di aspettare il risultato. Sotto i 10 minuti è l'obiettivo; sotto i 5 è l'ideale

Se la pipeline è lenta, i test inaffidabili e i rilasci rari, il problema non si risolve cambiando tool. Si risolve cambiando il processo, la cultura e, spesso, l'architettura che li vincola. È esattamente il tipo di intervento che facciamo con l'innesto nell'organizzazione: entriamo nel team, lavoriamo insieme e trasferiamo le pratiche che rendono il rilascio continuo una realtà quotidiana.

Raccontaci dove sei bloccato

Prototipo fragile, legacy pesante o delivery imprevedibile – partiamo da lì