Initial release v0.1.0 #1
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
| # ReasonKit Core - Quality Gates CI/CD | |
| # Enforces CONS-009: All 5 quality gates must pass | |
| # Reference: ORCHESTRATOR.md v3.3.0 | |
| name: Quality Gates | |
| on: | |
| push: | |
| branches: [main, develop, feature/*] | |
| pull_request: | |
| branches: [main, develop] | |
| workflow_dispatch: | |
| # Cancel in-progress runs for same workflow and branch | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUSTFLAGS: "-D warnings" | |
| RUST_BACKTRACE: 1 | |
| jobs: | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # GATE 1: Build Check (BLOCKING) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| gate1-build: | |
| name: "Gate 1: Build" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| prefix-key: "v1-gate1" | |
| - name: Check Cargo.lock is up to date | |
| run: cargo update --workspace --locked | |
| - name: Build (release) | |
| run: cargo build --release --locked | |
| - name: Build (all features) | |
| run: cargo build --all-features --locked | |
| - name: Build (no default features) | |
| run: cargo build --no-default-features --locked | |
| - name: Upload binary artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: rk-core-binary | |
| path: target/release/rk-core | |
| retention-days: 7 | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # GATE 2: Lint with Clippy (BLOCKING) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| gate2-lint: | |
| name: "Gate 2: Clippy" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| prefix-key: "v1-gate2" | |
| - name: Run Clippy (strict) | |
| run: | | |
| cargo clippy --all-targets --all-features --locked -- \ | |
| -D warnings \ | |
| -W clippy::pedantic \ | |
| -W clippy::nursery \ | |
| -W clippy::cargo \ | |
| -W clippy::suspicious \ | |
| -W clippy::perf \ | |
| -W clippy::correctness | |
| - name: Run Clippy (default features) | |
| run: cargo clippy --locked -- -D warnings | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # GATE 3: Format Check (BLOCKING) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| gate3-format: | |
| name: "Gate 3: Format" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: rustfmt | |
| - name: Check formatting | |
| run: cargo fmt --all -- --check | |
| - name: Generate format diff (on failure) | |
| if: failure() | |
| run: | | |
| cargo fmt --all -- --check --verbose | |
| echo "Run 'cargo fmt' to fix formatting issues" | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # GATE 4: Tests (BLOCKING) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| gate4-test: | |
| name: "Gate 4: Tests" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| prefix-key: "v1-gate4" | |
| - name: Run library tests | |
| run: cargo test --lib --all-features --locked | |
| - name: Run binary tests | |
| run: cargo test --bins --all-features --locked | |
| - name: Run integration tests | |
| run: cargo test --tests --all-features --locked | |
| - name: Run doc tests | |
| run: cargo test --doc --all-features --locked | |
| - name: Test with no default features | |
| run: cargo test --no-default-features --locked | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # GATE 5: Benchmarks (MONITORING - not blocking) | |
| # Research-backed performance targets from DEVELOPMENT_PLAN.md: | |
| # - Rerank latency: < 200ms for top-20 (arXiv:2010.06467) | |
| # - Fusion latency: < 50ms (RRF paper) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| gate5-bench: | |
| name: "Gate 5: Benchmarks" | |
| runs-on: ubuntu-latest | |
| if: contains(github.event.pull_request.labels.*.name, 'performance') || github.event_name == 'workflow_dispatch' | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Setup Rust cache | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| prefix-key: "v1-gate5" | |
| - name: Run retrieval benchmarks | |
| run: cargo bench --bench retrieval_bench -- --noplot | |
| continue-on-error: true | |
| - name: Run rerank benchmarks (target <200ms) | |
| run: cargo bench --bench rerank_bench -- --noplot | |
| continue-on-error: true | |
| - name: Run fusion benchmarks | |
| run: cargo bench --bench fusion_bench -- --noplot | |
| continue-on-error: true | |
| - name: Generate benchmark summary | |
| if: always() | |
| run: | | |
| echo "## Benchmark Results" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Benchmark | Target | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-----------|--------|--------|" >> $GITHUB_STEP_SUMMARY | |
| echo "| Rerank (20 candidates) | < 200ms | See logs |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Fusion RRF | < 50ms | See logs |" >> $GITHUB_STEP_SUMMARY | |
| echo "| BM25 Search | < 10ms | See logs |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "Full results in Criterion reports." >> $GITHUB_STEP_SUMMARY | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Quality Metrics Collection | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| metrics: | |
| name: "Quality Metrics" | |
| runs-on: ubuntu-latest | |
| needs: [gate1-build, gate2-lint, gate3-format, gate4-test] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install tools | |
| run: sudo apt-get update && sudo apt-get install -y jq cloc bc | |
| - name: Calculate metrics | |
| run: | | |
| echo "## Quality Metrics Report" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY | |
| echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY | |
| # Code metrics | |
| RUST_LINES=$(find src -name '*.rs' -exec cat {} \; | wc -l) | |
| echo "| Lines of Rust | $RUST_LINES |" >> $GITHUB_STEP_SUMMARY | |
| # Quality indicators | |
| TODO_COUNT=$(grep -r 'TODO' src --include='*.rs' | wc -l || echo 0) | |
| echo "| TODO count | $TODO_COUNT |" >> $GITHUB_STEP_SUMMARY | |
| FIXME_COUNT=$(grep -r 'FIXME' src --include='*.rs' | wc -l || echo 0) | |
| echo "| FIXME count | $FIXME_COUNT |" >> $GITHUB_STEP_SUMMARY | |
| UNSAFE_COUNT=$(grep -r 'unsafe' src --include='*.rs' | wc -l || echo 0) | |
| echo "| Unsafe blocks | $UNSAFE_COUNT |" >> $GITHUB_STEP_SUMMARY | |
| # Dependency count | |
| DEP_COUNT=$(cargo metadata --no-deps --format-version 1 | jq '.packages[0].dependencies | length') | |
| echo "| Direct dependencies | $DEP_COUNT |" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Gate Status" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Gate 1: Build" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Gate 2: Clippy" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Gate 3: Format" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Gate 4: Tests" >> $GITHUB_STEP_SUMMARY | |
| echo "- ℹ️ Gate 5: Benchmarks (conditional)" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**All quality gates passed! 🎉**" >> $GITHUB_STEP_SUMMARY | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Security Audit (Non-blocking but monitored) | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| security: | |
| name: "Security Audit" | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install cargo-audit | |
| run: cargo install cargo-audit --locked | |
| - name: Run security audit | |
| run: cargo audit | |
| continue-on-error: true | |
| - name: Run cargo-deny | |
| uses: EmbarkStudios/cargo-deny-action@v1 | |
| with: | |
| log-level: warn | |
| command: check advisories | |
| continue-on-error: true | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| # Final Status Check | |
| # ═══════════════════════════════════════════════════════════════════════════ | |
| ci-success: | |
| name: "CI Success" | |
| runs-on: ubuntu-latest | |
| needs: [gate1-build, gate2-lint, gate3-format, gate4-test, metrics] | |
| if: always() | |
| steps: | |
| - name: Check gate results | |
| run: | | |
| if [ "${{ needs.gate1-build.result }}" != "success" ] || \ | |
| [ "${{ needs.gate2-lint.result }}" != "success" ] || \ | |
| [ "${{ needs.gate3-format.result }}" != "success" ] || \ | |
| [ "${{ needs.gate4-test.result }}" != "success" ]; then | |
| echo "❌ One or more quality gates failed" | |
| echo "Gate 1 (Build): ${{ needs.gate1-build.result }}" | |
| echo "Gate 2 (Lint): ${{ needs.gate2-lint.result }}" | |
| echo "Gate 3 (Format): ${{ needs.gate3-format.result }}" | |
| echo "Gate 4 (Test): ${{ needs.gate4-test.result }}" | |
| exit 1 | |
| else | |
| echo "✅ All quality gates passed!" | |
| fi |