CI/CD mit GitHub Actions
PHP bei jedem Push automatisch testen und bereitstellen
CI/CD mit GitHub Actions ist eine kostenlose PHP Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des PHP Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.
CI/CD für PHP
Jeder Push sollte getestet, gelintet und statisch analysiert werden. Wenn der Build auf dem main-Branch erfolgreich ist, sollte außerdem ein Image erstellt und ausgerollt werden. GitHub Actions führt diese Pipeline auf verwalteten Runnern aus, die durch Repository-Ereignisse ausgelöst werden.
Wir erstellen einen Workflow, der PHPUnit mit einem echten MySQL-Service ausführt, Composer cached, PHPStan startet, ein Docker-Image baut und es ausrollt.
Aufbau eines Workflows
Ein Workflow liegt unter .github/workflows/*.yml. Er enthält on:-Trigger, einen oder mehrere jobs:, und jeder Job enthält steps:. Jobs laufen auf isolierten Runnern parallel, sofern sie nicht durch needs: miteinander verknüpft sind.
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4setup-php-Action
shivammathur/setup-php ist die Standardmethode, um auf dem Runner eine bestimmte PHP-Version mit ausgewählten Erweiterungen und Tools wie Composer und PHPStan zu installieren – deutlich schneller, als nur zum Testen ein Image zu bauen.
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: pdo_mysql, intl, redis, zip
coverage: pcov
tools: composer:v2, phpstanComposer cachen
Das erneute Herunterladen der Abhängigkeiten bei jedem Lauf kostet unnötig Zeit. Cachen Sie das Composer-Verzeichnis anhand des composer.lock-Hashes, sodass der Cache nur ungültig wird, wenn sich die Abhängigkeiten ändern.
- 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-progressService-Container
Jobs können Service-Container starten – eine echte MySQL- oder Redis-Instanz, die der Runner unter 127.0.0.1 erreichen kann. Fügen Sie über options einen Healthcheck hinzu, damit die Schritte nicht ausgeführt werden, bevor die Datenbank bereit ist.
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=10Tests und Coverage ausführen
Führen Sie PHPUnit aus, sobald die Abhängigkeiten installiert und MySQL gestartet ist. Richten Sie die Test-DSN auf 127.0.0.1:3306. Erzeugen Sie eine Coverage-Auswertung und lassen Sie den Build optional fehlschlagen, wenn ein Schwellenwert unterschritten wird.
- 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-progressMatrix-Builds
Bibliotheken sollten mit mehreren PHP-Versionen funktionieren. Eine strategy.matrix verteilt den Job auf parallele Läufe, einen pro Kombination, wobei ${{ matrix.php }} in die Schritte interpoliert wird.
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 }}Image-Tag berechnen
Deployments benötigen ein eindeutiges, nachvollziehbares Image-Tag. Der Commit-SHA ist dafür die übliche Wahl. Dieser Ausschnitt zeigt die Logik zur Ableitung des Tags, die Sie im Workflow formulieren würden – eine Ref und einen SHA in ein Registry-Tag umzuwandeln.
<?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;
?>Image bauen und pushen
Bauen Sie auf dem main-Branch das Docker-Image mit docker/build-push-action unter Verwendung von BuildKit und dem GitHub-Actions-Cache. Melden Sie sich vorher mit einem geheimen Token an der Registry an; hinterlegen Sie Zugangsdaten niemals direkt im Code.
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=maxSecrets und OIDC
Speichern Sie Zugangsdaten als Repository- oder Umgebungs-Secrets und referenzieren Sie sie mit ${{ secrets.NAME }} – in den Logs werden sie maskiert. Bevorzugen Sie für Cloud-Deployments OIDC: Der Runner erhält über permissions: id-token: write ein kurzlebiges Token von AWS/GCP, sodass keine langlebigen Schlüssel im Repository liegen.
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-1Deploy-Schritt und Umgebungen
Sichern Sie Produktions-Deployments mit einer GitHub-environment ab, optional mit erforderlichen Genehmigern. Der Deploy-Schritt stößt dann Ihren Rollout an – etwa durch das Aktualisieren eines Kubernetes-Deployments oder ECS-Services oder durch eine SSH-Verbindung zum Abrufen des neuen Images.
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=120sKurzprüfung
Was ist der wichtigste Sicherheitsvorteil von OIDC gegenüber gespeicherten Cloud-Schlüsseln in Actions?
Zusammenfassung
Sie haben eine PHP-CI/CD-Pipeline in GitHub Actions erstellt: Trigger bei Push und Pull Request, setup-php mit Erweiterungen, anhand der Lockdatei gecachtes Composer, ein MySQL-Service-Container mit Healthcheck, PHPUnit und PHPStan, eine Versionsmatrix sowie anschließend ein auf den main-Branch beschränktes Build-and-Push mit GHA-Cache und ein über OIDC authentifiziertes und durch eine Umgebung abgesichertes Deployment.
Grundsätze: anhand von Lockdatei-Hashes cachen, bereite Services mit Healthchecks absichern, Images nach dem SHA taggen und OIDC gegenüber gespeicherten Schlüsseln bevorzugen.
Häufig gestellte Fragen
Ist die Lektion „CI/CD mit GitHub Actions“ kostenlos?
Ja — der vollständige Text von „CI/CD mit GitHub Actions“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des PHP Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der PHP Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „CI/CD mit GitHub Actions“?
PHP bei jedem Push automatisch testen und bereitstellen Du übst PHP Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um PHP Academy zu starten?
Keine Vorkenntnisse erforderlich. PHP Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „CI/CD mit GitHub Actions“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser PHP Academy-Lektion Code schreiben und ausführen?
Ja. Jede PHP Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Eine PHP-Anwendung containerisieren
- Multi-Stage-Builds und Optimierung
- Docker Compose für lokale Stacks
- CI/CD mit GitHub Actions