0Pricing
PHP Academy · Lezione

CI/CD con GitHub Actions

Esegua automaticamente test e distribuzione di PHP a ogni push

CI/CD con GitHub Actions è una lezione PHP Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento PHP Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso PHP Academy include 4 lezioni in totale.

CI/CD per PHP

Ogni push deve essere testato, sottoposto a lint e analisi statica e, quando la build sul branch principale è completata con successo, trasformato in un'immagine e distribuito. GitHub Actions esegue questa pipeline su runner gestiti, attivati dagli eventi del repository.

Costruiremo un workflow che esegue PHPUnit su un servizio MySQL reale, memorizza Composer nella cache, esegue PHPStan, crea un'immagine Docker e la distribuisce.

Anatomia di un workflow

Un workflow risiede in .github/workflows/*.yml. Contiene trigger on:, uno o più job jobs: e ogni job contiene step steps:. I job vengono eseguiti su runner isolati in parallelo, salvo che siano collegati tramite needs:.

name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

Azione setup-php

shivammathur/setup-php è il modo standard per installare sul runner una versione specifica di PHP con estensioni e strumenti scelti (Composer, PHPStan ecc.): è molto più veloce che creare un'immagine solo per eseguire i test.

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          extensions: pdo_mysql, intl, redis, zip
          coverage: pcov
          tools: composer:v2, phpstan

Memorizzare Composer nella cache

Scaricare nuovamente le dipendenze a ogni esecuzione fa perdere minuti. Memorizzi nella cache la directory di Composer usando come chiave l'hash di composer.lock, così la cache viene invalidata solo quando cambiano le dipendenze.

      - name: Get Composer cache dir
        id: composer-cache
        run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT

      - uses: actions/cache@v4
        with:
          path: ${{ steps.composer-cache.outputs.dir }}
          key: composer-${{ hashFiles('**/composer.lock') }}
          restore-keys: composer-

      - run: composer install --prefer-dist --no-progress

Container di servizio

I job possono avviare container di servizio: un MySQL o Redis reale raggiungibile dal runner su 127.0.0.1. Aggiunga un controllo di integrità tramite options, così gli step non vengono eseguiti prima che il database sia pronto.

  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8.4
        env:
          MYSQL_DATABASE: app_test
          MYSQL_ROOT_PASSWORD: root
        ports: ['3306:3306']
        options: >-
          --health-cmd="mysqladmin ping -proot"
          --health-interval=5s --health-retries=10

Eseguire test e coverage

Con le dipendenze installate e MySQL attivo, esegua PHPUnit. Imposti il DSN dei test su 127.0.0.1:3306. Generi la coverage e, facoltativamente, faccia fallire la build se scende al di sotto di una soglia.

      - name: Run PHPUnit
        env:
          DATABASE_URL: "mysql://root:root@127.0.0.1:3306/app_test"
        run: vendor/bin/phpunit --coverage-clover=coverage.xml

      - name: Static analysis
        run: phpstan analyse src --level=8 --no-progress

Build con matrice

Le librerie dovrebbero superare i test su più versioni di PHP. Una strategy.matrix distribuisce il job in esecuzioni parallele, una per combinazione, con ${{ matrix.php }} interpolato negli step.

  test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        php: ['8.2', '8.3', '8.4']
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php }}

Calcolare il tag dell'immagine

Le distribuzioni richiedono un tag univoco e tracciabile. La SHA del commit è la scelta convenzionale. Questo frammento mostra la logica di derivazione del tag che si esprimerebbe nel workflow: trasformare un ref e una SHA in un tag del registry.

<?php
// Mirrors what the workflow computes for the image tag
$ref = 'refs/heads/main';
$sha = '9f41efadc0de1234567890abcdef0000deadbeef';

$branch = str_replace('refs/heads/', '', $ref);
$shortSha = substr($sha, 0, 7);
$tag = sprintf('registry.example.com/app:%s-%s', $branch, $shortSha);

echo $tag . PHP_EOL;          // registry.example.com/app:main-9f41efa
echo 'is_main: ' . ($branch === 'main' ? 'yes' : 'no') . PHP_EOL;
?>

Creare e pubblicare l'immagine

Sul branch principale, crei l'immagine Docker con docker/build-push-action, usando BuildKit e la cache di GitHub Actions. Acceda prima al registry con un token segreto; non codifichi mai le credenziali direttamente nel codice.

  build:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v6
        with:
          push: true
          target: runtime
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Segreti e OIDC

Conservi le credenziali nei segreti del repository o dell'ambiente, referenziati come ${{ secrets.NAME }}: nei log vengono mascherati. Per le distribuzioni cloud, preferisca OIDC: il runner riceve un token a breve durata da AWS/GCP tramite permissions: id-token: write, così nel repository non vengono archiviate chiavi a lunga durata.

  deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write     # enables OIDC
      contents: read
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/deploy
          aws-region: eu-central-1

Passaggio di deploy e ambienti

Protegga le distribuzioni in produzione dietro un environment di GitHub, facoltativamente con revisori obbligatori. Il passaggio di deploy avvia quindi il rollout: aggiorna una distribuzione Kubernetes o un servizio ECS, oppure si connette via SSH per scaricare la nuova immagine.

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: production       # can require manual approval
      url: https://app.example.com
    steps:
      - name: Roll out
        run: |
          kubectl set image deployment/app \
            app=ghcr.io/${{ github.repository }}:${{ github.sha }}
          kubectl rollout status deployment/app --timeout=120s

Controllo rapido

Qual è il principale vantaggio di sicurezza di OIDC rispetto alle chiavi cloud memorizzate in Actions?

Riepilogo

Ha creato una pipeline CI/CD PHP in GitHub Actions: trigger su push/PR, setup-php con estensioni, Composer nella cache con una chiave basata sul lockfile, un container di servizio MySQL con healthcheck, PHPUnit + PHPStan, una matrice di versioni, quindi una build-push solo sul branch principale con cache GHA e un deploy autenticato tramite OIDC e protetto da un environment.

Principi: usare gli hash del lockfile per la cache, regolare i servizi pronti con i controlli di integrità, assegnare tag alle immagini usando la SHA e preferire OIDC alle chiavi memorizzate.

Domande Frequenti

La lezione «CI/CD con GitHub Actions» è gratuita?

Sì — il testo completo di «CI/CD con GitHub Actions» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso PHP Academy, passa a CoddyKit PRO. Il corso PHP Academy include 4 lezioni in totale.

Cosa imparerò in «CI/CD con GitHub Actions»?

Esegua automaticamente test e distribuzione di PHP a ogni push Eserciti PHP Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare PHP Academy?

Non è richiesta alcuna esperienza precedente. PHP Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «CI/CD con GitHub Actions»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione PHP Academy?

Sì. Ogni lezione PHP Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Containerizzare un'applicazione PHP
  2. Build multi-stage e ottimizzazione
  3. Docker Compose per gli stack locali
  4. CI/CD con GitHub Actions
← Torna a PHP Academy