name: Performance Benchmarks on: push: branches: [main] workflow_dispatch: concurrency: group: bench-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true permissions: contents: read pull-requests: write env: CARGO_TERM_COLOR: always jobs: benchmarks: name: Criterion Benchmarks runs-on: blacksmith-2vcpu-ubuntu-2404 timeout-minutes: 30 steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable with: toolchain: 1.92.0 - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 - name: Run benchmarks run: cargo bench --locked 2>&1 | tee benchmark_output.txt - name: Upload benchmark results if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: benchmark-results path: | target/criterion/ benchmark_output.txt retention-days: 30 - name: Post benchmark summary on PR if: github.event_name == 'pull_request' uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: script: | const fs = require('fs'); const output = fs.readFileSync('benchmark_output.txt', 'utf8'); // Extract Criterion result lines const lines = output.split('\n').filter(l => l.includes('time:') || l.includes('change:') || l.includes('Performance') ); if (lines.length === 0) { core.info('No benchmark results to post.'); return; } const body = [ '## 📊 Benchmark Results', '', '```', lines.join('\n'), '```', '', '
Full output', '', '```', output.substring(0, 60000), '```', '
', ].join('\n'); // Find and update or create comment const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, }); const marker = '## 📊 Benchmark Results'; const existing = comments.find(c => c.body && c.body.startsWith(marker)); if (existing) { await github.rest.issues.updateComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: existing.id, body, }); } else { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.payload.pull_request.number, body, }); }