feat(providers): display synthetic provider on provider screens (ASY-β¦ #2301
Workflow file for this run
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: Backend CI | |
| on: | |
| push: | |
| branches: [ "main", "debug/*", "feature/*", "claude/*" ] | |
| paths: | |
| - 'src/**' | |
| - 'tests/**' | |
| - 'benches/**' | |
| - 'migrations/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'scripts/**' | |
| - '.github/workflows/ci.yml' | |
| pull_request: | |
| branches: [ main ] | |
| paths: | |
| - 'src/**' | |
| - 'tests/**' | |
| - 'benches/**' | |
| - 'migrations/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - 'scripts/**' | |
| - '.github/workflows/ci.yml' | |
| schedule: | |
| # Weekly release binary validation (Sundays at 2 AM UTC) | |
| - cron: '0 2 * * 0' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| # Security: Explicit permissions following principle of least privilege | |
| permissions: | |
| contents: read | |
| actions: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # Clippy linting with zero tolerance (includes cognitive complexity) | |
| clippy: | |
| name: Clippy Linting | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Free Disk Space (Ubuntu) | |
| uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: false | |
| android: true | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| docker-images: true | |
| swap-storage: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@1.92.0 | |
| with: | |
| components: rustfmt, clippy | |
| - name: Cache Rust dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-clippy-1.92.0-v2-${{ hashFiles('**/Cargo.lock', 'migrations/**') }} | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| - name: Lint with Clippy (Zero Tolerance + Cognitive Complexity) | |
| run: cargo clippy --all-targets --all-features -- -D warnings | |
| backend-tests: | |
| name: Backend Tests (SQLite) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Free Disk Space (Ubuntu) | |
| uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: false | |
| android: true | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| docker-images: false # Keep Docker for potential future use | |
| swap-storage: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@1.92.0 | |
| - name: Cache Rust dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-1.92.0-v2-${{ hashFiles('**/Cargo.lock', 'migrations/**') }} | |
| - name: Install cargo-deny | |
| uses: taiki-e/install-action@cargo-deny | |
| - name: Security Audit (via deny.toml) | |
| run: cargo deny check | |
| continue-on-error: true | |
| - name: Install ripgrep (for architectural validation) | |
| run: sudo apt-get update && sudo apt-get install -y ripgrep | |
| - name: Architectural Validation (Custom Patterns) | |
| run: ./scripts/architectural-validation.sh | |
| - name: Secret Pattern Validation | |
| run: ./scripts/validate-no-secrets.sh | |
| - name: Validate no ignored doctests | |
| run: | | |
| echo "π Checking for ignored doctests..." | |
| DOCTEST_OUTPUT=$(cargo test --doc 2>&1 || true) | |
| IGNORED_COUNT=$(echo "$DOCTEST_OUTPUT" | grep -E "test result:.*ignored" | grep -oE "[0-9]+ ignored" | grep -oE "[0-9]+" | head -1 || echo "0") | |
| if [ "${IGNORED_COUNT:-0}" -gt 0 ]; then | |
| echo "β ERROR: Found $IGNORED_COUNT ignored doctests!" | |
| echo "Doctests marked with 'ignore' are not compiled or tested." | |
| echo "Use 'no_run' if code should compile but not execute," | |
| echo "or 'text' for documentation-only examples." | |
| echo "" | |
| echo "To find ignored doctests, run: cargo test --doc 2>&1 | grep -i ignore" | |
| exit 1 | |
| fi | |
| echo "β No ignored doctests found" | |
| env: | |
| DATABASE_URL: "sqlite::memory:" | |
| PIERRE_MASTER_ENCRYPTION_KEY: "rEFe91l6lqLahoyl9OSzum9dKa40VvV5RYj8bHGNTeo=" | |
| STRAVA_CLIENT_ID: "test_client_id_ci" | |
| STRAVA_CLIENT_SECRET: "test_client_secret_ci" | |
| STRAVA_REDIRECT_URI: "http://localhost:8080/auth/strava/callback" | |
| - name: Setup Node.js (for SDK E2E tests runtime) | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Setup Bun (for SDK build) | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Build MCP SDK (required for E2E tests) | |
| working-directory: sdk | |
| run: | | |
| bun install --frozen-lockfile | |
| bun run build | |
| - name: Run all backend tests (SQLite) | |
| # Tests marked with #[serial] (concurrent/stress tests) run in isolation | |
| # Using --test-threads=4 for parallelism - see issue #36 for serial_test approach | |
| # Coverage is generated by dedicated coverage.yml workflow | |
| run: cargo test -- --test-threads=4 | |
| env: | |
| DATABASE_URL: "sqlite::memory:" | |
| ENCRYPTION_KEY: "rEFe91l6lqLahoyl9OSzum9dKa40VvV5RYj8bHGNTeo=" | |
| PIERRE_MASTER_ENCRYPTION_KEY: "rEFe91l6lqLahoyl9OSzum9dKa40VvV5RYj8bHGNTeo=" | |
| PIERRE_RSA_KEY_SIZE: "2048" | |
| STRAVA_CLIENT_ID: "test_client_id_ci" | |
| STRAVA_CLIENT_SECRET: "test_client_secret_ci" | |
| STRAVA_REDIRECT_URI: "http://localhost:8080/auth/strava/callback" | |
| USDA_API_KEY: ${{ secrets.USDA_API_KEY }} | |
| postgres-tests: | |
| name: Database Tests (PostgreSQL) | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: pierre | |
| POSTGRES_PASSWORD: ci_test_password | |
| POSTGRES_DB: pierre_mcp_server | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Free Disk Space (Ubuntu) | |
| uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: false | |
| android: true | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| docker-images: false # Keep Docker - PostgreSQL runs as container | |
| swap-storage: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@1.92.0 | |
| - name: Cache Rust dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-postgres-1.92.0-v2-${{ hashFiles('**/Cargo.lock', 'migrations/**') }} | |
| - name: Wait for PostgreSQL | |
| run: | | |
| echo "π Waiting for PostgreSQL to be ready..." | |
| timeout 60 bash -c 'until pg_isready -h localhost -p 5432 -U pierre; do sleep 2; done' | |
| echo "β PostgreSQL is ready!" | |
| - name: Verify PostgreSQL connection | |
| run: | | |
| echo "π§ Testing PostgreSQL connection..." | |
| PGPASSWORD=ci_test_password psql -h localhost -U pierre -d pierre_mcp_server -c "SELECT version();" | |
| - name: Run PostgreSQL tests (scoped on branches, full on main) | |
| # Main branch: full test suite validates complete PostgreSQL compatibility | |
| # Feature branches: scoped tests for faster iteration | |
| # Using --test-threads=4 - concurrent tests use #[serial] for isolation (issue #36) | |
| run: | | |
| if [ "${{ github.ref }}" = "refs/heads/main" ]; then | |
| echo "π Running FULL test suite on main branch..." | |
| cargo test --features postgresql -- --test-threads=4 | |
| else | |
| echo "π Running SCOPED database tests on feature branch..." | |
| cargo test --features postgresql database_plugins -- --test-threads=4 | |
| fi | |
| timeout-minutes: 30 | |
| env: | |
| DATABASE_URL: "postgresql://pierre:ci_test_password@localhost:5432/pierre_mcp_server" | |
| ENCRYPTION_KEY: "rEFe91l6lqLahoyl9OSzum9dKa40VvV5RYj8bHGNTeo=" | |
| PIERRE_MASTER_ENCRYPTION_KEY: "rEFe91l6lqLahoyl9OSzum9dKa40VvV5RYj8bHGNTeo=" | |
| PIERRE_RSA_KEY_SIZE: "2048" | |
| STRAVA_CLIENT_ID: "test_client_id_ci" | |
| STRAVA_CLIENT_SECRET: "test_client_secret_ci" | |
| STRAVA_REDIRECT_URI: "http://localhost:8080/auth/strava/callback" | |
| POSTGRES_MAX_CONNECTIONS: "3" | |
| POSTGRES_MIN_CONNECTIONS: "1" | |
| POSTGRES_ACQUIRE_TIMEOUT: "20" | |
| RUST_LOG: "info" | |
| USDA_API_KEY: ${{ secrets.USDA_API_KEY }} | |
| redis-tests: | |
| name: Cache Tests (Redis) | |
| runs-on: ubuntu-latest | |
| services: | |
| redis: | |
| image: redis:7-alpine | |
| options: >- | |
| --health-cmd "redis-cli ping" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 6379:6379 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Free Disk Space (Ubuntu) | |
| uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: false | |
| android: true | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| docker-images: true | |
| swap-storage: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@1.92.0 | |
| - name: Cache Rust dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-redis-1.92.0-v2-${{ hashFiles('**/Cargo.lock', 'migrations/**') }} | |
| - name: Install Redis tools | |
| run: sudo apt-get update && sudo apt-get install -y redis-tools | |
| - name: Wait for Redis | |
| run: | | |
| echo "π΄ Waiting for Redis to be ready..." | |
| timeout 60 bash -c 'until redis-cli -h localhost -p 6379 ping | grep -q PONG; do sleep 2; done' | |
| echo "β Redis is ready!" | |
| - name: Verify Redis connection | |
| run: | | |
| echo "π§ Testing Redis connection..." | |
| redis-cli -h localhost -p 6379 INFO server | head -10 | |
| - name: Run Redis cache tests | |
| # Coverage provided by SQLite backend tests - Redis tests validate integration only | |
| run: cargo test --test cache_redis_test -- --test-threads=1 | |
| env: | |
| REDIS_URL: "redis://localhost:6379" | |
| DATABASE_URL: "sqlite::memory:" | |
| ENCRYPTION_KEY: "rEFe91l6lqLahoyl9OSzum9dKa40VvV5RYj8bHGNTeo=" | |
| PIERRE_MASTER_ENCRYPTION_KEY: "rEFe91l6lqLahoyl9OSzum9dKa40VvV5RYj8bHGNTeo=" | |
| PIERRE_RSA_KEY_SIZE: "2048" | |
| STRAVA_CLIENT_ID: "test_client_id_ci" | |
| STRAVA_CLIENT_SECRET: "test_client_secret_ci" | |
| STRAVA_REDIRECT_URI: "http://localhost:8080/auth/strava/callback" | |
| RUST_LOG: "info" | |
| # Release binary validation (runs on push/PR and weekly schedule) | |
| release-binary: | |
| name: Release Binary Validation | |
| runs-on: ubuntu-latest | |
| needs: clippy | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Free Disk Space (Ubuntu) | |
| uses: jlumbroso/free-disk-space@main | |
| with: | |
| tool-cache: false | |
| android: true | |
| dotnet: true | |
| haskell: true | |
| large-packages: true | |
| docker-images: true | |
| swap-storage: true | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@1.92.0 | |
| - name: Cache Rust dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: ${{ runner.os }}-cargo-release-1.92.0-v2-${{ hashFiles('**/Cargo.lock', 'migrations/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-release-1.92.0-v2- | |
| # SDK build removed - release binary validation focuses on Rust binary only | |
| # Full test suite with SDK is covered by backend-tests job | |
| - name: Build release binary | |
| run: cargo build --release --verbose | |
| env: | |
| CARGO_INCREMENTAL: 0 | |
| RUSTFLAGS: "-C opt-level=3" | |
| - name: Verify release binary exists | |
| run: | | |
| if [ -f "target/release/pierre-mcp-server" ]; then | |
| echo "β Release binary built successfully" | |
| ls -lh target/release/pierre-mcp-server | |
| else | |
| echo "β Release binary not found" | |
| exit 1 | |
| fi | |
| - name: Check release binary size | |
| run: | | |
| BINARY_SIZE_BYTES=$(ls -l target/release/pierre-mcp-server | awk '{print $5}') | |
| BINARY_SIZE_MB=$((BINARY_SIZE_BYTES / 1024 / 1024)) | |
| MAX_SIZE_MB=50 | |
| echo "Binary size: ${BINARY_SIZE_MB}MB" | |
| if [ "$BINARY_SIZE_MB" -le "$MAX_SIZE_MB" ]; then | |
| echo "β Binary size (${BINARY_SIZE_MB}MB) within limit (<${MAX_SIZE_MB}MB)" | |
| else | |
| echo "β Binary size (${BINARY_SIZE_MB}MB) exceeds limit (${MAX_SIZE_MB}MB)" | |
| exit 1 | |
| fi | |
| # Full test suite removed - SQLite backend-tests job provides comprehensive coverage | |
| # Release binary validation focuses on build success and binary size | |
| - name: Basic smoke test of release binary | |
| run: | | |
| timeout 5 target/release/pierre-mcp-server --version || true | |
| echo "β Release binary executed successfully" | |
| - name: Upload release binary as artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pierre-mcp-server-release-ubuntu | |
| path: target/release/pierre-mcp-server | |
| retention-days: 7 |