benchmark-pr.ymlβ’6.01 kB
name: Benchmark PR Comparison
on:
pull_request:
branches: [main]
paths-ignore:
- '**.md'
- '**.txt'
- 'docs/**'
- 'examples/**'
- '.github/FUNDING.yml'
- '.github/ISSUE_TEMPLATE/**'
- '.github/pull_request_template.md'
- '.gitignore'
- 'LICENSE*'
- 'ATTRIBUTION.md'
- 'SECURITY.md'
- 'CODE_OF_CONDUCT.md'
permissions:
pull-requests: write
contents: read
statuses: write
jobs:
benchmark-comparison:
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
# Run benchmarks on current branch
- name: Run current benchmarks
run: npm run benchmark:ci
- name: Save current results
run: cp benchmark-results.json benchmark-current.json
# Checkout and run benchmarks on base branch
- name: Checkout base branch
run: |
git checkout ${{ github.event.pull_request.base.sha }}
git status
- name: Install base dependencies
run: npm ci
- name: Run baseline benchmarks
run: npm run benchmark:ci
continue-on-error: true
- name: Save baseline results
run: |
if [ -f benchmark-results.json ]; then
cp benchmark-results.json benchmark-baseline.json
else
echo '{"files":[]}' > benchmark-baseline.json
fi
# Compare results
- name: Checkout PR branch again
run: git checkout ${{ github.event.pull_request.head.sha }}
- name: Compare benchmarks
id: compare
run: |
node scripts/compare-benchmarks.js benchmark-current.json benchmark-baseline.json || echo "REGRESSION=true" >> $GITHUB_OUTPUT
# Upload comparison artifacts
- name: Upload benchmark comparison
if: always()
uses: actions/upload-artifact@v4
with:
name: benchmark-comparison-${{ github.run_number }}
path: |
benchmark-current.json
benchmark-baseline.json
benchmark-comparison.json
benchmark-comparison.md
retention-days: 30
# Post comparison to PR
- name: Post benchmark comparison to PR
if: always()
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
try {
const fs = require('fs');
let comment = '## β‘ Benchmark Comparison\n\n';
try {
if (fs.existsSync('benchmark-comparison.md')) {
const comparison = fs.readFileSync('benchmark-comparison.md', 'utf8');
comment += comparison;
} else {
comment += 'Benchmark comparison could not be generated.';
}
} catch (error) {
comment += `Error reading benchmark comparison: ${error.message}`;
}
comment += '\n\n---\n';
comment += `*[View full benchmark results](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})*`;
// Find existing comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('## β‘ Benchmark Comparison')
);
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: comment
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
}
} catch (error) {
console.error('Failed to create/update PR comment:', error.message);
console.log('This is likely due to insufficient permissions for external PRs.');
console.log('Benchmark comparison has been saved to artifacts instead.');
}
# Add status check
- name: Set benchmark status
if: always()
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
try {
const hasRegression = '${{ steps.compare.outputs.REGRESSION }}' === 'true';
const state = hasRegression ? 'failure' : 'success';
const description = hasRegression
? 'Performance regressions detected'
: 'No performance regressions';
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: context.sha,
state: state,
target_url: `https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}`,
description: description,
context: 'benchmarks/regression-check'
});
} catch (error) {
console.error('Failed to create commit status:', error.message);
console.log('This is likely due to insufficient permissions for external PRs.');
}