Einleitung: Warum reicht ein einfaches CI/CD nicht aus?
Das grundlegende CI/CD-Niveau für C#-Projekte beschränkt sich normalerweise auf das einfache Ausführen von dotnet build und dotnet test. Wenn das Projekt jedoch auf eine Microservice-Architektur, ein Monorepo anwächst oder die Unterstützung mehrerer .NET-Versionen erfordert, reicht der Standardansatz nicht mehr aus. Die Build-Zeit steigt, Tests werden dupliziert und der Deployment-Prozess von NuGet-Paketen wird zur Routine.
In diesem Artikel behandeln wir fortgeschrittene Techniken zur Konfiguration von GitHub Actions für C# (.NET)-Projekte. Sie erfahren, wie Sie Pipelines mit Caching beschleunigen, parallele Tests organisieren, Matrix-Builds implementieren und die automatische Veröffentlichung auf NuGet einrichten. Alle Codebeispiele sind bereit für den Einsatz in Ihren Projekten.
1. Matrix-Build und Testen mehrerer .NET-Versionen
Die Matrix ist ein leistungsstarkes Werkzeug von GitHub Actions, mit dem Sie denselben Workflow mit verschiedenen Parametern ausführen können. Für C# ist dies unverzichtbar, wenn die Kompatibilität des Codes mit .NET 6, .NET 8 und .NET 9 überprüft werden muss.
Beispiel einer Matrix-Konfiguration
Erstellen Sie die Datei .github/workflows/ci-matrix.yml:
name: Matrix Build and Test
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: build: runs-on: ubuntu-latest strategy: matrix: dotnet-version: ['6.0.x', '8.0.x', '9.0.x'] configuration: ['Release', 'Debug'] fail-fast: false # Build fortsetzen, auch wenn eine Version fehlschlägt
steps: - uses: actions/checkout@v4 - name: Setup .NET ${{ matrix.dotnet-version }} uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ matrix.dotnet-version }} - name: Restore dependencies run: dotnet restore - name: Build run: dotnet build --configuration ${{ matrix.configuration }} --no-restore - name: Run tests run: dotnet test --configuration ${{ matrix.configuration }} --no-build --verbosity normalWichtige Punkte:
fail-fast: false— ermöglicht es, die Ergebnisse für alle Versionen zu sehen, auch wenn eine davon fehlschlägt.- Die Matrix kann nicht nur .NET-Versionen, sondern auch Betriebssysteme umfassen (z.B.
os: [ubuntu-latest, windows-latest]). - Für ein Monorepo kann ein Parameter
project-pathhinzugefügt werden, um verschiedene Module zu testen.
2. Abhängigkeits-Caching: Builds 3x schneller machen
Jeder GitHub Actions-Start beginnt mit einer sauberen Umgebung. Ohne Caching wird dotnet restore jedes Mal alle NuGet-Pakete erneut herunterladen. Bei großen Projekten kann dies 2-5 Minuten dauern. Die Lösung ist das Caching des Ordners ~/.nuget/packages.
Fortgeschrittene Cache-Konfiguration
Verwenden Sie die Aktion actions/cache mit einem korrekten Schlüssel, der die Sperrdatei berücksichtigt:
steps: - uses: actions/checkout@v4
- name: Cache NuGet packages uses: actions/cache@v4 with: path: ~/.nuget/packages # Schlüssel: Hash der Sperrdatei + OS-Name key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} # Fallback auf vorherigen Schlüssel, wenn sich die Sperrdatei nicht geändert hat restore-keys: | ${{ runner.os }}-nuget-
- name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: '8.0.x'
- name: Restore dependencies run: dotnet restoreTipp: Wenn das Projekt mehrere .csproj-Dateien enthält, verwenden Sie hashFiles('**/*.csproj', '**/packages.lock.json') für einen genaueren Hash.
3. Parallele Testausführung und Berichterstellung
Wenn ein Projekt Hunderte von Tests hat, kann die sequentielle Ausführung Dutzende von Minuten dauern. GitHub Actions unterstützt die Parallelisierung auf Job-Ebene. Aber für