GitHub Actions per Developer: CI/CD Completo nel 2026

GitHub Actions è diventato lo standard de-facto per CI/CD nel 2026 — gratuito per repository pubblici, 2.000 minuti/mese gratuiti per quelli privati, e con un ecosistema di migliaia di action pronte all’uso. Per un developer JavaScript che lavora con Next.js, React o Node.js, una pipeline CI/CD ben configurata è la differenza tra deploy ansiosi e rilasci sereni. In questa guida costruiamo una pipeline completa: test automatici, build, deploy preview su Vercel e deploy di produzione — tutto automatizzato.

Struttura di un workflow YAML

Un workflow GitHub Actions è un file YAML nella cartella .github/workflows/. La struttura di base:

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  NODE_VERSION: "20"

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: "npm"
      - run: npm ci
      - run: npm run lint
      - run: npm run type-check
      - run: npm run test
      - run: npm run build

Ogni run è un comando shell. Se uno fallisce, il workflow si ferma e la PR viene marcata come “failing” — il developer riceve una notifica immediata.

CI completo: lint, type-check, test, build

Un pipeline CI professionale per un progetto Next.js/TypeScript:

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: ["**"]  # tutti i branch
  pull_request:
    branches: [main]

jobs:
  quality:
    name: Quality Checks
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Type check
        run: npx tsc --noEmit

      - name: Run tests
        run: npm run test -- --coverage
        env:
          CI: true

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: false

      - name: Build
        run: npm run build
        env:
          NEXT_PUBLIC_API_URL: ${{ vars.NEXT_PUBLIC_API_URL }}

Cache npm per build veloci

La cache di node_modules riduce il tempo del workflow da 2-3 minuti a 30-45 secondi. L’opzione cache: "npm" nel setup-node action gestisce tutto automaticamente — invalida la cache quando cambia package-lock.json. Per monorepo con workspaces:

- uses: actions/setup-node@v4
  with:
    node-version: "20"
    cache: "npm"
    cache-dependency-path: |
      package-lock.json
      apps/*/package-lock.json
      packages/*/package-lock.json

Deploy preview su Vercel per ogni PR

Ogni PR ottiene automaticamente un URL di preview univoco — fondamentale per review visive senza toccare la produzione:

# .github/workflows/preview.yml
name: Deploy Preview

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  deploy-preview:
    runs-on: ubuntu-latest
    environment: preview
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to Vercel (Preview)
        uses: amondnet/vercel-action@v25
        id: vercel-preview
        with:
          vercel-token:   ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id:  ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          github-token:   ${{ secrets.GITHUB_TOKEN }}
          scope:          ${{ secrets.VERCEL_ORG_ID }}

      - name: Comment PR with preview URL
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '🚀 **Preview deploy**: ${{ steps.vercel-preview.outputs.preview-url }}'
            })

Deploy di produzione su merge in main

# .github/workflows/deploy.yml
name: Deploy Production

on:
  push:
    branches: [main]

jobs:
  # Riesegui CI prima del deploy
  test:
    uses: ./.github/workflows/ci.yml

  deploy-production:
    needs: test
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Deploy to Vercel (Production)
        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"
          github-token:      ${{ secrets.GITHUB_TOKEN }}

      - name: Notify on Slack
        if: always()
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {"text": "Deploy ${{ job.status }}: ${{ github.repository }}@${{ github.sha }}"}
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Matrix strategy: test su più versioni Node

Per librerie o package npm che devono supportare più versioni di Node, la matrix strategy esegue i test in parallelo su tutte le versioni:

jobs:
  test-matrix:
    strategy:
      matrix:
        node-version: ["18", "20", "22"]
        os: [ubuntu-latest, windows-latest]
      fail-fast: false  # continua gli altri anche se uno fallisce
    runs-on: ${{ matrix.os }}
    name: Test Node ${{ matrix.node-version }} on ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

Gestione secrets e environment variables

GitHub Actions distingue tra Secrets (valori sensibili, sempre mascherati nei log) e Variables (configurazione non sensibile, visibile nei log). Organizzazione consigliata:

Secrets (Settings → Secrets → Actions): ANTHROPIC_API_KEY, VERCEL_TOKEN, DATABASE_URL, STRIPE_SECRET_KEY, SLACK_WEBHOOK. Variables (Settings → Variables → Actions): NEXT_PUBLIC_API_URL, VERCEL_ORG_ID, VERCEL_PROJECT_ID, NODE_ENV. Per ambienti diversi (staging vs production), usa GitHub Environments — permette di avere secrets diversi per branch diversi e richiede approvazione manuale per i deploy di produzione.

Risorse correlate

Approfondisci sul blog

Documentazione e strumenti

FAQ

Quanti minuti GitHub Actions inclusi nel piano gratuito?

Repository pubblici: minuti illimitati gratuiti. Repository privati: 2.000 minuti/mese su runner Linux (ubuntu-latest), 500 minuti equivalenti su Windows, 50 su macOS. Per progetti small team, 2.000 minuti sono spesso sufficienti. Se li superi, il costo è $0,008/minuto su Linux.

Posso usare GitHub Actions con altri hosting oltre a Vercel?

Sì. Esistono action per AWS (aws-actions/amazon-ecr-login, aws-actions/amazon-ecs-deploy), Netlify, Railway, Fly.io, Cloudflare Pages e praticamente qualsiasi piattaforma di hosting. Il pattern è sempre lo stesso: build nel workflow, poi deploy con l’action specifica della piattaforma.

Come velocizzare una pipeline CI lenta?

In ordine di impatto: (1) cache npm/yarn/pnpm correttamente configurata, (2) parallelizza i job invece di eseguirli in sequenza, (3) usa path filters per non triggerare CI su modifiche a README o doc, (4) separa il check veloce (lint + type-check, ~30s) dal check lento (test completi, ~2-3min) in due job paralleli, (5) usa self-hosted runners per evitare i tempi di startup del runner GitHub.

Come gestisco le migration del database nel CI/CD?

Aggiungi uno step nel workflow di deploy che esegue le migration prima del deploy dell’applicazione. Con Drizzle: npx drizzle-kit migrate. Con Prisma: npx prisma migrate deploy. Configura un timeout esplicito per prevenire blocchi indefiniti. Mai eseguire migration distruttive (DROP, DELETE) in automatico — aggiungi una richiesta di approvazione manuale con GitHub Environments.

Condividi

Articoli Recenti

Categorie popolari