Skip to content

ci: generalize bump-cursor-review-callers into a multi-workflow bump-callers dispatcher#35

Open
mattmillerai wants to merge 1 commit into
mainfrom
matt/be-3482-generalize-bump-callers
Open

ci: generalize bump-cursor-review-callers into a multi-workflow bump-callers dispatcher#35
mattmillerai wants to merge 1 commit into
mainfrom
matt/be-3482-generalize-bump-callers

Conversation

@mattmillerai

Copy link
Copy Markdown
Contributor

ELI-5

Today the repo has one robot that watches cursor-review.yml and, when it changes, opens "update your pin" PRs in every repo that uses it. A second reusable workflow (pr-size) is arriving, and copy-pasting a whole sibling robot per workflow means duplicated lists that rot. This PR turns the one-workflow robot into a single dispatcher that serves any registered reusable workflow, each with its own caller list — same bot identity, same "one bad repo doesn't stop the others" behavior, same PRs for cursor-review as before, byte-for-byte.

What changed

  • bump-callers.yml replaces bump-cursor-review-callers.yml (removed in this PR; no other references existed).
  • A static REGISTRY maps each registered workflow file to its own caller-list Actions variable: cursor-review.yml → CURSOR_REVIEW_CALLERS (existing variable, untouched — zero config migration) and pr-size.yml → PR_SIZE_CALLERS (registered now; seeded by the pr-size caller rollout). Registering a new workflow = 3 spots in this one file + seed the variable (documented in the header).
  • Push events resolve which registered workflows actually changed via the compare API (before...sha, paginated). If that can't be determined (force-push, all-zero before), it falls back to sweeping every registered workflow — already-pinned callers no-op, so over-bumping is harmless churn while under-bumping would silently strand callers.
  • Per-workflow fan-outs are independent: distinct bump branch per workflow (ci/bump-<name>-<short>; unchanged ci/bump-cursor-review-<short> for cursor-review), and one workflow's bad/missing caller variable cannot abort another's fan-out. The per-repo fault isolation inside a fan-out is the existing bump_one() code, unchanged except the name/file parameterization.
  • Loud-failure semantics kept, with one refinement: a missing/empty caller variable is a hard error when the workflow was explicitly targeted (its file changed in the push, or it was named in the dispatch input) — a wiped variable can never turn the dispatcher into a silent no-op. When sweeping all registered workflows, a registered-but-not-yet-seeded workflow is a warning-skip. An explicit [] is always a benign "intentionally zero callers" skip.
  • workflow_dispatch gains two inputs: workflows (filter which registered workflows to bump; empty = all, deduped, bare names and full paths accepted) and dry_run (read-only — logs what would be bumped, opens no branches/PRs).
  • Added permissions: contents: read (fixes the zizmor excessive-permissions finding the old file carried).
  • Masking is unchanged: every caller repo name is ::add-mask::ed immediately after parsing, before any loop that echoes it.

Verification

  • yaml.safe_load — valid; shellcheck -S warning -s bash on the extracted script — clean.
  • zizmor on the new file: no new findings; the old file's excessive-permissions (medium) is fixed. The two remaining github-app findings are pre-existing on main and inherent to the design: repositories:/permission-* scoping can't be added without either naming private repos in this public file or risking token-permission breakage (see judgment calls).
  • 16-case local end-to-end matrix with a mocked gh, run under bash -e exactly like the Actions default shell: push with one/both workflows changed; push with empty variable (hard error); push with compare failure (sweep fallback + warn-skip); dispatch explicit/all/bare-name/unknown/duplicate/glob input; dry run (verified zero write calls); invalid JSON in one variable with the other workflow's fan-out still completing; per-repo metadata failure with remaining repos still bumped and the job reddened at the end; already-pinned skip; missing-file skip; explicit [] skip.
  • Cursor-review output byte-compat verified in the mock logs: branch ci/bump-cursor-review-<short>, commit message and PR title ci: bump cursor-review to github-workflows@<short>, and PR body identical to today's — the only text delta is the footer naming the bump-callers workflow (the file rename).
  • The real seeded CURSOR_REVIEW_CALLERS variable (12 entries) passes the new validation and parses to the same 12 repo|file|label tuples the unchanged bump_one() consumes.

Judgment calls / notes for the reviewer

  • A live dispatched fan-out is a post-merge step, deliberately (same conclusion as ci(bump-callers): move caller list to CURSOR_REVIEW_CALLERS variable + mask repo names #27): GitHub does not register a brand-new workflow file until it exists on the default branch, so workflow_dispatch (even by ID) 404s pre-merge — I tried. Recommended immediately after merge: gh workflow run bump-callers.yml -f dry_run=true — safe (read-only), and its log shows the full resolution + per-caller "would bump" sweep with masked names.
  • pr-size.ymlPR_SIZE_CALLERS is registered ahead of the workflow's arrival. The paths entry on a not-yet-existing file is inert, and the sweep treats the unseeded variable as a warning-skip. If the pr-size workflow lands under a different filename, the fix is the three registered spots in this one file.
  • The dry_run and workflows dispatch inputs are additions, motivated by safe verification (a plain dispatch fans out real PRs) and by making the generalized dispatcher operable per-workflow. A plain workflow_dispatch with no inputs behaves like today's: it sweeps and bumps for real.
  • Left the app-token step exactly as-is (no permission-*/repositories: scoping to silence zizmor's pre-existing findings): scoping repositories: would require naming private repos in a public file, and requesting explicit permission-* values fails token minting outright if the app lacks any named permission (e.g. issues-write for label application) — a total-breakage risk against a cosmetic lint gain on a finding main already carries.

…callers dispatcher

One dispatcher now serves every registered reusable workflow, each with its
own caller-list Actions variable (cursor-review.yml keeps CURSOR_REVIEW_CALLERS
unchanged; pr-size.yml registers against PR_SIZE_CALLERS for when it lands).
Push events resolve which registered workflows actually changed via the compare
API (falling back to a sweep of all registered workflows), and workflow_dispatch
gains a workflows filter plus a read-only dry_run mode. Per-repo failures stay
fault-isolated per workflow, and one workflow's bad caller variable cannot abort
another's fan-out. Replaces bump-cursor-review-callers.yml.
@mattmillerai mattmillerai added cursor-review Multi-model cursor review agent-coded Authored by the agent-work loop labels Jul 18, 2026
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c7830057-34bf-4b61-b581-db1d7bfc1160

📥 Commits

Reviewing files that changed from the base of the PR and between 8b0ca00 and f8e1287.

📒 Files selected for processing (2)
  • .github/workflows/bump-callers.yml
  • .github/workflows/bump-cursor-review-callers.yml
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch matt/be-3482-generalize-bump-callers
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch matt/be-3482-generalize-bump-callers

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-coded Authored by the agent-work loop cursor-review Multi-model cursor review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant