Pipeline GitHub Actions: Guida Semplice

Le GitHub Actions rappresentano una delle funzionalità più potenti di GitHub per automatizzare workflow di sviluppo software. In questa guida imparerai come creare la tua prima pipeline CI/CD in modo semplice e pratico.

Cosa sono le GitHub Actions

Le GitHub Actions sono un sistema di automazione CI/CD integrato in GitHub che permette di eseguire codice in risposta a eventi specifici nel repository. Puoi utilizzarle per costruire, testare e distribuire il tuo codice direttamente da GitHub, creando pipeline di deployment automatizzate per il tuo progetto.

Vantaggi principali

  • Integrazione nativa: Direttamente integrata con GitHub
  • Flessibilità: Supporta qualsiasi linguaggio di programmazione
  • Automazione completa: Dai test al deployment in produzione
  • Community: Migliaia di actions precostruite disponibili

Runner hosting: dove vengono eseguite le pipeline GitHub Actions

Un aspetto importante da comprendere è che le GitHub Actions vengono eseguite su runner hosted forniti gratuitamente da GitHub. Questo significa che:

Vantaggi dei runner hosted

  • Nessuna configurazione richiesta: Non devi installare server o configurare infrastrutture
  • Ambienti pre-configurati: I runner includono già strumenti comuni per lo sviluppo
  • Sistemi operativi multipli: Puoi scegliere tra Ubuntu, Windows e macOS
  • Risorse dedicate: Ogni job viene eseguito in un ambiente pulito e isolato

Runner self-hosted per progetti avanzati

Se hai esigenze specifiche per la tua pipeline CI/CD, puoi anche configurare runner self-hosted sui tuoi server:

  • Controllo completo: Puoi installare software personalizzato e configurare l’ambiente
  • Risorse dedicate: Utilizzi le tue risorse hardware senza limitazioni di tempo
  • Sicurezza: Mantieni il codice e i dati nel tuo ambiente controllato
  • Costi: Eviti i costi dei runner hosted per progetti con molte esecuzioni

Raccomandazione: Per la maggior parte dei progetti, i runner hosted sono più che sufficienti e rappresentano la scelta più semplice per iniziare con le GitHub Actions.

Configurazione iniziale per il tuo primo workflow

Struttura delle directory per GitHub Actions

Per iniziare con le GitHub Actions, devi creare una cartella specifica nel tuo repository:

.github/
└── workflows/
    └── nome-workflow.yml

Importante: Tutti i file di workflow devono essere salvati nella directory .github/workflows/ e avere estensione .yml o .yaml.

Anatomia di un workflow GitHub Actions

Un workflow di GitHub Actions è composto da diversi elementi chiave:

  • Evento trigger: definisce quando il workflow viene eseguito (push, pull request, etc.)
  • Job: un gruppo di step che vengono eseguiti sullo stesso runner
  • Step: singole attività che compongono un job
  • Action: componenti riutilizzabili che eseguono compiti specifici

Convenzioni di naming per workflow

Per mantenere i tuoi workflow organizzati:

  • Usa nomi descrittivi: ci.yml, deploy-production.yml
  • Evita spazi nei nomi dei file
  • Raggruppa workflow simili con prefissi comuni

Tutorial: creazione della prima pipeline CI/CD

Esempio pratico: Pipeline automatizzata per progetto Node.js

Creiamo un workflow semplice per un progetto Node.js che esegue test automatici e deployment:

name: CI Pipeline

# Definisce quando il workflow viene eseguito
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

# Definisce i job da eseguire
jobs:
  test:
    # Sistema operativo su cui eseguire il job
    runs-on: ubuntu-latest
    
    steps:
    # Checkout del codice
    - name: Checkout repository
      uses: actions/checkout@v4
    
    # Setup di Node.js
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '18'
        cache: 'npm'
    
    # Installazione delle dipendenze
    - name: Install dependencies
      run: npm ci
    
    # Esecuzione dei test
    - name: Run tests
      run: npm test
    
    # Esecuzione del linting
    - name: Run linting
      run: npm run lint

Spiegazione dettagliata del workflow

Il workflow sopra implementa una pipeline CI/CD completa che esegue le seguenti operazioni:

Trigger automatici

Quando si attiva: Il workflow si attiva automaticamente quando viene fatto push sui branch main o develop, oppure quando viene aperta una pull request verso main.

Pipeline di test automatizzata

Job di test: Esegue una serie di step sequenziali su un ambiente Ubuntu:

  1. Checkout del codice: Scarica il codice dal repository usando l’action ufficiale di GitHub
  2. Setup ambiente: Configura Node.js versione 18 con cache npm per ottimizzare i tempi
  3. Installazione dipendenze: Installa le dipendenze usando npm ci (più veloce di npm install)
  4. Esecuzione test: Esegue i test del progetto per verificare la qualità del codice
  5. Controllo qualità: Esegue il linting per mantenere standard di codice consistenti

Tip: Questo workflow fornisce feedback immediato agli sviluppatori, bloccando merge di codice che non passa i test.

GitHub Actions più utilizzate

Durante la creazione delle tue pipeline, utilizzerai spesso actions pre-costruite dalla community. Ecco le più comuni e utili:

:warning: Importante: Sicurezza delle Actions

Limitare l’uso di actions di terze parti: È buona pratica ridurre al minimo l’utilizzo di actions esterne per evitare potenziali rischi di sicurezza. Ogni action di terze parti rappresenta codice che viene eseguito nel tuo ambiente con accesso al repository.

Analisi accurata: Prima di utilizzare qualsiasi action esterna, verifica sempre:

  • Reputazione del maintainer: Controlla chi mantiene l’action
  • Codice sorgente: Esamina il codice per comprendere cosa fa
  • Versioni fisse: Usa sempre versioni specifiche (es. @v4) non @main
  • Permessi richiesti: Verifica quali permessi necessita l’action
  • Vulnerabilità note: Controlla se ci sono segnalazioni di sicurezza

Preferire actions ufficiali: Quando possibile, usa actions mantenute da GitHub o organizzazioni affidabili come actions/*.

Actions comunemente usate

actions/checkout

  • Funzione: Scarica il codice del repository nel runner
  • Utilizzo: Sempre necessaria come primo step
  • Esempio: uses: actions/checkout@v4

actions/setup-node

  • Funzione: Configura Node.js e npm/yarn nel runner
  • Utilizzo: Per progetti JavaScript, TypeScript, React, etc.
  • Esempio: uses: actions/setup-node@v4

actions/setup-python

  • Funzione: Configura Python e pip nel runner
  • Utilizzo: Per progetti Python, Django, Flask, etc.
  • Esempio: uses: actions/setup-python@v4

actions/setup-java

  • Funzione: Configura Java JDK nel runner
  • Utilizzo: Per progetti Java, Spring, Android, etc.
  • Esempio: uses: actions/setup-java@v4

Actions per artefatti e cache

actions/cache

  • Funzione: Memorizza e riutilizza file tra esecuzioni
  • Utilizzo: Velocizza build cachando dipendenze
  • Esempio: Cache di node_modules o .m2 di Maven

actions/upload-artifact

  • Funzione: Salva file prodotti dal workflow
  • Utilizzo: Conserva build, report, log per download
  • Esempio: Upload di file JAR, bundle JS, report di test

actions/download-artifact

  • Funzione: Scarica artefatti da job precedenti
  • Utilizzo: Condivide file tra job diversi
  • Esempio: Download di build per deploy

Actions per deployment

peaceiris/actions-gh-pages

  • Funzione: Pubblica siti statici su GitHub Pages
  • Utilizzo: Deploy automatico di documentazione o siti
  • Esempio: Deploy di siti React, Vue, Jekyll

azure/webapps-deploy

  • Funzione: Deploy su Azure App Service
  • Utilizzo: Deployment di applicazioni web su Azure
  • Esempio: Deploy di app Node.js, Python, .NET

Actions per qualità del codice

github/super-linter

  • Funzione: Esegue linting su multipli linguaggi
  • Utilizzo: Controllo qualità codice automatico
  • Esempio: Linting di JavaScript, Python, YAML, Dockerfile

codecov/codecov-action

  • Funzione: Carica report di copertura codice
  • Utilizzo: Monitoraggio copertura test
  • Esempio: Integration con Codecov per metriche

Come trovare altre actions

Puoi cercare actions aggiuntive su:

  • GitHub Marketplace: marketplace.github.com
  • Actions repository: Cerca repository con tag github-actions
  • Community: Molte organizzazioni pubblicano le proprie actions

Quando scegli un’action, verifica sempre:

  • Numero di stelle e utilizzi
  • Frequenza degli aggiornamenti
  • Documentazione disponibile
  • Sicurezza e affidabilità del maintainer

Organizzazione di workflow multipli per progetti complessi

Struttura avanzata per progetti enterprise

Quando il tuo progetto cresce e diventa più complesso, potresti aver bisogno di organizzare più workflow GitHub Actions separati. Ecco come strutturarli efficacemente:

.github/
└── workflows/
    ├── ci.yml              # Continuous Integration
    ├── deploy-prod.yml     # Deploy in produzione
    ├── deploy-staging.yml  # Deploy in staging
    ├── security-scan.yml   # Scansione sicurezza
    ├── docs-build.yml      # Generazione documentazione
    └── cleanup.yml         # Pulizia artefatti

Convenzioni di naming per workflow professionali

Nomi descrittivi per pipeline CI/CD:

  • ci.yml - Continuous Integration (test, build, quality check)
  • deploy-prod.yml - Deploy in produzione
  • deploy-staging.yml - Deploy in ambiente staging
  • test-e2e.yml - Test end-to-end automatizzati
  • security-scan.yml - Scansione sicurezza e vulnerabilità
  • performance-test.yml - Test di performance

Separazione logica dei workflow:

  • Frequenza di esecuzione: Test frequenti vs deploy occasionali
  • Ambiente target: Sviluppo, staging, produzione
  • Scopo funzionale: Build, test, deploy, sicurezza
  • Team responsibility: Frontend, backend, DevOps

Esempi di workflow separati

ci.yml - Pipeline di integrazione continua:

name: Continuous Integration
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      - name: Install dependencies
        run: npm ci
      - name: Run tests
        run: npm test
      - name: Run linting
        run: npm run lint

deploy-prod.yml - Deploy in produzione:

name: Production Deployment
on:
  push:
    branches: [main]
    
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
      - name: Build for production
        run: npm run build
      - name: Deploy to production
        run: npm run deploy:prod

Best Practice: Separare i workflow per ambiente permette di avere controlli diversi (es. approvazioni manuali per produzione) e configurazioni specifiche per ogni ambiente.

Gestione delle dipendenze tra job nelle pipeline

Job sequenziali con GitHub Actions

Usa la keyword needs per creare dipendenze tra job e costruire pipeline più sofisticate:

name: Complete CI/CD Pipeline

on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run unit tests
        run: npm test

  build:
    runs-on: ubuntu-latest
    needs: test  # Esegue solo se test ha successo
    steps:
      - uses: actions/checkout@v4
      - name: Build application
        run: npm run build
      - name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: build-files
          path: dist/

  deploy:
    runs-on: ubuntu-latest
    needs: [test, build]  # Dipende da entrambi i job
    steps:
      - uses: actions/checkout@v4
      - name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: build-files
      - name: Deploy to production
        run: npm run deploy

Vantaggi delle dipendenze tra job

Controllo del flusso: I job dipendenti vengono eseguiti solo se i prerequisiti hanno successo, evitando deployment di codice non testato.

Ottimizzazione risorse: Job indipendenti vengono eseguiti in parallelo per velocizzare la pipeline, mentre quelli dipendenti seguono l’ordine logico.

Gestione errori: Se un job fallisce, tutti i job dipendenti vengono automaticamente cancellati, risparmiando risorse.

Tip: Usa le dipendenze per costruire pipeline robuste che rispettano il flusso logico del tuo processo di sviluppo (test → build → deploy).

Best practices

Organizzazione del codice

  • Nomi descrittivi: Usa nomi chiari per workflow e step
  • Commenti: Documenta workflow complessi
  • Riutilizza: Sfrutta actions esistenti dal marketplace

Ottimizzazione delle prestazioni

  • Cache: Utilizza la cache per dipendenze e build artifacts
  • Parallelizzazione: Esegui job indipendenti in parallelo
  • Trigger selettivi: Configura trigger appropriati per evitare esecuzioni inutili

Sicurezza

  • Secrets: Non inserire mai credenziali direttamente nel codice
  • Permissions: Concedi solo i permessi minimi necessari
  • Review: Controlla sempre le actions di terze parti prima dell’uso

Limiti e considerazioni per GitHub Actions

Limiti dei runner hosted GitHub

È importante conoscere i limiti dei runner gratuiti forniti da GitHub per pianificare correttamente le tue pipeline CI/CD:

Limiti di tempo per GitHub Actions

  • Repository pubblici: 6 ore per job, 20 job contemporanei
  • Repository privati: 2.000 minuti/mese gratuiti, poi a pagamento
  • Timeout automatico: Ogni job ha un timeout massimo di 6 ore
  • Coda di esecuzione: I job possono rimanere in coda se tutti i runner sono occupati

Limiti di storage e artefatti

  • Artifacts: 500 MB per singolo artifact, 1 GB totale per repository
  • GitHub Actions Cache: 10 GB di spazio cache per repository
  • Retention period: Artifacts conservati per 90 giorni (configurabile)
  • Log retention: Log dei workflow conservati per 90 giorni

Limiti di risorse hardware

  • CPU: 2 core per job su runner hosted
  • RAM: 7 GB di memoria disponibile per job
  • Storage: 14 GB di spazio disco SSD temporaneo
  • Rete: Buona connettività per download dipendenze

Ottimizzazione per ridurre i costi delle pipeline

Strategie per repository privati

  • Usa cache intelligente: Implementa cache per dipendenze frequenti (node_modules, .m2, pip cache)
  • Test selettivi: Esegui solo test necessari per ogni branch o path modificato
  • Trigger specifici: Configura trigger precisi per evitare esecuzioni inutili
  • Parallelizzazione: Usa job paralleli per ridurre tempo totale di esecuzione
  • Runner self-hosted: Considera runner propri per progetti con molte esecuzioni

Monitoraggio del consumo GitHub Actions

  • Billing dashboard: Controlla l’uso dei minuti in Settings > Billing
  • Spending limits: Configura limiti di spesa per evitare costi inattesi
  • Workflow analytics: Analizza quali workflow consumano più risorse
  • Ottimizzazione continua: Monitora e ottimizza i workflow più costosi

Quando considerare runner self-hosted

I runner self-hosted possono essere utili quando:

  • Hai bisogno di risorse superiori ai limiti dei runner hosted
  • Richiedi software specifico non disponibile negli ambienti standard
  • Vuoi ridurre i costi per progetti con molte esecuzioni
  • Necessiti di accesso a risorse interne della rete aziendale
  • Hai requisiti di sicurezza che richiedono controllo completo dell’ambiente

Conclusione

Le GitHub Actions offrono un modo potente e flessibile per automatizzare i workflow di sviluppo. Iniziando con pipeline semplici come quelle mostrate in questa guida, potrai gradualmente espandere e personalizzare i tuoi workflow per soddisfare le esigenze specifiche del tuo progetto.

Il prossimo passo è sperimentare con il tuo repository: crea un file workflow, eseguilo e osserva i risultati. Con la pratica, diventerai sempre più esperto nell’utilizzo di questo strumento fondamentale per lo sviluppo moderno.