Bot - Benchmark PR Comment #276
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: Bot - Benchmark PR Comment | |
| on: | |
| workflow_run: | |
| workflows: ["Benchmarks"] | |
| types: [completed] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| actions: read | |
| jobs: | |
| comment: | |
| if: github.event.workflow_run.event == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download benchmarks artifact | |
| uses: actions/github-script@v9 | |
| with: | |
| script: | | |
| const run_id = context.payload.workflow_run.id; | |
| const { data: list } = await github.rest.actions.listWorkflowRunArtifacts({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| run_id, | |
| }); | |
| const art = list.artifacts.find(a => a.name === 'benchmarks'); | |
| if (!art) { | |
| core.setFailed('benchmarks artifact missing'); | |
| return; | |
| } | |
| const dl = await github.rest.actions.downloadArtifact({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| artifact_id: art.id, | |
| archive_format: 'zip', | |
| }); | |
| const fs = require('fs'); | |
| fs.writeFileSync('benchmarks.zip', Buffer.from(dl.data)); | |
| - name: Unzip | |
| run: | | |
| mkdir -p bench | |
| unzip -o benchmarks.zip -d bench | |
| ls -la bench | |
| - name: Post comment | |
| uses: actions/github-script@v9 | |
| with: | |
| github-token: ${{ secrets.HOMEBREW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} | |
| script: | | |
| const fs = require('fs'); | |
| const read = (p, fallback = '') => { | |
| try { return fs.readFileSync(p, 'utf8'); } catch (_) { return fallback; } | |
| }; | |
| const prRaw = read('bench/pr-number.txt').trim(); | |
| const pr_number = parseInt(prRaw, 10); | |
| if (!pr_number) { | |
| core.info('no PR number recorded; skipping'); | |
| return; | |
| } | |
| const report = read('bench/benchstat.txt', '(empty)'); | |
| const verdict = read('bench/verdict.txt'); | |
| const parse = key => { | |
| const m = verdict.match(new RegExp("^" + key + "=(.+)$", "m")); | |
| return m ? m[1].trim() : ''; | |
| }; | |
| const status = parse('status') || 'neutral'; | |
| const worse = parse('worse') || '0'; | |
| const better = parse('better') || '0'; | |
| const headers = { | |
| regression: "### Benchmark report — regression detected", | |
| improvement: "### Benchmark report — improvement detected", | |
| neutral: "### Benchmark report — no significant change", | |
| }; | |
| const body = [ | |
| headers[status] || headers.neutral, | |
| `Metrics worse: **${worse}** · better: **${better}** (threshold: ±3%).`, | |
| "", | |
| "<details><summary>benchstat output</summary>", | |
| "", | |
| "```", | |
| report.trim() || "(empty)", | |
| "```", | |
| "", | |
| "</details>", | |
| "", | |
| "<sub>auto-generated by benchmarks.yml</sub>", | |
| ].join("\n"); | |
| const marker = "<sub>auto-generated by benchmarks.yml</sub>"; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: pr_number, | |
| }); | |
| const existing = comments.find(c => c.body && c.body.includes(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: pr_number, | |
| body, | |
| }); | |
| } |