☁ Cloud e DevOps

Pipeline CI/CD: dal commit al rilascio senza passaggi manuali

Cosa sono integrazione, consegna e deploy continui, come si organizzano le fasi di una pipeline e quali errori evitare per avere rilasci rapidi e sicuri.

In molti progetti il rilascio è ancora un rito: qualcuno si collega al server, scarica il codice, lancia due o tre comandi ricordati a memoria e spera che tutto vada bene. Funziona finché funziona, poi un venerdì sera manca un passaggio e il sito resta giù per un'ora. Una pipeline CI/CD trasforma quel rito in un processo automatico, ripetibile e verificabile.

Tre sigle da distinguere

Le espressioni sono spesso usate come sinonimi, ma indicano livelli diversi di automazione.

  • Continuous Integration (CI): ogni modifica inviata al repository viene compilata e testata automaticamente. Lo scopo è scoprire subito se una modifica rompe qualcosa, quando è ancora piccola e facile da correggere.
  • Continuous Delivery: oltre ai test, la pipeline produce un artefatto pronto per la produzione e lo porta fino a un ambiente di prova. Il rilascio finale avviene con un'approvazione umana, spesso un solo clic.
  • Continuous Deployment: anche il passaggio in produzione è automatico. Ogni modifica che supera tutti i controlli viene rilasciata senza intervento.

Non c'è un livello giusto in assoluto. Molte aziende si fermano alla consegna continua perché vogliono decidere quando rilasciare, per esempio evitando i momenti di massimo traffico.

Le fasi di una pipeline tipica

Una pipeline è una sequenza di passi eseguiti da un servizio di automazione, come GitHub Actions, GitLab CI o Jenkins, ogni volta che succede qualcosa nel repository.

  1. Recupero del codice e preparazione dell'ambiente, con la versione corretta del linguaggio.
  2. Installazione delle dipendenze, preferibilmente da un file di lock per avere versioni identiche ogni volta.
  3. Controlli statici: formattazione, linter, analisi dei tipi. Sono veloci e intercettano errori banali.
  4. Test automatici: prima quelli unitari, rapidi, poi quelli di integrazione che coinvolgono database o servizi esterni.
  5. Build dell'artefatto: un'immagine container, un pacchetto o una cartella di file statici, etichettato con l'identificativo del commit.
  6. Controlli di sicurezza: analisi delle dipendenze vulnerabili e ricerca di segreti finiti per errore nel codice.
  7. Deploy in staging e test di verifica rapidi sul sistema in esecuzione.
  8. Deploy in produzione, automatico o con approvazione.

L'ordine non è casuale: i controlli più veloci vengono prima, così una modifica sbagliata viene bloccata in pochi secondi invece che dopo dieci minuti di test.

Un esempio concreto

Un flusso di lavoro essenziale per un progetto Python su GitHub Actions può essere descritto così:

name: ci
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install -r requirements.txt
      - run: ruff check .
      - run: pytest

Ogni pull request viene così verificata prima di essere unita al ramo principale. Da qui si aggiungono progressivamente build, scansioni e deploy.

Principi che rendono una pipeline affidabile

Costruire una volta, distribuire ovunque

L'artefatto va creato una sola volta e poi promosso da un ambiente all'altro. Ricostruirlo per la produzione significa rilasciare qualcosa di diverso da ciò che è stato testato, magari perché nel frattempo è uscita una nuova versione di una dipendenza.

La pipeline deve essere veloce

Se servono quaranta minuti per sapere se una modifica funziona, gli sviluppatori smettono di aspettare e accumulano modifiche, perdendo il senso dell'integrazione continua. Cache delle dipendenze, test eseguiti in parallelo e separazione tra test rapidi e lenti aiutano a restare sotto pochi minuti.

Un test che fallisce a caso va sistemato subito

I test instabili, che a volte passano e a volte no, sono il peggior nemico della CI. Insegnano a ignorare il rosso e a rilanciare la pipeline finché diventa verde. Un test instabile va corretto o temporaneamente isolato, mai tollerato.

Segreti al sicuro

Le credenziali per il deploy vanno salvate nell'archivio di segreti del servizio di CI, mai nel repository. È buona regola dare a ogni pipeline solo i permessi strettamente necessari e, dove possibile, usare credenziali temporanee al posto di chiavi permanenti.

Ogni rilascio deve essere reversibile

Prima di automatizzare il deploy chiediti come si torna indietro. Se l'artefatto precedente è ancora disponibile e il rilascio è un semplice cambio di versione, il rollback diventa un'operazione di un minuto. Le modifiche al database meritano un'attenzione particolare, perché non sempre si possono annullare.

Da dove cominciare

Non serve costruire tutto in un giorno. Il passo con il miglior rapporto tra sforzo e risultato è far girare i test a ogni pull request e impedire l'unione se falliscono. Poi si automatizza la build, quindi il deploy in staging, infine la produzione. Ogni passo riduce il lavoro manuale e il rischio di errori, e documenta in un file versionato come si rilascia il software.

In sintesi

  • La CI verifica ogni modifica; la consegna continua prepara il rilascio; il deploy continuo lo esegue in automatico.
  • Ordina le fasi dalla più veloce alla più lenta per bloccare subito gli errori evidenti.
  • Costruisci l'artefatto una volta e promuovilo tra gli ambienti senza ricostruirlo.
  • Mantieni la pipeline rapida, elimina i test instabili e proteggi le credenziali.
  • Inizia dai test automatici sulle pull request e aggiungi le altre fasi gradualmente.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica e in psicologia, unisce l'analisi tecnica alla comprensione del fattore umano.

Leggi anche