CI/CD con GitHub Actions: Guida Completa 2025

THEJORD Team5 min di lettura
githubcicddevopsautomation

CI/CD con GitHub Actions: workflow, jobs, deploy automatico. Guida completa 2025 per automatizzare build, test e deployment dei tuoi progetti software.

CI/CD con GitHub Actions: Guida Completa 2025

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

ComponenteDescrizione
WorkflowFile YAML in .github/workflows/
EventTrigger che avvia il workflow
JobGruppo di step su un runner
StepSingola operazione (action o comando)
ActionOperazione riutilizzabile
RunnerMacchina 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: @v4 non @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:

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.