Continuous Integration e Continuous Delivery (CI/CD) sono oggi due pratiche fondamentali per l’automazione dei processi di sviluppo e rilascio del software. Questo perché, in un processo di adozione di pratiche e strumenti DevOps, le pipeline di CI/CD aiutano gli sviluppatori ad automatizzare fasi come il testing e i controlli di sicurezza continui, oltre alle build e ai rilasci.
Tuttavia, ci sono numerosi strumenti in grado di implementare tali meccanismi in maniera più o meno flessibile e ognuno ha delle particolarità che potrebbero renderlo più o meno adatto ad un certo caso d’uso.
Esploriamo insieme alcuni dei principali strumenti a oggi utilizzati e sui quali abbiamo lavorato spesso, analizzandone punti di forza e debolezze.
Jenkins
Jenkins nasce nel lontano 2004 per mano di Kohsuke Kawaguchi. Originariamente chiamato Hudson, viene rinominato per un conflitto di nomi con Oracle.
È un sistema facilmente estendibile in quanto supporta un'[architettura master-slave](https://it.wikipedia.org/wiki/Architettura_master-slave) che consente l’aggiunta di nuovi nodi cosiddetti “worker” che, a seguito dell’installazione di un agente, mettono a disposizione le proprie risorse hardware e software per l’esecuzione delle pipeline di CI/CD.
Ad oggi, è uno degli strumenti più popolari per l’implementazione di CI/CD. Questo perché oltre ad avere una community molto attiva ed essere open-source, ha tra i suoi vantaggi quello di avere una grande flessibilità. Infatti, tramite il suo sistema di plugin, consente l’integrazione con una vasta gamma di tecnologie. Inoltre, grazie al suo DSL (Domain-specific Language) basato su Groovy, permette di scrivere le pipeline di CI/CD come codice in modo flessibile e adattabile a qualsiasi esigenza.
Ma attenzione! L’elevata flessibilità di Jenkins può rivelarsi un’arma a doppio taglio. Infatti, se si esagera con le integrazioni utilizzate e con la complessità del codice delle pipeline, si rischia di incorrere in un’elevata complessità. Inoltre, si potrebbe incorrere in problemi di scalabilità, dovuti all’eccessiva quantità di risorse che Jenkins necessita per la corretta esecuzione dei flussi.
GitLab
Conosciamo GitLab come una delle piattaforme di sviluppo software più diffuse. Di base, GitLab è open source, ma è disponibile anche una versione commerciale con funzionalità e supporto aggiuntivi.
Da alcuni anni, tra le altre cose, ospita al suo interno la possibilità di eseguire delle pipeline di CI/CD tramite un sistema integrato. Questo si presenta come un grosso vantaggio per chi fa utilizzo della piattaforma per i propri repository Git, evitando di dover installare uno strumento ulteriore (come Jenkins) e avendo un’integrazione totale anche con gli altri strumenti, come quelli per la pianificazione o il ticketing, ad esempio.
Il sistema prevede l’installazione di un cosiddetto “Runner” rilasciato da GitLab stessa, che prevede la possibilità di eseguire pipeline di CI/CD all’interno di macchine fisiche, virtuali o all’interno di container. Il codice per la creazione delle pipeline di CI/CD viene scritto in YAML rispettando lo schema previsto da GitLab e consultabile nella relativa documentazione. I comandi veri e propri sono comunque scritti nel linguaggio supportato dalla shell di sistema su cui gira il Runner (batch o powershell per Windows, bash/sh per Linux).
Tuttavia, anche GitLab ha i suoi difetti. Ad esempio, alcune funzionalità avanzate come l’AutoDevOps, l’alta disponibilità del sistema, miglioramenti della sicurezza e l’integrazione con strumenti come Jira, Slack, Kubernetes, sono disponibili solo nella versione commerciale del software.
GitHub
Anche la piattaforma più utilizzata al mondo per lo sviluppo del software ha il suo sistema di CI/CD, chiamato GitHub Actions. Anche in questo caso, la perfetta integrazione del sistema di CI/CD con la gestione dei repository è un punto di forza.
Una delle peculiarità di GitHub Actions è la possibilità di comporre le proprie pipeline (chiamate “workflow” nel sistema in questione) tramite piccoli blocchi chiamati Actions (da cui il nome). Tali Actions sono disponibili in un marketplace per l’utilizzo, consentendo così di poter implementare interi workflow senza dover riscrivere intere parti come avviene in Jenkins o in GitLab. Molte action sono inoltre verificate da GitHub stessa e corredate di una documentazione esaustiva.
Bisogna tuttavia prestare molta attenzione alle Actions utilizzate. Alcune sono di terze parti e potrebbero contenere del codice malevolo. Inoltre, è necessario capire se una certa Action che abbiamo scelto, risponde effettivamente alle nostre esigenze. Se così non fosse, potremmo trovarci davanti alla necessità di riscrivere le parti di cui abbiamo bisogno, oppure effettuare un fork della Action e personalizzarla secondo le nostre esigenze.
Altri strumenti
Ovviamente l’ecosistema di strumenti per l’implementazione di pipeline di CI/CD è molto vasto. Oltre quelli che abbiamo esplorato ve ne sono altri che molto diffusi che vogliamo ricordare:
- Travis CI
- Circle CI
- Atlassian Bamboo, integrato con BitBucket e tutta la suite Atlassian
- TeamCity di JetBrains
- Tekton, la CI/CD Kubernetes-native
- E i più recenti strumenti pensati per adottare una filosofia GitOps quali ArgoCD e Flux.
Conclusioni
In definitiva, quando si tratta di scegliere lo strumento più adatto per implementare le proprie pipeline di CI/CD, è necessario capire quali sono le proprie necessità ed effettuare una meticolosa ricerca delle funzionalità indispensabili all’interno dei vari strumenti. Probabilmente più strumenti saranno in grado di rispondere alle proprie necessità, quindi è necessario valutarne aspetti riguardanti l’esperienza di utilizzo, di cui fanno parte la facilità di installazione e gestione, il linguaggio con cui vengono scritte le pipeline e l’eventuale presenza di documentazione, supporto della community e supporto commerciale.