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@v4Azione 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, phpstanMemorizzare 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-progressContainer 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=10Eseguire 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-progressBuild 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=maxSegreti 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-1Passaggio 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=120sControllo 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
- Containerizzare un'applicazione PHP
- Build multi-stage e ottimizzazione
- Docker Compose per gli stack locali
- CI/CD con GitHub Actions