Skip to content

Commit 8b225ce

Browse files
authored
ci: add PR benchmark workflows (#2271)
## Summary Extract the PR benchmark workflows from #2252 into a standalone PR so they can land on `main` first. ## Why The benchmark job uploads a Markdown artifact with the PR comment contents, but the actual PR comment is posted by a separate `workflow_run` workflow. GitHub only triggers `workflow_run` workflows when the workflow file already exists on the default branch, so keeping the reporter in the same PR prevents it from commenting on that PR's benchmark run. Splitting these workflows out first lets subsequent benchmark PRs use the comment-reporting flow as intended. ## Changes - add `PR Benchmarks` workflow triggered by the `benchmark` label on pull requests - add `PR Benchmark Report` workflow triggered by `workflow_run` - keep the benchmark summary as an uploaded artifact consumed by the reporter workflow ## Testing - `mise run lint:fix`
1 parent 3b2a33b commit 8b225ce

3 files changed

Lines changed: 162 additions & 0 deletions

File tree

.github/renovate-tracked-deps.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@
7373
"mise"
7474
]
7575
},
76+
".github/workflows/pr-benchmarks.yml": {
77+
"regex": [
78+
"mise"
79+
]
80+
},
7681
".github/workflows/regenerate-api-diff-otel.yml": {
7782
"regex": [
7883
"mise"
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
name: PR Benchmark Report
3+
4+
on:
5+
# zizmor: ignore[dangerous-triggers] -- this workflow never checks out or executes PR code;
6+
# it only reads artifacts produced by the benchmark run and posts a PR comment.
7+
workflow_run:
8+
workflows:
9+
- PR Benchmarks
10+
types:
11+
- completed
12+
13+
permissions: {}
14+
15+
jobs:
16+
comment:
17+
if: >
18+
github.event.workflow_run.event == 'pull_request' &&
19+
github.event.workflow_run.conclusion != 'cancelled'
20+
runs-on: ubuntu-24.04
21+
permissions:
22+
actions: read
23+
contents: read
24+
pull-requests: write
25+
steps:
26+
- name: Comment on PR with benchmark results
27+
env:
28+
GH_TOKEN: ${{ github.token }}
29+
REPO: ${{ github.repository }}
30+
RUN_ID: ${{ github.event.workflow_run.id }}
31+
RUN_URL: ${{ github.event.workflow_run.html_url }}
32+
CONCLUSION: ${{ github.event.workflow_run.conclusion }}
33+
run: |
34+
PR_NUMBER=$(gh api "repos/${REPO}/actions/runs/${RUN_ID}" --jq '.pull_requests[0].number')
35+
HEAD_SHA=$(gh api "repos/${REPO}/actions/runs/${RUN_ID}" --jq '.head_sha')
36+
37+
COMMENT_ARTIFACT_ID=$(gh api "repos/${REPO}/actions/runs/${RUN_ID}/artifacts" \
38+
--jq '.artifacts[] | select(.name == "pr-benchmark-comment-pr-'"${PR_NUMBER}"'-'"${HEAD_SHA}"'") | .id' \
39+
| head -1)
40+
41+
RESULTS_ARTIFACT_NAME="pr-benchmark-results-pr-${PR_NUMBER}-${HEAD_SHA}"
42+
MARKER="<!-- pr-benchmark-report -->"
43+
44+
if [[ -n "${COMMENT_ARTIFACT_ID}" ]]; then
45+
gh api \
46+
-H "Accept: application/octet-stream" \
47+
"repos/${REPO}/actions/artifacts/${COMMENT_ARTIFACT_ID}/zip" > /tmp/pr-benchmark-comment.zip
48+
unzip -p /tmp/pr-benchmark-comment.zip pr-benchmark-comment.md > /tmp/pr-benchmark-comment.md
49+
SUMMARY_BODY=$(cat /tmp/pr-benchmark-comment.md)
50+
else
51+
SUMMARY_BODY="_Benchmark summary artifact was not found; see the workflow run for details._"
52+
fi
53+
54+
if [[ "${CONCLUSION}" == "success" ]]; then
55+
STATUS_LINE="Benchmark run succeeded for \`${HEAD_SHA}\`."
56+
else
57+
STATUS_LINE="Benchmark run finished with conclusion \`${CONCLUSION}\` for \`${HEAD_SHA}\`."
58+
fi
59+
60+
body=$(cat <<EOF
61+
${MARKER}
62+
## Benchmark results
63+
64+
${STATUS_LINE}
65+
66+
- Workflow run: ${RUN_URL}
67+
- Artifact: \`${RESULTS_ARTIFACT_NAME}\`
68+
69+
${SUMMARY_BODY}
70+
EOF
71+
)
72+
73+
comment_id=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" --paginate \
74+
--jq ".[] | select(.body | startswith(\"${MARKER}\")) | .id" | head -1)
75+
76+
if [[ -n "${comment_id}" ]]; then
77+
gh api --method PATCH "repos/${REPO}/issues/comments/${comment_id}" \
78+
--field body="$body"
79+
else
80+
gh pr comment "${PR_NUMBER}" --repo "${REPO}" --body "$body"
81+
fi
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
name: PR Benchmarks
3+
4+
on:
5+
pull_request:
6+
types:
7+
- labeled
8+
9+
permissions: {}
10+
11+
concurrency:
12+
group: pr-benchmarks-${{ github.event.pull_request.number }}
13+
14+
defaults:
15+
run:
16+
shell: bash
17+
18+
jobs:
19+
benchmark:
20+
if: github.event.label.name == 'benchmark'
21+
runs-on: ubuntu-24.04
22+
permissions:
23+
contents: read # checkout only
24+
steps:
25+
- name: Checkout PR head
26+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
27+
with:
28+
repository: ${{ github.event.pull_request.head.repo.full_name }}
29+
ref: ${{ github.event.pull_request.head.sha }}
30+
persist-credentials: false
31+
fetch-depth: 0
32+
33+
- name: Setup mise
34+
uses: jdx/mise-action@e6a8b3978addb5a52f2b4cd9d91eafa7f0ab959d # v4.2.0
35+
with:
36+
version: v2026.6.14
37+
sha256: 96ae1ef7b00a6ebbbec23ba1016d6e722f5e904966272f621d15326429e90d53
38+
39+
- name: Cache local Maven repository
40+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
41+
with:
42+
path: ~/.m2/repository
43+
key: ${{ runner.os }}-pr-bench-maven-${{ github.event.pull_request.head.sha }}
44+
restore-keys: |
45+
${{ runner.os }}-pr-bench-maven-
46+
${{ runner.os }}-maven-
47+
48+
- name: Run JMH benchmarks
49+
run: mise run benchmark:ci-json
50+
51+
- name: Generate benchmark summary
52+
run: |
53+
mise run benchmark:generate-summary \
54+
--input benchmark-results.json \
55+
--output-dir benchmark-results \
56+
--commit-sha "${{ github.event.pull_request.head.sha }}"
57+
env:
58+
GITHUB_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }}
59+
60+
- name: Prepare PR comment summary
61+
run: |
62+
cp benchmark-results/README.md pr-benchmark-comment.md
63+
64+
- name: Upload PR benchmark results
65+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
66+
with:
67+
name: pr-benchmark-results-pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}
68+
path: benchmark-results
69+
retention-days: 5
70+
71+
- name: Upload PR benchmark comment
72+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
73+
with:
74+
name: pr-benchmark-comment-pr-${{ github.event.pull_request.number }}-${{ github.event.pull_request.head.sha }}
75+
path: pr-benchmark-comment.md
76+
retention-days: 5

0 commit comments

Comments
 (0)