Einleitung: Warum fortgeschrittenes CI/CD für Rust-Projekte wichtig ist
Ein einfacher CI/CD-Pipeline für Rust ist gut, aber in realen Projekten, insbesondere mit mehreren Plattformen, Abhängigkeiten und der Notwendigkeit schnellen Feedbacks, reicht ein einfaches cargo test nicht aus. Eine fortgeschrittene Einrichtung von GitHub Actions ermöglicht es, die Build-Zeit um das 2- bis 3-fache zu reduzieren, Code automatisch auf verschiedenen Architekturen zu prüfen, Crates zu veröffentlichen und Linting durchzuführen.
In diesem Artikel behandeln wir fortgeschrittene Techniken: Caching von Abhängigkeiten, Build-Matrix für Windows/macOS/Linux, paralleles Ausführen von Tests, Veröffentlichung auf crates.io und Integration mit Clippy.
1. Optimierung der Build-Zeit: Caching und inkrementelle Kompilierung
Der aufwändigste Vorgang in CI für Rust ist die Kompilierung von Abhängigkeiten. Ohne Caching wird jeder Durchlauf alle Crates erneut herunterladen und kompilieren. Die Lösung ist die Verwendung des integrierten Caches von GitHub Actions.
Basis-Caching des target-Verzeichnisses
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Cache Rust dependencies uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - run: cargo build --releaseWichtiger Punkt: Der Cache-Schlüssel enthält den Hash von Cargo.lock. Wenn sich die Abhängigkeiten nicht geändert haben, wird der Cache sofort wiederhergestellt.
Fortgeschrittene Aufteilung des Caches für Tests und Builds
Für große Projekte ist es sinnvoll, den Cache für cargo build und cargo test zu trennen, um Test-Binaries beim Release-Build nicht neu zu kompilieren:
- name: Cache cargo build uses: actions/cache@v3 with: path: | ~/.cargo/registry ~/.cargo/git target/debug/.fingerprint target/debug/build key: ${{ runner.os }}-build-${{ hashFiles('**/Cargo.lock') }}2. Build-Matrix: Testen auf allen Plattformen
Rust wird für viele Plattformen kompiliert. Um die korrekte Funktion unter Windows, macOS und Linux zu gewährleisten, verwenden wir eine Matrix-Strategie.
Beispiel einer Matrix für drei Betriebssysteme
jobs: test: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] toolchain: [stable, beta] features: - default - all runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: ${{ matrix.toolchain }} - name: Run tests run: cargo test --features ${{ matrix.features }}Dieser Ansatz erstellt automatisch 6 parallele Jobs (3 Betriebssysteme × 2 Toolchains). Sie können Prüfungen für nightly, arm64-Architekturen oder Cross-Kompilierung für WASM hinzufügen.
Ausschluss unnötiger Kombinationen
strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] toolchain: [stable, nightly] exclude: - os: macos-latest toolchain: nightly # Nightly auf macOS nicht testen3. Linting, Formatierung und Sicherheit
Neben Tests umfasst fortgeschrittenes CI auch statische Analyse. Fügen wir Prüfungen mit clippy, rustfmt und cargo-audit für Schwachstellen hinzu.
Separater Job für Linting
lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: components: clippy, rustfmt - name: Check formatting run: cargo fmt --check - name: Clippy with warnings as errors run: cargo clippy -- -D warnings