aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Tools & DevOps

CI/CD-Pipeline mit GitHub Actions aufbauen

GitHub Actions ist ein Automatisierungstool, das deine Tests bei jedem Code-Push ausführt und dein Projekt automatisch auf den Server deployt, sobald alles grün ist. Es lebt direkt in deinem Repository, du musst dich also bei keinem separaten Dienst anmelden, und es kommt mit einem großzügigen Gratiskontingent für Open-Source-Projekte. In dieser Anleitung bauen wir eine CI/CD-Pipeline von Grund auf: zuerst klären wir die Begriffe, dann schreiben wir einen echten Test- und Deploy-Workflow.

Warum CI/CD und GitHub Actions helfen

CI (Continuous Integration) bedeutet, jede Codeänderung automatisch zu bauen und zu testen, sodass du einen kaputten Commit abfängst, bevor er überhaupt gemergt wird. CD (Continuous Delivery/Deployment) bedeutet, Code, der die Tests besteht, automatisch in eine Staging- oder Produktionsumgebung auszuliefern. Der kombinierte Ablauf heißt CI/CD-Pipeline.

Die manuelle Schleife "Tests lokal ausführen, Dateien per FTP hochladen, Daumen drücken" ist langsam und fehleranfällig. GitHub Actions macht diese Schleife wiederholbar:

  • Konsistenz: Die Pipeline läuft auf einer sauberen virtuellen Maschine, was das Problem "bei mir lief es doch" weitgehend beseitigt.
  • Geschwindigkeit: Jobs können parallel laufen, sodass Lint, Test und Build gleichzeitig voranschreiten.
  • Sicherheit: SSH-Schlüssel und Tokens werden verschlüsselt in den Repository-Secrets gespeichert, statt hart im Code zu stehen.

Kernbegriffe: Workflow, Job, Step, Action

Das Vokabular von GitHub Actions ist klein, aber wichtig:

  • Workflow: eine YAML-Datei im Ordner .github/workflows/. Sie legt fest, wann und was ausgeführt wird.
  • Event (Trigger): das Ereignis, das den Workflow startet — push, pull_request, ein geplanter schedule oder ein manueller workflow_dispatch.
  • Job: eine Gruppe von Schritten, die auf demselben Runner läuft. Jobs laufen standardmäßig parallel und mit needs sequenziell.
  • Step: ein einzelner Befehl (run) innerhalb eines Jobs oder eine fertige uses-Action.
  • Runner: die virtuelle Maschine, auf der der Job läuft, zum Beispiel ubuntu-latest.

Dein erster Workflow: Tests ausführen

Nehmen wir ein Node.js-Projekt. Erstelle .github/workflows/ci.yml im Wurzelverzeichnis des Repositorys:

name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm test

actions/checkout@v4 klont dein Repo auf den Runner, setup-node installiert die richtige Node-Version und cache: npm cacht deine Abhängigkeiten. npm ci führt eine saubere Installation durch, die sich strikt an package-lock.json hält — zuverlässiger als npm install in der CI. Sobald du diese Datei pushst, laufen die Tests automatisch bei jedem Commit und Pull Request.

Mehrere Versionen mit einer Matrix testen

Willst du eine Bibliothek gegen mehrere Sprachversionen testen, vervielfacht strategy.matrix einen einzelnen Job:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

Dieser Workflow führt dieselben Tests parallel auf Node 18, 20 und 22 aus. Auf der PHP/Laravel-Seite wendest du dieselbe Idee mit der Action shivammathur/setup-php an, um mehrere PHP-Versionen zu probieren, und führst danach php artisan test aus.

Secrets und der Deploy-Job

Der Deploy-Schritt benötigt Zugriff auf deinen Server, also Secrets. Schreibe niemals einen privaten SSH-Schlüssel oder ein API-Token ins YAML. Erstelle stattdessen auf GitHub unter Settings → Secrets and variables → Actions ein Secret (zum Beispiel SSH_PRIVATE_KEY, SSH_HOST) und referenziere es im Workflow als ${{ secrets.SSH_HOST }}.

Das folgende Beispiel fügt einen zweiten Job hinzu, der deployt, nachdem die Tests bestanden sind. Dank needs: test läuft der Deploy nur, wenn der Test-Job erfolgreich war, und die if-Bedingung beschränkt ihn auf Pushes auf main:

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Auf dem Server via SSH deployen
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SSH_PORT }}
          script: |
            cd ~/app
            git pull origin main
            composer install --no-dev -o
            php artisan migrate --force
            php artisan optimize

Hier ist die Deploy-Strategie ein einfacher "mit dem Server verbinden, pullen, aktualisieren"-Ablauf. Mit Docker würdest du stattdessen das Image bauen und in eine Registry pushen (docker/build-push-action) und danach das neue Image auf dem Server pullen. Das Prinzip bleibt gleich: Konfiguration im Code, Secrets in den Secrets.

Tipps, um die Pipeline zu härten

  • Schnell scheitern: Mach Lint und Test zu eigenen Jobs vor dem Deploy, damit ein roter Test den Deploy vollständig blockiert.
  • Caching nutzen: Abhängigkeits- und Build-Caches senken die Pipelinezeit von Minuten auf Sekunden.
  • Action-Versionen pinnen: Binde dich an eine feste Major-Version wie @v4; bei besonders sensiblen Projekten pinne auf einen Commit-SHA.
  • Concurrency: Verwende einen concurrency-Block, um ältere Läufe desselben Branches abzubrechen und überflüssige Deploys zu verhindern.
  • Sichtbarkeit: Füge deinem README ein Status-Badge hinzu, damit du auf einen Blick siehst, ob die Pipeline grün oder rot ist.

Häufige Fragen

Ist GitHub Actions kostenlos?

Standard-Runner sind für öffentliche Repositories kostenlos. Private Repositories erhalten ein kostenloses monatliches Minutenkontingent; wird es überschritten, wird pro Minute abgerechnet. Die meisten kleinen und mittleren Projekte bleiben bequem innerhalb des Gratiskontingents.

Warum GitHub Actions statt Jenkins oder GitLab CI?

Liegt dein Code bereits auf GitHub, lebt Actions am selben Ort wie dein Repo, du startest also ohne jegliche Infrastruktur. Jenkins bietet mehr Kontrolle und Plugins, erfordert aber, dass du einen Server betreibst. Die Entscheidung hängt davon ab, wo dein Team arbeitet und wie viel Anpassung du brauchst.

Was passiert, wenn ein Deploy fehlschlägt?

Der Job wird rot, spätere Schritte laufen nicht und GitHub benachrichtigt dich. Die Logs zeigen den genauen Befehl und die Fehlerausgabe. Für sichere Deploys gestalte deine Migrationen umkehrbar und nutze, wo möglich, eine Blue-Green- oder Rolling-Deploy-Strategie.

Möchtest du deine Pipeline einrichten oder einen bestehenden Deploy-Ablauf automatisieren? Ich helfe dir, dein Projekt auf eine schnelle, sichere und wiederholbare CI/CD-Pipeline zu bringen — nimm Kontakt auf.

Bu kategorideki tüm yazılar →

Devamı için