0Pricing
PHP Academy · Lektion

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@v4

setup-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, phpstan

Composer 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-progress

Service-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=10

Tests 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-progress

Matrix-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=max

Secrets 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-1

Deploy-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=120s

Kurzprü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

  1. Eine PHP-Anwendung containerisieren
  2. Multi-Stage-Builds und Optimierung
  3. Docker Compose für lokale Stacks
  4. CI/CD mit GitHub Actions
← Zurück zu PHP Academy