-
Notifications
You must be signed in to change notification settings - Fork 14
ci(bench): add per-PR perf canary for extractor/graph/native changes #1488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3892e7d
ef8ea4f
a372b82
9a52c7c
85a26df
184d221
909e1df
66fc899
84e1a5f
c4f221f
ffd2013
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,113 @@ | ||||||||||||||||||
| name: Perf Canary | ||||||||||||||||||
|
|
||||||||||||||||||
| # Lightweight per-PR build-time regression gate for PRs that touch the | ||||||||||||||||||
| # extractor, graph-builder, or native Rust layers — the parts of the codebase | ||||||||||||||||||
| # that caused the v3.12.0 regressions (+1827% 1-file rebuild, +98% full build). | ||||||||||||||||||
| # | ||||||||||||||||||
| # Only the incremental-benchmark suite is run (full build + no-op + 1-file | ||||||||||||||||||
| # rebuild for both engines). The regression guard uses BENCH_CANARY=1 mode, | ||||||||||||||||||
| # which applies a 50% threshold instead of the full suite's 25% — enough | ||||||||||||||||||
| # to catch catastrophic regressions while tolerating CI runner variance. | ||||||||||||||||||
| # | ||||||||||||||||||
| # This is intentionally separate from the full pre-publish-benchmark job in | ||||||||||||||||||
| # ci.yml, which runs unconditionally on every PR and measures the complete | ||||||||||||||||||
| # suite. The canary completes in roughly 5–10 minutes; the full suite takes | ||||||||||||||||||
| # 20–60 minutes. | ||||||||||||||||||
|
|
||||||||||||||||||
| on: | ||||||||||||||||||
| pull_request: | ||||||||||||||||||
| paths: | ||||||||||||||||||
| - "src/extractors/**" | ||||||||||||||||||
| - "src/domain/graph/**" | ||||||||||||||||||
| - "crates/**" | ||||||||||||||||||
| - "scripts/benchmark.ts" | ||||||||||||||||||
| - "scripts/incremental-benchmark.ts" | ||||||||||||||||||
| - "scripts/lib/bench-config.ts" | ||||||||||||||||||
| - "scripts/lib/fork-engine.ts" | ||||||||||||||||||
| - "scripts/update-incremental-report.ts" | ||||||||||||||||||
| - "tests/benchmarks/regression-guard.test.ts" | ||||||||||||||||||
|
|
||||||||||||||||||
| permissions: {} | ||||||||||||||||||
|
|
||||||||||||||||||
| concurrency: | ||||||||||||||||||
| group: perf-canary-${{ github.ref }} | ||||||||||||||||||
| cancel-in-progress: true | ||||||||||||||||||
|
Comment on lines
+32
to
+34
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed — added |
||||||||||||||||||
|
|
||||||||||||||||||
| jobs: | ||||||||||||||||||
| perf-canary: | ||||||||||||||||||
| name: Perf canary (incremental tiers) | ||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||
| env: | ||||||||||||||||||
| CODEGRAPH_FAST_SKIP_DIAG: "1" | ||||||||||||||||||
|
|
||||||||||||||||||
| steps: | ||||||||||||||||||
| - uses: actions/checkout@v6 | ||||||||||||||||||
|
|
||||||||||||||||||
| - uses: actions/setup-node@v6 | ||||||||||||||||||
| with: | ||||||||||||||||||
| node-version: 22 | ||||||||||||||||||
| cache: "npm" | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Setup Rust | ||||||||||||||||||
| uses: dtolnay/rust-toolchain@stable | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Rust cache | ||||||||||||||||||
| uses: Swatinem/rust-cache@v2 | ||||||||||||||||||
| with: | ||||||||||||||||||
| workspaces: crates/codegraph-core | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Install napi-rs CLI | ||||||||||||||||||
| timeout-minutes: 5 | ||||||||||||||||||
| run: npm install -g @napi-rs/cli@3 | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Build native addon | ||||||||||||||||||
| working-directory: crates/codegraph-core | ||||||||||||||||||
| run: napi build --release | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||
| timeout-minutes: 20 | ||||||||||||||||||
| shell: bash | ||||||||||||||||||
| run: | | ||||||||||||||||||
| for attempt in 1 2 3; do | ||||||||||||||||||
| npm install && break | ||||||||||||||||||
| if [ "$attempt" -lt 3 ]; then | ||||||||||||||||||
| echo "::warning::npm install attempt $attempt failed, retrying in 15s..." | ||||||||||||||||||
| sleep 15 | ||||||||||||||||||
| else | ||||||||||||||||||
| echo "::error::npm install failed after 3 attempts" | ||||||||||||||||||
| exit 1 | ||||||||||||||||||
| fi | ||||||||||||||||||
| done | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Install native addon over published binary | ||||||||||||||||||
| run: node scripts/ci-install-native.mjs | ||||||||||||||||||
|
|
||||||||||||||||||
| # Build dist/ so benchmarks load the same compiled JS that ships to npm, | ||||||||||||||||||
| # matching the methodology used by the full pre-publish-benchmark gate. | ||||||||||||||||||
| - name: Build TypeScript | ||||||||||||||||||
| run: npm run build | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Run incremental benchmark | ||||||||||||||||||
| timeout-minutes: 15 | ||||||||||||||||||
| run: | | ||||||||||||||||||
| STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')") | ||||||||||||||||||
| node $STRIP_FLAG --import ./scripts/ts-resolve-loader.js scripts/incremental-benchmark.ts --version dev --dist > incremental-canary-result.json | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Update incremental report | ||||||||||||||||||
| run: | | ||||||||||||||||||
| STRIP_FLAG=$(node -e "const [M]=process.versions.node.split('.').map(Number); console.log(M>=23?'--strip-types':'--experimental-strip-types')") | ||||||||||||||||||
| node $STRIP_FLAG scripts/update-incremental-report.ts incremental-canary-result.json | ||||||||||||||||||
|
|
||||||||||||||||||
| - name: Regression guard (50% threshold) | ||||||||||||||||||
| env: | ||||||||||||||||||
| RUN_REGRESSION_GUARD: "1" | ||||||||||||||||||
| BENCH_CANARY: "1" | ||||||||||||||||||
| run: npm run test:regression-guard | ||||||||||||||||||
|
Comment on lines
+101
to
+105
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The workflow is a separate file and is not included in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Acknowledged — making the canary a required status check in branch protection rules is a repo settings change, not a code change. Filed as a follow-up action for the repo admin to add |
||||||||||||||||||
|
|
||||||||||||||||||
| - name: Upload canary result | ||||||||||||||||||
| if: always() | ||||||||||||||||||
| uses: actions/upload-artifact@v7 | ||||||||||||||||||
| with: | ||||||||||||||||||
| name: incremental-canary-result | ||||||||||||||||||
| path: incremental-canary-result.json | ||||||||||||||||||
| if-no-files-found: warn | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests/benchmarks/regression-guard.test.tsorscripts/update-incremental-report.ts. This very PR modifies the former to introduceBENCH_CANARYmode, but the canary won't fire for that change because nosrc/extractors/**/crates/**paths were touched. A future PR that adjusts the canary thresholds or the report-update logic will silently bypass this gate: the fullpre-publish-benchmarkruns but withoutBENCH_CANARY=1, so the BENCH_CANARY code path is never exercised in CI.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed — added both
scripts/update-incremental-report.tsandtests/benchmarks/regression-guard.test.tsto the path filter. PRs that only touch the canary infrastructure will now correctly trigger the canary run.