Skip to content

ci(benchmarks): surface the gate table as a sticky PR comment#148

Merged
lesnik512 merged 7 commits into
mainfrom
docs/benchmark-pr-comment-spec
Jul 17, 2026
Merged

ci(benchmarks): surface the gate table as a sticky PR comment#148
lesnik512 merged 7 commits into
mainfrom
docs/benchmark-pr-comment-spec

Conversation

@lesnik512

Copy link
Copy Markdown
Member

What

Surface the benchmark gate's sweep table as a sticky PR comment (and on the run Summary page), without changing the gate itself. Today just bench-check computes the table on every PR but it only lives in the CI log.

Design + rationale: planning/changes/2026-07-17.03-benchmark-pr-comment.md.

How

  • benchmarks check --markdown — new output mode; renders the existing sweep + a / verdict as GitHub Markdown on stdout. Same exit code as before (0 pass / 1 fail), so the gate is untouched. Python owns the whole comment body (unit-tested).
  • .github/workflows/benchmarks.yml — new, permission-scoped (pull-requests: write only here). Runs just bench-report, tees the Markdown to $GITHUB_STEP_SUMMARY and a $RUNNER_TEMP scratch file, and posts it with gh pr comment --edit-last --create-if-none. The bench job moves out of the reusable _checks.yml so the write token isn't widened across lint/docs/pytest.
  • just bench-reportdocker compose run -T ... check --markdown (-T keeps stdout clean for capture).

modern-di's benchmark-action mechanism was deliberately not copied: it gates on wall-clock timing, which this repo's design rejects as flaky. Only the PR comment is ported; the deterministic counter gate stays as-is.

Notes

  • The counter gate, baseline.json, EXACT_KEYS/TOLERANT_KEYS, and the --cov-fail-under=100 gate are all unchanged.
  • Fork PRs (read-only token) can't comment; the step continue-on-errors and the Summary page still shows the table. With 0 forks today this is theoretical.
  • Trade-off accepted: bench no longer runs on the Monday scheduled dependency-drift check (cost of the scoped token) — see the spec's Non-goals.

Testing

  • 15/15 tests/test_benchmarks.py pass; ruff + ty clean.
  • just bench-report exercised in Docker: clean Markdown, exit 0 against the committed baseline.
  • The live PR comment posts on this very PR — first end-to-end validation of the comment step.

🤖 Generated with Claude Code

lesnik512 and others added 5 commits July 17, 2026 18:00
Design for posting the existing bench-check sweep table as a sticky PR
comment (and run Summary) via a new `benchmarks check --markdown` mode and
a permission-scoped benchmarks.yml. Gate and baseline unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`benchmarks check --markdown` renders the sweep table plus a pass/fail
verdict as a GitHub Markdown document on stdout, so CI can post it as a PR
comment. Gate logic and exit codes unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move the bench job into its own permission-scoped benchmarks.yml, run it via
`just bench-report`, tee the markdown to the run Summary, and post it with
`gh pr comment --edit-last --create-if-none`. Scopes `pull-requests: write` to
the one job instead of widening the reusable _checks.yml token.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GITHUB_STEP_SUMMARY is unique per step, so the comment step read its own
empty summary and gh pr comment silently failed on a blank body. Tee the
report to a RUNNER_TEMP scratch file that survives across steps and post
that. Add a concurrency group so rapid PR pushes don't race the sticky
comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GITHUB_STEP_SUMMARY is per-step, so the comment must read a RUNNER_TEMP
scratch file the capture step also tees to, not the summary path. Record
accepting the lost weekly scheduled counter gate as the cost of the scoped
write token.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

Benchmark gate

✅ gate passed

scenario msg/s delete/msg WALrec/msg WALB/msg fpi upd del dead_tup
consumer/w1/b10 967 1.000 6.79 921 242 5000 5000 10000
consumer/w1/b100 969 1.000 6.82 922 243 5000 5000 10000
consumer/w2/b10 1087 1.000 6.79 961 242 5000 5000 10000
consumer/w2/b100 1323 1.000 6.73 959 243 5000 5000 10000
consumer/w4/b10 1000 1.000 6.77 960 242 5000 5000 10000
consumer/w4/b100 1479 1.000 6.87 1038 244 5000 5000 10000
consumer/w1/b100/tfbs100 5265 0.010 6.07 1116 243 5000 5000 10000
producer/w1/b100 2113 0.000 3.04 584 0 0 0 0

Gated (fails the build): delete_calls + tuple counters (upd/del/ins) + the producer's insert_calls/select_calls, exact; wal_records within a 10% band. msg/s, WAL bytes and total calls are informational (timing/FPI noise).

lesnik512 and others added 2 commits July 17, 2026 18:54
`docker compose run` leaks buildkit image-build output onto stdout in CI, so
the first sticky comment was ~120 lines of build noise before the table. The
report always starts with the `## Benchmark gate` heading and the container
prints it last, so capture from that sentinel to EOF. Manage the exit code by
hand (set +e, re-exit with the gate status) so a failing gate still posts its
report yet still fails the build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The first live PR comment was buried under buildkit build output because
`docker compose run` leaks it to stdout in CI. Document slicing the report
from its `## Benchmark gate` sentinel and owning the exit code by hand, and
correct the earlier claim that -T alone yields clean stdout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lesnik512
lesnik512 merged commit e2feeb8 into main Jul 17, 2026
7 checks passed
@lesnik512
lesnik512 deleted the docs/benchmark-pr-comment-spec branch July 17, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant