feat(ci): add benchci for better visualization (#149)

This adds a small in-repo tool and updates the ci.yml file in order
to make benchmark and most importantly allocation results visible in a
PR. It also drops the 3rdparty action we had commented out.

Signed-off-by: Marvin Drees <marvin.drees@9elements.com>
This commit is contained in:
Marvin Drees
2026-07-03 01:21:49 +02:00
committed by GitHub
parent e5f8ac0687
commit 104a2b0b26
3 changed files with 311 additions and 14 deletions
+78
View File
@@ -0,0 +1,78 @@
name: Benchmark Comment
# Rationale: This more privileged workflow runs in the base repo's
# context (with a write token) only after the 'untrusted' CI workflow finishes.
# It does NOT check out or execute PR code; it only consumes the benchmark
# report artifact as inert, validated data.
on:
workflow_run:
workflows: [CI]
types: [completed]
permissions:
contents: read
jobs:
comment:
# Only for PR-triggered CI runs that succeeded to suppress noise
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write # needed to comment
steps:
- name: Download generated benchmark report
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.1
with:
name: bench-report
path: bench-report
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Validate report and upsert PR comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
set -euo pipefail
report="bench-report/bench-report.md"
marker='<!-- lneto-bench -->'
# Treat the artifact as untrusted input: it was produced by a job that
# ran PR code. Basic validation before posting. TODO: Make more robust.
test -f "$report"
size="$(wc -c < "$report")"
if [ "$size" -le 0 ] || [ "$size" -gt 1000000 ]; then
echo "::error::benchmark report has unexpected size: ${size} bytes"
exit 1
fi
if ! grep -qF "$marker" "$report"; then
echo "::error::benchmark report missing marker ${marker}"
exit 1
fi
# Resolve the PR from the run's head SHA rather than trusting any
# value carried in the artifact, so we can only comment on the PR that
# actually produced this run.
pr="$(gh api "repos/${REPO}/commits/${HEAD_SHA}/pulls" \
--jq 'map(select(.state == "open")) | .[0].number // empty')"
if [ -z "$pr" ]; then
echo "No open PR found for ${HEAD_SHA}; nothing to comment."
exit 0
fi
comment_id="$(
gh api "repos/${REPO}/issues/${pr}/comments" --paginate \
--jq ".[] | select(.body | contains(\"${marker}\")) | .id" | head -n1
)"
if [ -n "$comment_id" ]; then
gh api --method PATCH "repos/${REPO}/issues/comments/${comment_id}" \
-f body=@"$report"
else
gh api --method POST "repos/${REPO}/issues/${pr}/comments" \
-f body=@"$report"
fi
+14 -14
View File
@@ -104,7 +104,7 @@ jobs:
needs: [test]
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -115,20 +115,20 @@ jobs:
- name: Run benchmarks
run: go test -bench=. -benchmem -count=5 -shuffle=on -run='^$' -timeout=15m ./... | tee bench-results.txt
# Fails for a weird reason, will be investigated in the future
# - name: Report benchmark regressions
# uses: benchmark-action/github-action-benchmark@a887eba2af2000fda74e733fcf952aa823b65916 # v1.21.0
# with:
# tool: go
# output-file-path: bench-results.txt
# summary-always: true
# comment-on-alert: true
# alert-threshold: "120%"
# fail-on-alert: false
# auto-push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
# github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Generate benchmark report
run: |
go run ./internal/benchci -current bench-results.txt -out bench-report.md
cat bench-report.md >> "$GITHUB_STEP_SUMMARY"
- name: Upload benchmark results
- name: Upload generated benchmark report
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: bench-report
path: bench-report.md
retention-days: 30
- name: Upload raw benchmark results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: