Come si usa GitHub Actions per creare flussi di lavoro per l'integrazione continua?
Tenere presente che l'obiettivo è automatizzare il processo di compilazione e pubblicazione del codice in modo che le funzionalità vengano aggiornate ogni volta che uno sviluppatore aggiunge una modifica alla codebase.
Per implementare questo processo, si apprenderà come:
- Creare un flusso di lavoro da un modello.
- Evitare la duplicazione usando flussi di lavoro riutilizzabili.
- Eseguire test su più obiettivi.
- Separare i processi di compilazione e test.
Creare un flusso di lavoro da un modello
Per creare un flusso di lavoro, è comune iniziare usando un modello. Un modello include processi e passaggi comuni preconfigurati per il tipo specifico di automazione che si sta implementando. Se non si ha familiarità con flussi di lavoro, processi e passaggi, vedere il modulo Automatizzare le attività di sviluppo usando GitHub Actions .
Nella pagina principale del repository GitHub selezionare Azioni e quindi selezionare Nuovo flusso di lavoro.
Nella pagina Scegliere un flusso di lavoro è possibile scegliere tra molti tipi di modelli. Un esempio è il modello di Node.js. Il modello diNode.js installa Node.js e tutte le dipendenze, compila il codice sorgente ed esegue test per versioni diverse di Node.js. Un altro esempio è il modello di pacchetto Python , che installa Python e le relative dipendenze e quindi esegue i test, incluso lint, in più versioni di Python.
Per iniziare con il modello di flusso di lavoro Node.js, nella casella di ricerca immettere Node.js.
Nei risultati della ricerca, nel riquadro Node.jsselezionare Configura.
Un node.js.yml file per il progetto viene creato dal modello:
name: Node.js CI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
Come illustrato nell'attributo on , questo flusso di lavoro di esempio viene eseguito in risposta a un push nel repository o quando viene creata una richiesta pull nel ramo principale.
Questo flusso di lavoro esegue un processo, indicato dall'attributo job .
L'attributo runs-on specifica che, per il sistema operativo, il flusso di lavoro viene eseguito in ubuntu-latest. L'attributo node-version specifica che sono presenti tre build, ognuna per Node.js versione 14.x, 16.x e 18.x. L'attributo matrix viene descritto in dettaglio più avanti nel modulo.
Nell'attributo jobs i passaggi usano l'azione GitHub Actions /checkout@v3 per ottenere il codice dal repository in una macchina virtuale (VM) e azioni/setup-node@v3 per configurare la versione corretta di Node.js. Si specifica di voler testare tre versioni di Node.js usando l'attributo ${{ matrix.node-version }} . Questo attributo fa riferimento alla matrice definita in precedenza. L'attributo cache specifica una gestione pacchetti per la memorizzazione nella cache nella directory predefinita.
L'ultima parte di questo passaggio esegue i comandi che i progetti Node.js utilizzano. Il npm ci comando installa le dipendenze dal package-lock.json file.
npm run build --if-present esegue uno script di compilazione, se esistente.
npm test esegue il framework di test. Questo modello include sia passaggi di compilazione che di test nello stesso processo.
Per altre informazioni su npm, vedere la documentazione di npm:
Un team di sviluppatori può trarre vantaggio dall'uso di flussi di lavoro riutilizzabili per semplificare e standardizzare i passaggi di automazione ripetuti. Usando flussi di lavoro riutilizzabili, è possibile ridurre la ridondanza, migliorare la gestibilità e garantire la coerenza tra le pipeline di integrazione continua/distribuzione continua (CI/CD).
Evitare la duplicazione usando flussi di lavoro riutilizzabili
Man mano che i team aumentano le dimensioni e i progetti, è comune vedere gli stessi passaggi ripetuti in più file del flusso di lavoro. Questi passaggi possono includere il checkout del codice, l'installazione delle dipendenze, il test e la distribuzione. Questo tipo di duplicazione non solo complica la codebase, ma aumenta anche il tempo di manutenzione quando è necessario apportare modifiche al codice. I flussi di lavoro riutilizzabili risolveno questo problema consentendo di definire la logica di automazione una sola volta e quindi chiamare la logica da altri flussi di lavoro.
I flussi di lavoro riutilizzabili sono flussi di lavoro speciali di GitHub Actions che altri flussi di lavoro possono chiamare, in modo analogo alle funzioni nella programmazione. È possibile crearli per condividere la logica ripetuta, ad esempio passaggi di compilazione, procedure di test o strategie di distribuzione. Dopo aver creato un flusso di lavoro riutilizzabile, è possibile farvi riferimento da qualsiasi altro flusso di lavoro nello stesso repository o anche in repository diversi.
Perché usare flussi di lavoro riutilizzabili?
Questi sono i vantaggi dell'uso di flussi di lavoro riutilizzabili:
- Coerenza. Teams può seguire gli stessi standard di automazione in tutti i progetti.
- Efficienza. Invece di copiare e incollare i passaggi, è sufficiente puntare a un flusso di lavoro riutilizzabile.
- Aggiornamenti più semplici. Quando un processo cambia, ad esempio aggiungendo un passaggio di test, lo si aggiorna in un'unica posizione. Quindi, tutti i flussi di lavoro che usano il flusso di lavoro sfruttano automaticamente i vantaggi.
- Scalabilità. I flussi di lavoro riutilizzabili sono ideali per i team di piattaforma o DevOps che gestiscono più servizi.
Si esamini quindi come usare flussi di lavoro riutilizzabili per migliorare i progetti.
Implementare flussi di lavoro riutilizzabili
Per usare flussi di lavoro riutilizzabili:
- Nella cartella del repository creare un flusso di lavoro riutilizzabile. Il file include i passaggi di automazione da condividere, ad esempio i passaggi comuni relativi a test, compilazione e distribuzione.
- Abilitare in modo esplicito un flusso di lavoro per essere riutilizzabile configurandolo con l'evento
workflow_call. - Nei flussi di lavoro principali (flussi di lavoro chiamanti), fare riferimento a questo file riutilizzabile e fornire input o segreti richiesti.
Per illustrare i vantaggi dei flussi di lavoro riutilizzabili, prendere in considerazione lo scenario reale seguente.
Esempio
Si supponga che l'organizzazione disponga di 10 microservizi. Tutti i 10 microservizi richiedono gli stessi passaggi per:
- Esecuzione dei test
- Codice Lint
- Eseguire la distribuzione in un ambiente specifico
Senza flussi di lavoro riutilizzabili, ogni repository finisce per duplicare la stessa logica tra più file del flusso di lavoro, causando passaggi ripetuti e manutenzione più difficile.
Se si usano flussi di lavoro riutilizzabili:
- Il processo viene definito una sola volta in un file centrale, ad esempio in
ci-standard.yml. - Questo file viene chiamato dal flusso di lavoro di ogni microservizio, passando variabili come l'ambiente o il nome dell'applicazione.
Se viene aggiunto un nuovo passaggio o uno strumento di sicurezza, ad esempio per analizzare le vulnerabilità, aggiungerlo una sola volta nel flusso di lavoro riutilizzabile. Tutti i 10 microservizi iniziano immediatamente a usare il processo aggiornato. Non è necessario modificare i 10 microservizi.
Comprendendo come funzionano i flussi di lavoro riutilizzabili e i relativi vantaggi, è possibile adottare procedure consigliate per massimizzare l'efficacia e garantire una perfetta integrazione con le pipeline CI/CD.
Procedure consigliate
- Centralizzare i flussi di lavoro riutilizzabili in un repository se si prevede di condividerli tra team.
- Usare rami o tag per la versione dei flussi di lavoro (ad esempio, usare
@v1), in modo da poter eseguire facilmente il rollback delle modifiche, se necessario. - Documentare gli input e i segreti in modo chiaro. I flussi di lavoro riutilizzabili spesso si basano su input e segreti. I team devono sapere quali informazioni utilizzare.
- Se è necessario riutilizzare solo alcuni passaggi, combinare flussi di lavoro riutilizzabili con azioni composite anziché creare un flusso di lavoro completo.
I flussi di lavoro riutilizzabili sono un modo efficace per applicare coerenza, ridurre la duplicazione e ridimensionare le procedure DevOps in qualsiasi team di progettazione. Che tu stia gestendo un singolo repository, microservizi o librerie open source, i flussi di lavoro riutilizzabili possono semplificare l'automazione, rendendo il tuo CI/CD più veloce, pulito e facile da gestire.
Personalizzare i modelli di flusso di lavoro
All'inizio di questo modulo hai considerato uno scenario in cui devi configurare CI/CD per il tuo team di sviluppatori. Il modello di Node.js è un ottimo punto di partenza, ma si vuole personalizzarlo in base ai requisiti del team. Si vogliono usare versioni diverse di Node.js e sistemi operativi diversi. Si vuole anche che i passaggi di compilazione e test siano processi separati.
Ecco un esempio di flusso di lavoro personalizzato:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [16.x, 18.x]
In questo esempio viene configurata una matrice di compilazione per il test in più sistemi operativi e versioni del linguaggio. Questa matrice produce quattro build, una per ogni sistema operativo associato a ogni versione di Node.js.
Quattro build e i relativi test producono una grande quantità di dati di log. Potrebbe essere difficile ordinare tutto. L'esempio seguente illustra come spostare il passaggio del test in un processo di test dedicato. Questo processo esegue test su più destinazioni. La separazione dei passaggi di compilazione e test semplifica l'uso dei dati di log.
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [16.x, 18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: npm install, and test
run: |
npm install
npm test
env:
CI: true