feat: add agent-based install, update, repair, and maintenance support #218
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- | |
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| merge_group: | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| RUSTFLAGS: -D warnings | |
| CARGO_INCREMENTAL: 0 | |
| CARGO_NET_RETRY: 10 | |
| RUSTUP_MAX_RETRIES: 10 | |
| # Performance improvements | |
| CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse | |
| CARGO_PROFILE_DEV_DEBUG: 0 | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Detect which crates have changed | |
| changed-files: | |
| name: Detect changed crates | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: read | |
| outputs: | |
| crates_changed: ${{ steps.list-changed-crates.outputs.crates_changed }} | |
| any_crate_changed: ${{ steps.list-changed-crates.outputs.any_crate_changed }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Get changed files | |
| id: changed-files | |
| uses: tj-actions/changed-files@v45 | |
| with: | |
| files: | | |
| Cargo.toml | |
| Cargo.lock | |
| crates/** | |
| files_ignore: | | |
| **/*.md | |
| **/*.txt | |
| **/benches/** | |
| **/examples/** | |
| - name: List changed crates | |
| id: list-changed-crates | |
| env: | |
| ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} | |
| run: | | |
| echo "Changed files: $ALL_CHANGED_FILES" | |
| # If no files changed, we still need to run tests (e.g., scheduled runs) | |
| if [ -z "$ALL_CHANGED_FILES" ]; then | |
| echo "No files changed, will test all crates" | |
| echo "any_crate_changed=true" >> "$GITHUB_OUTPUT" | |
| echo "crates_changed=" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # Check if root Cargo.toml or Cargo.lock changed (affects all crates) | |
| if echo "$ALL_CHANGED_FILES" | grep -E "^Cargo\.(toml|lock)$"; then | |
| echo "Root Cargo files changed, will test all crates" | |
| echo "any_crate_changed=true" >> "$GITHUB_OUTPUT" | |
| echo "crates_changed=" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # Check individual crate changes | |
| crates_changed="" | |
| for crate_dir in crates/*/; do | |
| crate=$(basename "$crate_dir") | |
| if echo "$ALL_CHANGED_FILES" | grep -E "crates/$crate/"; then | |
| crates_changed="$crates_changed $crate" | |
| fi | |
| done | |
| # Remove leading space and output | |
| crates_changed=$(echo "$crates_changed" | xargs) | |
| if [ -n "$crates_changed" ]; then | |
| echo "Crates changed: $crates_changed" | |
| echo "any_crate_changed=true" >> "$GITHUB_OUTPUT" | |
| echo "crates_changed=$crates_changed" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "No crate changes detected" | |
| echo "any_crate_changed=false" >> "$GITHUB_OUTPUT" | |
| echo "crates_changed=" >> "$GITHUB_OUTPUT" | |
| fi | |
| # Quick checks that should fail fast | |
| quick-checks: | |
| name: Quick Checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain with formatting and linting components | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: 1.92.0 | |
| components: rustfmt, clippy | |
| - name: Install protoc | |
| uses: arduino/setup-protoc@v3 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "quick-checks-${{ hashFiles('**/Cargo.lock') }}" | |
| cache-on-failure: true | |
| cache-all-crates: true | |
| # Format check (fastest) | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| # Check compilation | |
| - name: Check compilation | |
| run: cargo check --workspace --all-targets | |
| # Clippy lints | |
| - name: Clippy | |
| run: cargo clippy --workspace --all-targets | |
| # Dependency security and license checks | |
| deny: | |
| name: Cargo Deny | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Check dependencies | |
| uses: EmbarkStudios/cargo-deny-action@v2 | |
| with: | |
| command: check | |
| arguments: --all-features | |
| rust-version: "1.92.0" | |
| # Main test suite with optimized matrix | |
| test: | |
| name: Test (${{ matrix.rust }} on ${{ matrix.os }}) | |
| needs: [quick-checks, changed-files] | |
| if: needs.changed-files.outputs.any_crate_changed == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| rust: 1.92.0 | |
| - os: ubuntu-latest | |
| rust: stable | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain (${{ matrix.rust }}) | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: ${{ matrix.rust }} | |
| - name: Install cargo-nextest | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-nextest | |
| - name: Install protoc | |
| uses: arduino/setup-protoc@v3 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Cache Rust dependencies for ${{ matrix.os }} | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "tests-${{ matrix.os }}-${{ matrix.rust }}-${{ hashFiles('**/Cargo.lock') }}" | |
| cache-on-failure: true | |
| cache-all-crates: true | |
| save-if: ${{ github.ref == 'refs/heads/main' }} | |
| # Determine test scope based on changed crates | |
| - name: Determine test scope | |
| id: test-scope | |
| env: | |
| CRATES_CHANGED: ${{ needs.changed-files.outputs.crates_changed }} | |
| run: | | |
| if [ -z "$CRATES_CHANGED" ]; then | |
| echo "Testing all crates (full workspace test)" | |
| echo "test_args=--workspace" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "Testing only changed crates: $CRATES_CHANGED" | |
| args="" | |
| for crate in $CRATES_CHANGED; do | |
| args="$args -p $crate" | |
| done | |
| echo "test_args=$args" >> "$GITHUB_OUTPUT" | |
| fi | |
| # Test with default features | |
| - name: Test default features (changed crates) | |
| run: cargo nextest run --profile ci ${{ steps.test-scope.outputs.test_args }} | |
| # Test with no default features | |
| - name: Test no default features (changed crates) | |
| run: cargo nextest run --profile ci --no-default-features ${{ steps.test-scope.outputs.test_args }} | |
| # Test each changed crate individually (only on stable Linux) | |
| - name: Test individual changed crates | |
| if: matrix.os == 'ubuntu-latest' && matrix.rust == 'stable' && needs.changed-files.outputs.crates_changed != '' | |
| env: | |
| CRATES_CHANGED: ${{ needs.changed-files.outputs.crates_changed }} | |
| run: | | |
| for crate in $CRATES_CHANGED; do | |
| echo "Testing $crate individually..." | |
| cargo nextest run --profile ci -p "$crate" | |
| done | |
| # WASM compilation check | |
| wasm: | |
| name: WASM Compilation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain with WASM target | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: 1.92.0 | |
| targets: wasm32-unknown-unknown | |
| - name: Verify WASM target installation | |
| run: | | |
| rustup target list --installed | grep wasm32-unknown-unknown || echo "WASM target not found" | |
| rustup target add wasm32-unknown-unknown | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "wasm-${{ hashFiles('**/Cargo.lock') }}" | |
| cache-on-failure: true | |
| cache-all-crates: true | |
| - name: Check WASM compilation | |
| run: | | |
| cargo check --target wasm32-unknown-unknown -p cascette-crypto | |
| cargo check --target wasm32-unknown-unknown -p cascette-formats | |
| # Documentation build - runs in parallel | |
| docs: | |
| name: Documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain for documentation | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: 1.92.0 | |
| - name: Install protoc | |
| uses: arduino/setup-protoc@v3 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Cache documentation dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "docs-${{ hashFiles('**/Cargo.lock') }}" | |
| cache-on-failure: true | |
| cache-all-crates: true | |
| - name: Build documentation | |
| run: cargo doc --workspace --no-deps | |
| env: | |
| RUSTDOCFLAGS: -D warnings | |
| - name: Check for broken links | |
| run: cargo doc --workspace --no-deps --document-private-items | |
| # Coverage collection - runs in parallel | |
| coverage: | |
| name: Code Coverage | |
| runs-on: ubuntu-latest | |
| continue-on-error: true | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust stable toolchain with LLVM tools | |
| uses: dtolnay/rust-toolchain@v1 | |
| with: | |
| toolchain: stable | |
| components: llvm-tools | |
| - name: Install protoc | |
| uses: arduino/setup-protoc@v3 | |
| with: | |
| repo-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Cache coverage dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| shared-key: "coverage-${{ hashFiles('**/Cargo.lock') }}" | |
| cache-on-failure: true | |
| cache-all-crates: true | |
| - name: Install cargo-llvm-cov for coverage collection | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-llvm-cov | |
| - name: Install cargo-nextest for faster coverage collection | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: cargo-nextest | |
| - name: Collect coverage | |
| run: cargo llvm-cov nextest --workspace --lcov --output-path lcov.info | |
| - name: Upload coverage reports to Codecov | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| files: lcov.info | |
| fail_ci_if_error: false | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # Success marker for branch protection | |
| ci-success: | |
| name: CI Success | |
| if: always() | |
| needs: [quick-checks, deny, test, docs, wasm, changed-files] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check all jobs | |
| run: | | |
| # Skip test job check if no crates changed | |
| if [[ "${{ needs.changed-files.outputs.any_crate_changed }}" == "false" ]]; then | |
| echo "No crate changes detected, skipping test job check" | |
| if [[ "${{ needs.quick-checks.result }}" == "failure" || "${{ needs.deny.result }}" == "failure" || "${{ needs.docs.result }}" == "failure" || "${{ needs.wasm.result }}" == "failure" ]]; then | |
| echo "Quick checks, deny, docs, or WASM check failed" | |
| exit 1 | |
| fi | |
| else | |
| if [[ "${{ contains(needs.*.result, 'failure') }}" == "true" ]]; then | |
| echo "One or more jobs failed" | |
| exit 1 | |
| fi | |
| fi | |
| echo "All required jobs succeeded" |