Come e cosa serve per impostare il processo di Continuous Deploy in azienda

Come e cosa serve per impostare il processo di Continuous Deploy in azienda

Sia Jez Humble e David Farley, nel suo libro, che Martin Fowler in un interessante articolo, elencano e descrivono una serie di pratiche ottimali da adottare per implementare processi in ambito Continuous Development.

Come e cosa serve per impostare il processo di Continuous Deploy in azienda

Unico repository per i sorgenti

I progetti software (programmi) coinvolgono numerosi file che devono essere opportunamente combinati tra loro per costruire un prodotto (una vera e propria orchestrazione). Tenerne traccia è un effort oneroso, in particolare quando sono coinvolte più persone. Non c’è da sorprendersi quindi che, negli anni, i team di sviluppo software abbiano costruito tools per gestire tutto questo. Questi tools, chiamati Source Code Management, Configuration Management, Version Control Systems, repositories o anche in altri modi, devono essere parte integrante del progetto: bisogna evitare soluzioni “artigianali” quali, ad esempio, il ricorso a dischi e directory condivisi.

La maggior parte di questi tools sono open source, quindi non è necessario fare investimenti, se non il tempo necessario ad installare il sistema e comprenderne in maniera almeno basilare il funzionamento.

Una volta messo in piedi il sistema, assicurarsi che il posto da cui prelevare i sorgenti sia noto a tutti, nessuno dovrebbe chiedere “Dove è il tale file?”, tutto dovrebbe essere nel repository e rintracciabile.

Tutto il necessario ai fini del funzionamento di un programma eseguibile, deve essere nel repository, compresi: script di test, file properties, database schema, script di installazione e librerie esterne.

Nel caso delle librerie esterne, può essere utile l’impiego di tool quali, ad esempio, Maven, che permettono la gestione centralizzata delle dipendenze tra progetti sollevando, almeno in parte, gli sviluppatori da tale onere.

E’ sconsigliato invece, mantenere nei repositories i prodotti delle build (packages).

L’insieme dei file sorgenti posti sotto controllo di versione, non ancora inclusi in una release software, viene indicato con vari termini quali, ad esempio trunk, baseline, master. Nel seguito ci si riferirà a tali file con il termine Mainline.

Automatizzare la Build

Partire dai sorgenti per ottenere un sistema funzionante può spesso essere un processo complicato che coinvolge compilazione, trasferimento file, caricamento di schemi nei database, ed altro ancora.

Questa parte può, e deve, essere automatizzata. Chiedere alle persone di eseguire “strani” comandi o cliccare attraverso finestre di dialogo è una perdita di tempo e può favorire errori.

Gli ambienti automatizzati per le build sono una caratteristica comune dei sistemi (esempio Ant, Ruby, Nant, MSBuild, …)

Un errore comune è il non includere tutto nella build automatica. La build dovrebbe comprendere, ad esempio, il prelievo degli script relativi alle modifiche al database e la loro esecuzione nell’ambiente in cui il programma verrà mandato in esecuzione.

L’idea di base è che, una volta installata una macchina vergine ex novo, dopo un checkout del repository questa macchina dovrebbe essere in grado di buildare ed eseguire il programma senza problemi.

Nel caso la build di un grosso progetto richieda parecchio tempo, particolari accorgimenti possono essere adottati in modo da non dover costruire da zero il prodotto tutte le volte che vengono apportate modifiche, anche elementari.

Rendere la Build Auto-Testante

Build significa compilazione, link e tutto ciò necessario ad un programma per essere eseguito partendo dai sorgenti. Un programma può girare, ma ciò non esclude la presenza di eventuali bug nel codice. Un buon modo per intercettare bug in modo veloce ed efficiente è includere test automatici nel processo di build. La crescita dell’Extreme Programming (XP) e del Test Driven Development ha contribuito a diffondere il concetto di codice auto-testante. Ovviamente non è strettamente necessario il ricorso al TDD per avere del codice auto-testante, sicuramente questa tecnica è di grande aiuto nella predisposizione dei test.

E’ però necessario avere una suite di test automatici che coprano la maggior parte della mainline, allo scopo di scoprire eventuali bug. I test vengono poi lanciati tramite un comando ed il loro risultato deve riportare eventuali test falliti. In una build auto-testante il fallimento di un test comporta il fallimento della build stessa.

Negli ultimi anni ha acquisito popolarità la famiglia di tool open-source XUnit, ideali per questo tipo di test e per costruire un ambiente completamente auto- testante.

Ovviamente non si può contare sui test per trovare tutto. Come spesso si dice: i test non dimostrano l’assenza di bug. Tuttavia, la perfezione non è l’unico punto per cui si ottiene valore dalla build auto-testante. Test imperfetti, lanciati spesso, sono molto meglio dei test perfetti che non sono mai stati scritti.

Tutti committano sulla mainline ogni giorno

Integrazione è soprattutto comunicazione. L’integrazione mette gli sviluppatori in condizione di parlare con gli altri sviluppatori delle modifiche che hanno fatto. Il primo prerequisito per uno sviluppatore, affinché possa committare il proprio lavoro sulla mainline, è che questa continui a buildare correttamente. Questo include, ovviamente, il passaggio dei test automatici. Come avviene per ogni commit, lo sviluppatore prima aggiorna la propria codebase locale con la mainline su repository, risolve eventuali conflitti, builda in locale. Se la build va a buon fine, committa le modifiche fatte.

Facendo questo frequentemente, gli sviluppatori scoprono velocemente eventuali conflitti tra il proprio codice locale e la mainline. La chiave per risolvere i problemi velocemente è individuarli velocemente. Con commit frequenti, eventuali problemi emergono altrettanto frequentemente e, a questo punto, non essendovi molte differenze tra due commit adiacenti, sono relativamente facili da risolvere. I conflitti che rimangono “sommersi” per settimane, possono essere invece estremamente difficili da risolvere.

Se ci sono solo poche ore di modifiche tra un commit e l’altro, i punti del programma in cui il problema potrebbe nascondersi rimangono circoscritti.

In generale, più frequentemente si committa, meno punti andranno verificati in caso di conflitti e, quindi, più rapidamente i conflitti verranno sistemati.

I commit frequenti incoraggiano inoltre gli sviluppatori a spezzare il proprio lavoro in piccoli intervalli da qualche ora ciascuno. Questo aiuta ad avere consapevolezza dei progressi fatti.

Eseguire tutti i Commit Tests localmente prima di committare

Prima di committare le proprie modifiche sulla mainline è necessario scongiurare il rischio che queste possano far fallire la build della mainline. Oltre ad aggiornare la propria codebase locale all’ultima versione della mainline ed assicurarsi che il codice venga correttamente compilato, è necessario eseguire localmente anche i test che verificano il corretto funzionamento delle modifiche introdotte (self-testing, vedi sopra). Sono gli stessi test che verranno eseguiti quando verrà lanciato il processo di build della mainline presente sotto SCM.

Alcuni moderni server di Continuous Integration sono in grado di gestire automaticamente questo passaggio. Intercettano le modifiche committate e svolgono automaticamente i test. Solamente in caso di esito positivo di questi test, le modifiche vengono effettivamente committate sulla mainline, viceversa viene notificato il problema allo sviluppatore o agli sviluppatori che l’hanno creato in modo che possa essere risolto.

Ogni Commit lancia una build della mainline su una Integration Machine

Attraverso commit giornaliere, un team ottiene build testate frequenti. Questo significa che la mainline, o meglio il prodotto risultante dalla build dei file che la costituiscono, rimane in uno stato funzionante. Nella pratica, le cose potrebbero andare diversamente. Un motivo è la disciplina, ovvero persone che non aggiornano la propria codebase locale. Un altro motivo sono le differenze ambientali tra le macchine dei vari sviluppatori.

Bisogna quindi prevedere build regolari su una macchina dedicata (integration machine) conseguenti ad ogni commit. E ogni commit viene considerato completato solamente se la build da lui scatenata va a buon fine. La responsabilità di monitorare che questo accada ricade sullo sviluppatore che committa, in modo che lui stesso possa sistemare eventuali inconvenienti. Come corollario, non si esce dall’ufficio se gli ultimi commit di giornata hanno rotto la build sulla integration machine.

Per assicurare questo, oltre a lanciare build manuali sulla integration machine dopo ogni build, si può ricorrere ad un continuous integration server.

Un continuous integration server agisce da monitor sul repository. Ogni volta che viene eseguita una commit sul repository, il server esegue il check out della codebase sulla integration machine, lancia la build e notifica a chi ha committato l’esito della build. Il commit si considera concluso solo a ricezione avvenuta della notifica. Onde evitare spam di notifiche, si può restringere l’invio di una notifica solamente in caso di fallimento della build. E’ comunque responsabilità dello sviluppatore, verificare l’esito della build avvenuta sulla integration machine in seguito al suo commit.

Alcune organizzazioni ricorrono a build schedulate, questo però è leggermente diverso rispetto al concetto di continuous build esposto sopra e non è sufficiente come pratica di Continuous Integration, in quanto uno degli scopi della continuous integration è scovare problemi in tempo brevissimo. L’emergere di un bug durante una build notturna, ad esempio, significa che, potenzialmente, questo bug è rimasto nascosto per un intero giorno lavorativo, e potrebbe essere quindi di non facile risoluzione.

Non iniziare altre attività fino a quando non vengono superati i Commit Tests

Il sistema di Continuous Integration è una risorsa condivisa per il team. Se viene effettivamente impiegato come descritto poc’anzi, con commit frequenti, ogni rottura della build implica un temporaneo blocco per il team e, di conseguenza, per il progetto. Questi inconvenienti, tuttavia, sono normali e da mettere in conto. L’importante è quindi che gli errori che li hanno causati vengano individuati e riparati nel minor tempo possibile.

Al momento del commit gli sviluppatori che lo hanno eseguito sono responsabili del monitoraggio della build della mainline. Fino a quando la compilazione della mainline non è terminata ed i commit tests sono stati eseguiti e superati sulle macchine dedicate alla Continuous Integration, gli sviluppatori non dovrebbero iniziare nuove attività, riunioni e pause pranzo incluse.

Se il commit va a buon fine, sono allora liberi di dedicarsi a nuove attività. Se fallisce sono già pronti per determinare la natura del problema e per risolverlo, con un nuovo commit o con un revert alla situazione precedente al commit che ha rotto la build. In questo secondo caso, le modifiche vengono quindi rimosse dalla mainline fino a quando non verranno ricommittate funzionanti.

Non committare se la build è rotta

Uno dei “peccati capitali” della Continuous Integration è il commit sulla build rotta. Se la build si rompe, gli sviluppatori che hanno causato la rottura stanno lavorando, o almeno dovrebbero, per risolvere il problema al più presto.

Se dei colleghi committano una o più modifiche che rompono la build (non facendola compilare o facendo fallire dei test automatici, per esempio), devono poter risalire al problema senza ostacoli, per risolverlo nel migliore dei modi. Ulteriori commit di modifiche, scateneranno nuove build che falliranno ed i cui risultati potrebbero mescolarsi con quelli della prima build che si è rotta, creando confusione.

Quando non viene rispettata questa regola, quindi, il fix della build richiede maggior tempo e, come conseguenza, le persone si “abituano” a vedere la build rotta e si arriva ad una situazione in cui la build rimane rotta per la maggior parte del tempo. Questo continua fino a che qualcuno nel team decide che “quando è troppo è troppo” e con un notevole sforzo ripara la build.

Mai andare a casa se la build è rotta

Lasciare la build rotta a fine giornata lavorativa, o peggio, a fine settimana non è una buona pratica. Al rientro in ufficio potrebbe esser necessario diverso tempo per rifocalizzare l’attenzione su quel che potrebbe aver rotto la build. Inoltre, il resto del team sarebbe costretto ad uno stop forzato ad inizio giornata o settimana lavorativa o peggio, a dover investire energie per aggirare il problema. Nel caso dei team distribuiti in punti con fusi orari diversi questo aspetto assume ancora maggiore criticità.

Per essere chiari, non è richiesto di rimanere in ufficio fino ad orari improponibili per sistemare una build, viceversa è raccomandato fare commit frequenti e lontani da orari-limite, in modo da aver tempo di fronteggiare eventuali anomalie. In alternativa, attendere il giorno successivo per committare. Molti sviluppatori esperti e molti team Agili definiscono un orario oltre il quale non si committa (ad esempio un’ora prima della fine dell’orario lavorativo) e tutti i commit non fatti oltre l’orario limite diventano la prima attività da svolgere nella prossima giornata lavorativa.

Sistemare immediatamente le build rotte

Questo è diretta conseguenza di quanto appena esposto.

Se la build della mainline fallisce, deve essere sistemata immediatamente. Non è un fatto negativo in se “rompere la build”, anche se una perseveranza di questo potrebbe indicare scarsa attenzione da parte degli sviluppatori nella fase pre- commit (build in locale su tutto).

Quando questo avviene, il ripristino della build assume priorità massima. Non è necessario che tutto il team si dedichi a ciò, di norma bastano una o due persone.

Spesso il metodo più rapido per sistemare la build è ripristinare la situazione all’ultimo commit fatto prima che si manifestasse il problema, riportando di fatto il sistema indietro. A meno che la causa del problema sia evidente, è buona norma lasciare la mainline aggiornata all’ultimo commit funzionante e ricercare il problema che ha rotto la build eseguendo debug su una singola workstation.

Essere sempre pronti a tornare alla versione precedente

Come abbiamo visto, la rottura della build è una cosa normale. Nei progetti di dimensioni importanti, è lecito aspettarsi che ciò avvenga almeno una o due volte al giorno, nonostante i test svolti in locale prima di committare modifiche allevino questo rischio.

In queste circostanze, i fix normalmente consistono in commit di poche righe di codice che risolvono bug in tempo rapidissimo.

Tuttavia, a volte, il compito è più arduo sia per un errore un po’ più “grave” del solito, e questo non significa colpevolizzare chi l’ha commesso, sia perché il bug non è di semplice individuazione e sia perché subito dopo il commit delle modifiche ed il successivo fail della build, si potrebbe realizzare di aver trascurato particolari importanti nell’implementare le modifiche appena committate. Indipendentemente dalla ragione, è importante ripristinare il corretto funzionamento della build alla svelta. Se il problema, per qualunque ragione, non può essere risolto rapidamente, occorre riportare la mainline alla situazione precedente al commit che ne ha rotto la build facendo revert della modifica.

L’approccio mentale suggerito è lo stesso, facendo un paragone, che hanno i piloti di aereo quando stanno per atterrare. Ovvero essere pronti a tornare indietro (“go around”) e fare un ulteriore tentativo nel caso qualcosa vada storto.

Definire un Time-Box per il fix della build rotta

Quando la build si rompe, investire non più di X minuti per sistemarla. Se dopo X minuti non è stata sistemata, procedere col revert della mainline alla versione precedente alla rottura, recuperabile dal versioning control system. L’entità di X è lasciata all’auto-regolamentazione dei team di sviluppo. In alcuni casi, se trascorso questo limite ci si sente confidenti di essere prossimi alla soluzione, si può ricorrere ad alcuni minuti extra. Ad esempio, se dopo dieci minuti si stà procedendo con la build locale, è ovviamente possibile terminare la build locale, procedere col commit e, nel caso la build sia tornata in uno stato funzionante, il fix si può considerare finito. Viceversa, procedere col revert e, con calma, a tutti i controlli del caso.

Mantenere la build rapida

Uno degli scopi della Continuous Integration è il fornire un rapido feedback. Nulla è più “stressante” di una build che dura “a lungo”. Sul concetto di “build lunga” si potrebbe discutere per giorni. Dipende dai punti di vista e dalle abitudini dei team. Alcuni potrebbero percepire come lunga una build della durata di un’ora, mentre altri sognano di avere una build che duri “solo” un’ora.

Le linee guida dell’Extreme Programming definiscono 10 minuti come durata ragionevole di una build e i progetti più moderni rispettano queste linee. Vale la pena sforzarsi affinché ciò avvenga. Ogni minuto di riduzione della build, è un minuto “regalato” agli sviluppatori ogni volta che loro committano (e che devono attendere l’esito della build della mainline…).

Non sempre è possibile ridurre “magicamente” l’intero processo di build alla durata desiderata.

La pratica consigliata, è l’impostazione di una deployment pipeline. L’idea dietro alla deployment pipeline (nota anche come build pipeline o staged build) è che, di fatto, ci sono build multiple eseguite in sequenza. Il commit sulla mainline scatena la build primaria, detta anche commit build, che è quella che deve essere veloce.

Una volta che la commit build è a posto, le altre persone possono lavorare sul codice con confidenza. Tuttavia ci possono essere ulteriori test, più lenti, che devono essere svolti. Questi possono, ad esempio, essere demandati a macchine dedicate e/o eseguiti in tempi diversi.

Un semplice esempio è una deployment pipeline a due stadi. Il primo si occupa della commit build, ovvero della compilazione e dell’esecuzione dei test unitari che non dipendono dai dati presenti su database. Questi test sono molto veloci e mantengono tutto il processo sotto i 10 minuti stabiliti. Tuttavia alcuni bug potrebbero non essere scovati dai test unitari, in particolare quelli eventualmente presenti in parti che richiedono interazioni più di larga scala, come ad esempio interazioni col database.

La build svolta al secondo livello (build secondaria) lancia una suite differente di test, più lenti, che verificano il comportamento del codice su dati presi dal database reale, testando così il comportamento del codice nel suo insieme piuttosto che nelle sue singole parti.

In questo scenario, il primo livello viene usato come ciclo principale di Continuous Integration. La build secondaria invece, viene eseguita (o schedulata) quando possibile, prelevando il codice eseguibile preparato dall’ultima build di primo livello andata a buon fine e svolgendo test ulteriori. Se questa seconda build fallisce, l’impatto sul team non è importante quanto quello che avrebbe un fallimento della commit build, tuttavia deve essere sistemata in tempi ragionevolmente rapidi.

Un bug rilevato dalla build secondaria spesso riguarda un problema rilevabile anche da uno o più test unitari eseguiti dalla commit build. In generale, ogni problema emerso ad un livello successivo al primo, porta allo sviluppo di nuovi test unitari da eseguire durante la commit build in modo da renderla sempre più efficace ed abbassare il rischio che i livelli successivi rilevino bug o malfunzionamenti.

Il principio può essere esteso a più livelli successivi. Le build secondarie possono anche essere eseguite in parallelo. Ad esempio se i test secondari durano due ore, si possono migliorare le performances distribuendoli equamente su due macchine che lavorano in parallelo. Parallelizzando le build secondarie in questo modo si può introdurre ogni sorta di test automatici all’interno del processo di build.

Testare in un clone dell’ambiente di Produzione

Lo scopo dei test è (anche) quello di eliminare ogni problema che il sistema potrebbe avere in produzione. L’ambiente in cui il sistema si troverà a girare in produzione è molto importante. Se i test vengono svolti in un ambiente differente, ogni differenza è sinonimo di rischio che quello che succede in ambiente di test non succederà in produzione.

La pratica ideale sarebbe quindi quella di impostare l’ambiente di test il più possibile uguale a quello di produzione. Utilizzare lo stesso software, alla stessa versione per il database, la stessa versione del sistema operativo. Tutte le librerie presenti nell’ambiente di produzione devono essere riportate nell’ambiente di test, anche se il sistema non le usa. Utilizzare gli stessi indirizzi IP, le stesse porte e lo stesso hardware.

In realtà ci sono dei limiti. Se si scrive, ad esempio, software per macchine desktop è praticamente impossibile testare su un clone di tutte le potenziali macchine su cui il sistema verrà installato (sic!). Similmente, alcuni ambienti di produzione sono molto costosi, impensabile quindi la loro duplicazione.

Nonostante questi limiti, l’obiettivo rimane quello di replicare l’ambiente di produzione al meglio e comprendere i rischi legati ad ogni differenza tra l’ambiente di test e quello di produzione.

Negli ultimi tempi ha acquisito sempre maggior popolarità il ricorso alla virtualizzazione, vale a dire più ambienti simulati su una stessa macchina fisica. Risulta quindi relativamente facile impostare uno o più ambienti virtuali all’interno dei quali svolgere i test.

Non escludere i test che falliscono

In presenza di una build rotta a causa del fallimento di alcuni test, gli sviluppatori tendono a commentare il codice di questi test, bloccandone l’esecuzione, in modo da poter committare agevolmente le proprie modifiche ed avere la build correttamente funzionante. Questo è comprensibile, ma sbagliato. Quando uno o più test che hanno sempre funzionato falliscono, può essere complicato scoprirne il motivo. Siamo veramente in presenza di regressione? Magari una o più assunzioni fatte dai test non sono più valide, oppure sono state fatte modifiche alla funzionalità testata per un motivo valido. Scoprire quale di queste condizioni si è verificata può coinvolgere più persone per un discreto periodo di tempo, ma è essenziale scoprire cosa stà succedendo e quindi sistemare il codice se si è introdotta regressione, modificare i test se la funzionalità ha cambiato comportamento o addirittura eliminarli nel caso non servano più.

L’esclusione dei test che falliscono deve essere vista come una extrema-ratio, a cui si deve ricorrere, ad esempio, se è necessario un importante ed articolato sviluppo.

Assumersi le proprie responsabilità

Assumersi la responsabilità degli inconvenienti che i propri commit potrebbero causare alla build della mainline.

Se i test scritti per la funzionalità introdotta o modificata passano, ma altri no, significa che è stata introdotta regressione.

E’ responsabilità di chi ha sviluppato questa funzionalità sistemare anche gli altri test che in seguito alla modifica hanno smesso di avere esito positivo.

Questa pratica ha diverse implicazioni. In primis gli sviluppatori devono avere accesso a tutto il codice impattato dalla propria modifica, in modo da poter sistemare ciò che si dovesse rompere. Questo esclude la possibilità che gli sviluppatori abbiano accesso esclusivo su una parte ristretta della codebase. Nella pratica di Continuous Integration, tutto il team ha accesso alla intera codebase. Nel caso questo non sia proprio possibile per cause non facilmente risolvibili, si deve per forza ricorrere alla collaborazione da parte di chi può mettere mano a certe parti della codebase.

Rendere gli ultimi eseguibili creati accessibili facilmente

Una delle parti più difficili dello sviluppo software è assicurare che venga buildato il software corretto. Abbiamo visto che è difficile specificare i requisiti corretti in anticipo. Le persone trovano molto più semplice notare qualcosa fatto in modo non completamente corretto e indicare i cambiamenti necessari. I processi Agili sono basati anche su questo comportamento umano.

Per aiutare in questo, chiunque è coinvolto in un progetto software deve poter avere gli ultimi eseguibili creati ed essere in grado di mandarli in esecuzione: per dimostrazioni, test esplorativi o anche semplicemente curiosità.

Fare questo è abbastanza semplice: basta assicurarsi che ci sia un posto noto dove le persone possono trovare gli ultimi eseguibili. Può essere utile mettere diversi eseguibili in questo posto. Oltre all’ultimissima versione, si potrebbe mettere anche l’ultima che ha passato i commit test, qualora questi test non fossero vincolanti al processo di build e costruzione degli eseguibili.

Se si segue un processo di sviluppo per iterazioni ben definite (sprint), è utile mettere anche l’eseguibile prodotto a seguito degli sviluppi fatti durante le ultime iterazioni concluse. In particolare le dimostrazioni necessitano di software con caratteristiche conosciute, in queste circostanze vale la pena sacrificare l’ultimissima versione disponibile a discapito di una versione le cui caratteristiche siano note a chi la deve presentare.

Chiunque è informato sulla build

La Continuous Integration si basa sulla comunicazione, bisogna quindi assicurare che tutti siano informati circa lo stato del sistema e delle modifiche che vi sono state apportate.

Una delle cose più importanti da comunicare è lo stato della build della mainline. Diversi tool per la gestione della Continuous Integration espongono interfacce web che forniscono questa informazione.

I team, nell’ambito della propria auto-organizzazione, possono assicurare queste informazioni adottando gli accorgimenti che ritengono opportuni. Alcuni team, ad esempio, connettono alle macchine adibite alla continuous integration dispositivi luminosi o sonori che emettono opportuni segnali (esempio luce rossa vs. luce verde, oppure fischi vs. applausi, o anche peggio…) a seconda dello stato della build.

Questo aspetto assume importanza strategica laddove si adotta un approccio manuale verso la Continuous Integration. Deve essere chiaro a tutto il team chi è il collega che ha la temporanea responsabilità della build della mainline.

I server Continuous Integration possono fornire ulteriori informazioni rispetto al semplice stato della build. Ad esempio possono fornire informazioni circa le modifiche apportate alla mainline ed i loro autori.

Non dimentichiamo che le informazioni esposte via web possono essere utili per i team distribuiti.

Automatizzare il Deployment

Per fare Continuous Integration servono diversi ambienti, uno per i commit tests, uno o più per i test secondari. Dal momento che vengono trasferiti eseguibili tra questi ambienti, più volte al giorno, è ideale farlo automaticamente. E’ quindi importante avere script che permettano di deployare facilmente l’applicazione in ogni ambiente utile ai fini di test.

Come conseguenza naturale di questo, si dovrebbero avere a disposizione script che permettono il deploy in produzione con la stessa facilità. Può non essere necessario deployare in produzione ogni giorno, ma avere a disposizione script per il deploy automatico aiuta ad accelerare il processo ed a ridurre gli errori.

Se si procede col deploy automatico in produzione, occorre considerare anche il rollback automatico. Bisogna essere in grado di poter riportare l’ambiente di produzione alla versione precedentemente installata e funzionante, nel caso emergano malfunzionamenti non rilevati in sede di test. La possibilità di poter svolgere automaticamente questo passo indietro riduce la tensione all’interno del team e del dipartimento, incoraggia le persone a deployare più frequentemente, e quindi a fornire agli utenti nuove funzionalità rapidamente.

Oltre al trasferimento degli eseguibili tra i server, gli script introdotti precedentemente hanno anche responsabilità di apportare eventuali modifiche all’ambiente in cui l’applicazione dovrà operare. Devono quindi essere incluse in questi script le modifiche al sistema operativo, ai server web ed alle macchine virtuali, se previste, al database. Le stesse responsabilità, ovviamente al contrario, devono essere assunte dagli script di rollback.

Questi processi possono essere gestiti sia tramite “semplici” script bash o batch, che tramite l’impiego di tool atti allo scopo (Ansible, Puppet, …) alcuni dei quali (Docker) orchestrano il rilascio completo dell’applicazione e di “tutto quel che le serve per funzionare” su di un server web.

Pubblicato da Vito Lavecchia

Lavecchia Vito Ingegnere Informatico (Politecnico di Bari) Email: [email protected] Sito Web: https://vitolavecchia.altervista.org

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *