Skip to content

Commit cc52ae2

Browse files
authored
Build: Post bench reports as Semantic Performance Bot (#147)
* Build: Post bench reports as Semantic Performance Bot Swap the comment job and the history-archive job from `GITHUB_TOKEN` to an installation token minted via `actions/create-github-app-token@v1`, driven by the two secrets already set up in repo settings: - SEMANTIC_PERF_BOT_APP_ID - SEMANTIC_PERF_BOT_PRIVATE_KEY Same permission surface as before — Pull requests (write), Contents (write), Actions (read). Branded identity, not widened scope. Effect downstream: - PR bench comments post as the bot with its uploaded SUI-themed avatar instead of the generic `github-actions[bot]` face. - Archival commits on main are authored by the bot, so git blame / history listings clearly show which chunk of main was machine- authored bench bookkeeping vs. developer work. Commit-author fields on the archive step use the `<app-id>+<app-slug>[bot]@users.noreply.github.com` format. Slug assumed to be `semantic-performance-bot` — if the app was registered under a different slug, that's a one-line fix in this file. GitHub still attributes the commit to the app regardless, the slug just affects the display email and avatar linkage. Also bundles `docs/public/images/{heap,performance}-avatar.png` staged alongside — the avatar assets land with the workflow change that uses them. Acceptance test: next PR that touches `packages/**` after this merges posts its bench comment under the bot's identity. One-commit revert restores `GITHUB_TOKEN` if anything's off. * Build: Tighten bench path filter — tools/bench-reporter in, report yml out Two corrections to the pull_request path filter now that we've exercised the workflow enough to see the gaps: - Add `tools/bench-reporter/**`. A PR that modifies only reporter.js or append-history.js previously didn't trigger benchmarks, yet those scripts run from the PR-head checkout when the report workflow fires, so the change DOES take effect on the PR's own comment. Missed coverage. - Drop `.github/workflows/benchmarks-report.yml`. This workflow file is the `workflow_run` handler — GitHub runs it from main's copy, not the PR's, which means a PR that modifies only this file cannot validate its own change inline anyway. Triggering benchmarks on such a PR wastes ~10 min of CI without producing actionable signal. `benchmarks.yml` itself stays in the filter — it's the `pull_request` entry point and GitHub runs it from PR-head YAML, so self-validation works.
1 parent 19f8e6f commit cc52ae2

4 files changed

Lines changed: 47 additions & 6 deletions

File tree

.github/workflows/benchmarks-report.yml

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@ jobs:
2323
github.event.workflow_run.conclusion == 'success'
2424
&& github.event.workflow_run.event == 'pull_request'
2525
steps:
26+
# Generate an installation access token for the Semantic Performance
27+
# Bot GitHub App. Comments post under the bot's identity + avatar
28+
# rather than the generic `github-actions[bot]`. Same permissions
29+
# surface as GITHUB_TOKEN; branded, not widened.
30+
- name: Generate bot token
31+
id: bot-token
32+
uses: actions/create-github-app-token@v1
33+
with:
34+
app-id: ${{ secrets.SEMANTIC_PERF_BOT_APP_ID }}
35+
private-key: ${{ secrets.SEMANTIC_PERF_BOT_PRIVATE_KEY }}
36+
2637
- uses: actions/checkout@v4
2738
with:
2839
ref: ${{ github.event.workflow_run.head_sha }}
@@ -43,6 +54,7 @@ jobs:
4354
- name: Download bench artifacts
4455
uses: dawidd6/action-download-artifact@v2
4556
with:
57+
github_token: ${{ steps.bot-token.outputs.token }}
4658
workflow: ${{ github.event.workflow.id }}
4759
run_id: ${{ github.event.workflow_run.id }}
4860
name_is_regexp: true
@@ -52,7 +64,7 @@ jobs:
5264
- name: Resolve PR number
5365
id: pr
5466
env:
55-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67+
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
5668
run: |
5769
NUMBER='${{ github.event.workflow_run.pull_requests[0].number }}'
5870
if [ -z "$NUMBER" ] || [ "$NUMBER" = "null" ]; then
@@ -89,10 +101,13 @@ jobs:
89101
- name: Post or update PR comment
90102
if: steps.pr.outputs.number != ''
91103
env:
92-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
104+
GH_TOKEN: ${{ steps.bot-token.outputs.token }}
93105
PR: ${{ steps.pr.outputs.number }}
94106
REPO: ${{ github.repository }}
95107
run: |
108+
# --edit-last finds the most recent comment from the authenticated
109+
# user; with the bot token, that targets the bot's previous bench
110+
# comment (not github-actions[bot]'s earlier artifacts).
96111
if ! gh pr comment "$PR" --repo "$REPO" --edit-last \
97112
--body-file bench-report/comment.md 2>/dev/null; then
98113
gh pr comment "$PR" --repo "$REPO" \
@@ -115,14 +130,23 @@ jobs:
115130
group: bench-history-append
116131
cancel-in-progress: false
117132
steps:
133+
# Bot token for the archival commit — shows up on main as authored
134+
# by Semantic Performance Bot rather than github-actions[bot].
135+
- name: Generate bot token
136+
id: bot-token
137+
uses: actions/create-github-app-token@v1
138+
with:
139+
app-id: ${{ secrets.SEMANTIC_PERF_BOT_APP_ID }}
140+
private-key: ${{ secrets.SEMANTIC_PERF_BOT_PRIVATE_KEY }}
141+
118142
# Check out main's tip for the commit target. We push back to main,
119143
# so we need the most recent state — not the bench's head_sha (which
120144
# may have been superseded by a later merge during the ~10-min bench).
121145
- uses: actions/checkout@v4
122146
with:
123147
ref: main
124148
fetch-depth: 2 # need HEAD~1 for parent_sha lookup
125-
token: ${{ secrets.GITHUB_TOKEN }}
149+
token: ${{ steps.bot-token.outputs.token }}
126150

127151
- uses: actions/setup-node@v4
128152
with:
@@ -131,6 +155,7 @@ jobs:
131155
- name: Download bench artifacts
132156
uses: dawidd6/action-download-artifact@v2
133157
with:
158+
github_token: ${{ steps.bot-token.outputs.token }}
134159
workflow: ${{ github.event.workflow.id }}
135160
run_id: ${{ github.event.workflow_run.id }}
136161
name_is_regexp: true
@@ -155,9 +180,16 @@ jobs:
155180
--history bench-history.json
156181
157182
- name: Commit + push
183+
env:
184+
# The checkout step's token persists as the git remote's credential
185+
# helper, so the push below authenticates as the bot automatically.
186+
BOT_APP_SLUG: semantic-performance-bot
158187
run: |
159-
git config user.name 'github-actions[bot]'
160-
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
188+
# Use the bot's noreply email format. The exact local-part is the
189+
# app's numeric user id; GitHub renders the commit as authored by
190+
# the app regardless, as long as the name matches the app slug.
191+
git config user.name 'semantic-performance-bot[bot]'
192+
git config user.email '${{ secrets.SEMANTIC_PERF_BOT_APP_ID }}+semantic-performance-bot[bot]@users.noreply.github.com'
161193
# If nothing changed (e.g. a re-run for a SHA already archived with
162194
# identical numbers), skip rather than making an empty commit.
163195
if git diff --quiet bench-history.json; then

.github/workflows/benchmarks.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,18 @@ name: Benchmarks
33
on:
44
pull_request:
55
paths:
6+
# perf-sensitive code — the measurement target
67
- 'packages/**'
8+
# bench workflow itself — changes here take effect on this PR's own
9+
# run (pull_request uses PR-head YAML), so self-test
710
- '.github/workflows/benchmarks.yml'
8-
- '.github/workflows/benchmarks-report.yml'
11+
# reporter scripts — runs from PR-head via the report workflow's
12+
# checkout step, so a PR that only changes reporter.js still gets
13+
# its output rendered on its own bench comment. Note: we deliberately
14+
# DON'T include `.github/workflows/benchmarks-report.yml` here — that
15+
# file runs from main's copy (workflow_run constraint), so modifying
16+
# it on a PR doesn't exercise the change until after merge.
17+
- 'tools/bench-reporter/**'
918
# Bench every merge commit on main so bench-history.json accumulates
1019
# absolute CIs per commit. These runs aren't gated against anything —
1120
# the report workflow branches on event type and appends history instead

docs/public/images/heap-avatar.png

981 KB
Loading
914 KB
Loading

0 commit comments

Comments
 (0)