fix(deps): update rust crate toml to v1 #27
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: Performance Benchmarks | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'crates/**' | |
| - 'benchmarks/**' | |
| - 'Cargo.toml' | |
| - 'Cargo.lock' | |
| - '.github/workflows/benchmarks.yml' | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| # Criterion bench targets to run (real_corpus is excluded -- requires QNDX_BENCH_CORPUS) | |
| BENCH_TARGETS: "serializer_choice postings_choice ngram_extract query_planner end_to_end_search git_overlay" | |
| jobs: | |
| benchmark: | |
| name: Run Benchmarks | |
| runs-on: [self-hosted, freebsd] | |
| timeout-minutes: 60 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| cache-on-failure: true | |
| - name: Install gnuplot (for Criterion HTML reports) | |
| run: pkg install -y gnuplot | |
| - name: Restore baseline from main branch | |
| if: github.event_name == 'pull_request' | |
| id: restore-baseline | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: target/criterion | |
| key: benchmark-baseline-${{ github.base_ref }}-${{ hashFiles('benchmarks/budgets.toml') }} | |
| restore-keys: | | |
| benchmark-baseline-${{ github.base_ref }}- | |
| benchmark-baseline-main- | |
| # --------------------------------------------------------------- | |
| # PR with baseline: compare against saved main baseline | |
| # --------------------------------------------------------------- | |
| - name: Run benchmarks (PR - with baseline comparison) | |
| if: github.event_name == 'pull_request' && steps.restore-baseline.outputs.cache-hit == 'true' | |
| run: | | |
| echo "::group::Running benchmarks against main baseline" | |
| for bench in $BENCH_TARGETS; do | |
| echo "--- $bench ---" | |
| cargo bench -p qndx-bench --bench "$bench" -- --baseline main 2>&1 | tee -a bench-output.txt | |
| done | |
| echo "::endgroup::" | |
| # --------------------------------------------------------------- | |
| # PR without baseline: just run and save as PR baseline | |
| # --------------------------------------------------------------- | |
| - name: Run benchmarks (PR - no baseline) | |
| if: github.event_name == 'pull_request' && steps.restore-baseline.outputs.cache-hit != 'true' | |
| run: | | |
| echo "::warning::No baseline found, running benchmarks without comparison" | |
| for bench in $BENCH_TARGETS; do | |
| echo "--- $bench ---" | |
| cargo bench -p qndx-bench --bench "$bench" -- --save-baseline "pr-${{ github.event.pull_request.number }}" | |
| done | |
| # --------------------------------------------------------------- | |
| # Main branch push: save as the canonical baseline | |
| # --------------------------------------------------------------- | |
| - name: Run benchmarks (main branch - save as baseline) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| run: | | |
| echo "::group::Running benchmarks and saving as baseline" | |
| for bench in $BENCH_TARGETS; do | |
| echo "--- $bench ---" | |
| cargo bench -p qndx-bench --bench "$bench" -- --save-baseline main | |
| done | |
| echo "::endgroup::" | |
| # --------------------------------------------------------------- | |
| # Check for regressions in Criterion output | |
| # --------------------------------------------------------------- | |
| - name: Check performance budgets | |
| if: github.event_name == 'pull_request' && steps.restore-baseline.outputs.cache-hit == 'true' | |
| run: | | |
| echo "::group::Checking performance budgets" | |
| # Criterion prints "Performance has regressed." to stdout when | |
| # a benchmark regresses beyond its noise threshold. | |
| REGRESSIONS=$(grep -c "Performance has regressed" bench-output.txt || true) | |
| if [ "$REGRESSIONS" -gt 0 ]; then | |
| echo "::warning::Criterion detected $REGRESSIONS benchmark regression(s)" | |
| echo "" | |
| echo "Regressed benchmarks:" | |
| grep -B2 "Performance has regressed" bench-output.txt || true | |
| echo "" | |
| fi | |
| # Check for large regressions (>20% change) | |
| # Criterion format: "change: [-1.2345% +23.4567% +45.6789%]" | |
| # The middle value is the point estimate. | |
| LARGE=$(awk '/change:/{ | |
| s=$0; n=0 | |
| while(match(s,/\+[0-9]+\.[0-9]+%/)){ | |
| n++; val=substr(s,RSTART+1,RLENGTH-2)+0 | |
| s=substr(s,RSTART+RLENGTH) | |
| if(n==2 && val>=20) print val | |
| } | |
| }' bench-output.txt || true) | |
| if [ -n "$LARGE" ]; then | |
| echo "::error::Significant performance regression (>20%) detected" | |
| grep -EB5 'change:.*\+[0-9]{2,}\.[0-9]' bench-output.txt || true | |
| exit 1 | |
| fi | |
| echo "::notice::Performance budgets check passed ($REGRESSIONS minor regression(s))" | |
| echo "::endgroup::" | |
| - name: Upload benchmark results | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: benchmark-results-${{ github.sha }} | |
| path: | | |
| target/criterion/ | |
| bench-output.txt | |
| retention-days: 90 | |
| - name: Save baseline cache (main branch) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: target/criterion | |
| key: benchmark-baseline-${{ github.ref_name }}-${{ hashFiles('benchmarks/budgets.toml') }} | |
| - name: Comment PR with benchmark summary | |
| if: github.event_name == 'pull_request' && steps.restore-baseline.outputs.cache-hit == 'true' | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| let output = ''; | |
| try { | |
| output = fs.readFileSync('bench-output.txt', 'utf8'); | |
| } catch (e) { | |
| output = '(benchmark output not available)'; | |
| } | |
| // Count regressions and improvements | |
| const regressions = (output.match(/Performance has regressed/g) || []).length; | |
| const improvements = (output.match(/Performance has improved/g) || []).length; | |
| const noChange = (output.match(/No change in performance/g) || []).length; | |
| let summary = '## Benchmark Results\n\n'; | |
| summary += `| Status | Count |\n|--------|-------|\n`; | |
| summary += `| Regressions | ${regressions} |\n`; | |
| summary += `| Improvements | ${improvements} |\n`; | |
| summary += `| No change | ${noChange} |\n\n`; | |
| if (regressions > 0) { | |
| summary += '### Regressions\n\n```\n'; | |
| const lines = output.split('\n'); | |
| for (let i = 0; i < lines.length; i++) { | |
| if (lines[i].includes('Performance has regressed')) { | |
| // Include benchmark name (2 lines before) and the change line | |
| const start = Math.max(0, i - 3); | |
| summary += lines.slice(start, i + 1).join('\n') + '\n\n'; | |
| } | |
| } | |
| summary += '```\n\n'; | |
| } | |
| summary += 'Download full results from the workflow artifacts.\n'; | |
| github.rest.issues.createComment({ | |
| issue_number: context.issue.number, | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| body: summary | |
| }); | |
| # ================================================================ | |
| # Nightly comprehensive benchmark run for trend tracking | |
| # ================================================================ | |
| nightly-benchmark: | |
| name: Nightly Comprehensive Benchmarks | |
| runs-on: [self-hosted, freebsd] | |
| if: github.event_name == 'workflow_dispatch' | |
| timeout-minutes: 120 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust dependencies | |
| uses: Swatinem/rust-cache@v2 | |
| - name: Set date | |
| run: echo "BENCH_DATE=$(date +%Y%m%d)" >> $GITHUB_ENV | |
| - name: Run all benchmarks | |
| run: | | |
| for bench in $BENCH_TARGETS; do | |
| echo "--- $bench ---" | |
| cargo bench -p qndx-bench --bench "$bench" -- --save-baseline "nightly-$BENCH_DATE" | |
| done | |
| - name: Upload nightly results | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: nightly-benchmark-${{ env.BENCH_DATE }} | |
| path: target/criterion/ | |
| retention-days: 365 |