CI/CD con GitHub Actions: Guida Completa 2025
CI/CD con GitHub Actions: workflow, jobs, deploy automatico. Guida completa 2025 per automatizzare build, test e deployment dei tuoi progetti software.
Introduzione a GitHub Actions
GitHub Actions è la piattaforma di CI/CD integrata in GitHub che permette di automatizzare build, test e deployment direttamente nei repository. Con un ecosistema ricco di action predefinite e la flessibilità di eseguire qualsiasi script, è diventato lo strumento preferito per l'automazione nel mondo open source e enterprise.
Concetti Fondamentali
Anatomia di un Workflow
# .github/workflows/ci.yml
name: CI Pipeline # Nome del workflow
on: # Trigger events
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs: # Gruppi di step
build:
runs-on: ubuntu-latest # Runner environment
steps: # Singole operazioni
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install
run: npm ci
- name: Test
run: npm test
Componenti Chiave
| Componente | Descrizione |
|---|---|
| Workflow | File YAML in .github/workflows/ |
| Event | Trigger che avvia il workflow |
| Job | Gruppo di step su un runner |
| Step | Singola operazione (action o comando) |
| Action | Operazione riutilizzabile |
| Runner | Macchina che esegue i job |
Trigger Events
Push e Pull Request
on:
push:
branches:
- main
- 'release/**' # Pattern wildcard
paths:
- 'src/**' # Solo se modificati file in src/
paths-ignore:
- '**.md' # Ignora modifiche ai markdown
pull_request:
types: [opened, synchronize, reopened]
branches: [main]
Schedule e Manual
on:
# Cron schedule (UTC)
schedule:
- cron: '0 3 * * *' # Ogni giorno alle 3:00 UTC
# Trigger manuale
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'staging'
type: choice
options:
- staging
- production
# Chiamato da altro workflow
workflow_call:
inputs:
version:
required: true
type: string
Jobs e Parallelismo
Jobs Paralleli
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
# Lint e test eseguono in parallelo
Jobs Dipendenti
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: npm run build
test:
needs: build # Attende build
runs-on: ubuntu-latest
steps:
- run: npm test
deploy:
needs: [build, test] # Attende entrambi
runs-on: ubuntu-latest
steps:
- run: npm run deploy
Matrix Strategy
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [18, 20, 22]
fail-fast: false # Continua anche se uno fallisce
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
Variabili e Secrets
Environment Variables
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_ENV: production
API_URL: https://api.example.com
steps:
- name: Use env vars
run: |
echo "Environment: $NODE_ENV"
echo "API: ${{ env.API_URL }}"
- name: Set output
id: vars
run: echo "version=1.0.0" >> $GITHUB_OUTPUT
- name: Use output
run: echo "Version: ${{ steps.vars.outputs.version }}"
Secrets
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy
env:
AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 sync build/ s3://my-bucket/
# Non loggare mai secrets!
# GitHub li maschera automaticamente nei log
Actions Comuni
Checkout e Setup
steps:
# Checkout repository
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history per git operations
# Setup Node.js
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # Cache automatica node_modules
# Setup Python
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
# Setup Docker Buildx
- uses: docker/setup-buildx-action@v3
Caching
steps:
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
# Cache più avanzata con cache-dependency-path
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
Upload/Download Artifacts
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 5
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: build-output
path: dist/
- run: ls -la dist/
Deployment Patterns
Deploy to Vercel
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod'
Deploy to AWS
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- name: Deploy to S3
run: aws s3 sync dist/ s3://my-bucket/
- name: Invalidate CloudFront
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.CF_DISTRIBUTION_ID }} \
--paths "/*"
Docker Build and Push
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: myuser/myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
Testing Workflow
Test con Coverage
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run test:coverage
- uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage/lcov.info
E2E con Playwright
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npx playwright install --with-deps
- run: npm run test:e2e
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
Environments e Protezioni
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- run: echo "Deploying to staging"
deploy-production:
runs-on: ubuntu-latest
needs: deploy-staging
environment:
name: production
url: https://myapp.com
steps:
- run: echo "Deploying to production"
# Richiede approval manuale se configurato
Best Practices
Sicurezza
- Usa secrets per credenziali, mai hardcode
- Pin action versions:
@v4non@main - Limita permissions del GITHUB_TOKEN
- Usa environments per deployment sensibili
Performance
- Usa caching aggressivo
- Parallelizza jobs indipendenti
- Usa matrix per test multi-versione
- Fail fast quando appropriato
Troubleshooting
Quando un workflow fallisce, controlla prima i log nella tab Actions del repository. I log mostrano l'output di ogni step e l'errore specifico. Per errori intermittenti, considera il re-run. Per debug avanzato, abilita il debug logging impostando i secrets ACTIONS_RUNNER_DEBUG e ACTIONS_STEP_DEBUG a true. Verifica che i secrets siano configurati correttamente e che il token abbia i permessi necessari.
Strumenti Correlati
Per CI/CD e automazione:
- JSON Formatter - Valida configurazioni
- Cron Builder - Genera espressioni cron
- Diff Checker - Confronta versioni workflow
Conclusione
GitHub Actions è potente e flessibile. Punti chiave:
- Inizia semplice, aggiungi complessità quando serve
- Usa caching per velocizzare i build
- Proteggi secrets e deployment production
- Sfrutta matrix per test cross-platform
- Monitora usage per ottimizzare costi
Per altri strumenti utili, esplora i nostri tool online gratuiti. Per documentazione completa, consulta GitHub Actions Documentation.