DevOps & Cloud

CI/CD Pipeline: Automatisierte Tests & Deployment mit GitHub Actions

10 Min. Lesezeit17. März 2026
CI/CD pipelineGitHub ActionsCI/CD rehberiOtomatik deploymentGitHub Actions tutorialDevOpsContinuous integrationContinuous deploymentGitHub Actions DockerCI/CD .NET

CI/CD (Continuous Integration / Continuous Deployment) ist eine der kritischsten Komponenten des Softwareentwicklungsprozesses. GitHub Actions ist eine leistungsstarke CI/CD-Plattform, die Codeaenderungen automatisch testet, baut und deployt. In diesem Artikel zeige ich, wie man umfassende CI/CD-Pipelines fuer .NET- und Flutter-Projekte mit GitHub Actions erstellt.

GitHub Actions Grundlagen

GitHub Actions Workflows werden als YAML-Dateien im .github/workflows/-Verzeichnis definiert. Jeder Workflow enthaelt einen oder mehrere Jobs, und jeder Job besteht aus einer Reihe von Steps.

  • Workflow: Automatisierte Prozessdefinition (YAML-Datei)
  • Event: Das Ereignis, das den Workflow ausloest (push, pull_request, schedule)
  • Job: Arbeitseinheiten, die parallel oder sequenziell ausgefuehrt werden
  • Step: Ein einzelner Operationsschritt innerhalb eines Jobs

.NET CI/CD Pipeline

yaml
# .github/workflows/dotnet-ci-cd.yml
name: .NET CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  DOTNET_VERSION: '8.0.x'
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:16-alpine
        env:
          POSTGRES_DB: testdb
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v4

      - name: .NET SDK einrichten
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ${{ env.DOTNET_VERSION }}

      - name: NuGet-Pakete cachen
        uses: actions/cache@v4
        with:
          path: ~/.nuget/packages
          key: nuget-${{ hashFiles('**/*.csproj') }}

      - name: Restore und Build
        run: |
          dotnet restore
          dotnet build --no-restore -c Release

      - name: Tests ausfuehren
        run: dotnet test --no-build -c Release --collect:"XPlat Code Coverage"

  docker-build:
    needs: build-and-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
      - uses: actions/checkout@v4

      - name: Docker-Image bauen und pushen
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

Flutter CI/CD Pipeline

yaml
# .github/workflows/flutter-ci-cd.yml
name: Flutter CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  analyze-and-test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Flutter SDK einrichten
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.24.0'
          channel: stable
          cache: true

      - name: Abhaengigkeiten installieren
        run: flutter pub get

      - name: Codeanalyse
        run: flutter analyze --fatal-infos

      - name: Tests ausfuehren
        run: flutter test --coverage

  build-android:
    needs: analyze-and-test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'

    steps:
      - uses: actions/checkout@v4

      - name: Flutter SDK einrichten
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.24.0'
          cache: true

      - name: Android APK bauen
        run: flutter build apk --release

Fortgeschrittene Techniken

Secrets-Verwaltung und Sicherheit

Ein mehrschichtiger Ansatz fuer die sichere Verwaltung sensibler Daten:

  • Repository Secrets: Allgemeine Secrets fuer alle Workflows
  • Environment Secrets: Umgebungsspezifische Geheimnisverwaltung mit optionaler Genehmigungspflicht
  • OIDC: OpenID Connect fuer secretlose Verbindung zu Cloud-Anbietern
yaml
# OIDC-Beispiel fuer secretlosen AWS-Zugriff
permissions:
  id-token: write
  contents: read

steps:
  - name: AWS-Anmeldeinformationen (OIDC)
    uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789:role/github-actions-role
      aws-region: eu-central-1

Umgebungsspezifische Deployments

Unterschiedliche Konfigurationen fuer verschiedene Umgebungen erhoehen die Deployment-Sicherheit:

yaml
  deploy-staging:
    needs: docker-build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    environment: staging
    steps:
      - name: Deploy nach Staging
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.STAGING_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/myapp-staging
            docker compose pull
            docker compose up -d --remove-orphans

  deploy-production:
    needs: docker-build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: production  # Erfordert manuelle Genehmigung
    steps:
      - name: Deploy nach Production
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.PRODUCTION_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /opt/myapp
            docker compose pull
            docker compose up -d --remove-orphans

Wiederverwendbare Workflows und Matrix-Strategie

  • Reusable Workflows: Wiederverwendbare Workflow-Teile fuer organisationsweite Standards
  • Matrix Strategy: Parallele Tests ueber mehrere Versionen oder Plattformen
yaml
# Matrix-Strategie fuer Multi-Plattform-Tests
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        dotnet-version: ['8.0.x', '9.0.x']
      fail-fast: false
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: ${{ matrix.dotnet-version }}
      - run: dotnet test -c Release

Caching-Strategien

Effektive Cache-Strategien koennen Build-Zeiten um bis zu 50% reduzieren:

yaml
# NuGet-Paket-Cache
- uses: actions/cache@v4
  with:
    path: ~/.nuget/packages
    key: nuget-${{ runner.os }}-${{ hashFiles('**/*.csproj') }}
    restore-keys: |
      nuget-${{ runner.os }}-

# Flutter-Pub-Cache
- uses: actions/cache@v4
  with:
    path: |
      ~/.pub-cache
      .dart_tool
    key: flutter-${{ hashFiles('**/pubspec.lock') }}

Praktische Tipps

  1. Caching nutzen: NuGet- und Flutter-Pakete cachen fuer schnellere Builds
  2. Parallele Jobs: Unabhaengige Operationen parallel ausfuehren
  3. Environment-Schutz: Manuelle Genehmigung fuer Produktions-Deployments
  4. Artefakt-Verwaltung: Build-Ausgaben als Artefakte fuer Rollbacks speichern
  5. Benachrichtigungen: Pipeline-Status mit Slack oder Teams verfolgen

Eine gut konfigurierte CI/CD-Pipeline ist das Rueckgrat des Softwareentwicklungsprozesses. Automatisches Testen und Deployment reduzieren sowohl die Fehlerquote als auch erhoehen die Liefergeschwindigkeit.

Verwandte Artikel

Haben Sie ein Flutter-Projekt?

Ich entwickle hochleistungsfähige Flutter-Anwendungen für iOS, Android und Web.

Kontakt aufnehmen