mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #77] [MERGED] feat(groom): own the max_prs dispatch override in the reusable + add the groom caller fleet (BE-4346) #86
Labels
No labels
cursor-review-catalog-drift
groom
groom
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/github-workflows#86
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/github-workflows/pull/77
Author: @mattmillerai
Created: 7/26/2026
Status: ✅ Merged
Merged: 7/26/2026
Merged by: @mattmillerai
Base:
main← Head:matt/groom-max-prs-reusable📝 Commits (4)
62fa54cfeat(groom): own the max_prs dispatch override in the reusable + add the groom caller fleet (BE-4346)ac575f8fix(bump-callers): SHA-pin checkout, scope the bot token, anchor the pin-comment rewrite (BE-4346)46abc9ffix(bump-callers): anchor the pin-comment rewrite to workflows_ref too (BE-4346)84f5a32Merge origin/main into matt/groom-max-prs-reusable (BE-4346)📊 Changes
8 files changed (+364 additions, -26 deletions)
View changed files
📝
.github/bump-callers/README.md(+11 -0)📝
.github/bump-callers/bump-callers.sh(+43 -8)📝
.github/bump-callers/tests/test_bump_callers.sh(+77 -1)➕
.github/workflows/bump-groom-callers.yml(+145 -0)📝
.github/workflows/groom.yml(+76 -8)📝
.github/workflows/test-bump-callers.yml(+7 -6)📝
AGENTS.md(+4 -2)📝
README.md(+1 -1)📄 Description
Comfy-Org/cloud#5572 added a
max_prsworkflow_dispatchinput to ONE groom caller. It cost ~40 lines of expression gymnastics to do it:Every line of that exists because the reusable declared
max_prsastype: number. Aworkflow_dispatchinput is always a string; GitHub rejects a string expression assigned to atype: numberreusable input at startup; so the caller has to cast withfromJSON()— andfromJSON()on a non-numeric string throws during expression evaluation, killing the run before any job starts. Hence the mirroredcontains()allowlist guarding the cast.Any second caller wanting the same knob would have carried its own copy of that expression and its own allowlist to keep in sync. That is precisely the drift this repo exists to prevent — the logic belongs here, once. So this moves it.
What changed
max_prsis nowtype: string, and the reusable does the parse. The caller collapses to:No
fromJSON(), no allowlist mirror, no startup-throw class of failure.Verified the type asymmetry is real rather than assumed, with
actionlinton a scratch pair of workflows:type: numberinputstring value cannot be assigned(this is #5572's whole problem)max_prs: 1→type: stringinputThat second row is what makes this non-breaking: every existing caller passing a bare number keeps working untouched.
Parsing lives in
build_select, and no case can abort a run:''/ whitespace — what a SCHEDULE yields, carrying no inputs5,5.0,1e3,2)>= 0abc,inf,nan)That last row is the one judgement call worth a reviewer's eye. Falling back to the default would be actively wrong — a caller piloting at
max_prs: 1would silently get 5. Exiting non-zero would throw away a finder+verifier run already paid for, when every finding still files as an issue on the 0-PR path. So: fail closed, stay alive, warn loudly.No upper bound is enforced, deliberately. #5572's
contains()allowlist read as a guard, but a caller'soptions:list is a UI convention and a typo guard, not a security boundary — the only principals who can post past it (an API/CLI dispatch) already have repo write access and could just editoptions:. The real backstops are structural and unchanged: builder PRs are review-gated and never auto-merged, the finder emits ~6-12 findings a run, andpr_size_limitbails oversized patches to issues. The typo case, which was the genuine risk, is now handled above.The groom caller fleet, which didn't exist
groom is the fleet that most needs a bumper: a groom caller pins the reusable twice — the
uses:SHA and theworkflows_ref:input that loads the finder/verifier/builder briefs plus the dedup ledger. Those must move in lock-step or a run executes one version's workflow against another version's briefs.bump-callers.shalready rewrote both pins (confirmed by dry-running itssedagainst both live callers). It now also re-points the# main @ <short>pin comment those callers carry — the bumper previously left it naming the old commit while the pin moved, which is worse than no comment in the one file where the pin is the whole point. Anchored to thegithub-workflowsline and bounded to{7,12}hex, so an unrelated# main @ …note and a deliberate full-SHA comment are both left alone..github/workflows/bump-groom-callers.yml— thin entrypoint over the shared script.GROOM_CALLERS,ALLOW_EMPTY=true(the fleet grows as callers land), noWIRE_BOT_SCRIPT(bot-identity injection is cursor-review-only; a groom caller must setbot_app_iditself).test_bump_callers.sh— a groom case covering both pins moving together, the comment rewrite, an untouchedactions/checkoutpin, and an intactmax_prsforward expression.Verification
actionlint— clean across all workflows.shellcheck -x— clean on the script + tests.agents-md-integritypasses (129 lines, under the 150 aim).'',' ','5.0','-2','0','abc','1e3','inf','-inf','nan','01',' 2 ','1.9'.seddry-run against the two real callers: both 40-hex pins rewrite,actions/checkoutuntouched.Follow-ups (not in this PR)
GROOM_CALLERSwith the two existing callers (a variable edit, no commit).ELI5
The groomer opens at most a few cleanup PRs per weekly run. Somebody wanted a dropdown on the manual "Run workflow" button to ask for more just that once — and doing it in one repo took forty lines of fiddly YAML, because the shared workflow insisted the number be a number and dispatch buttons can only hand over text.
This teaches the shared workflow to accept the text and sort it out itself. The dropdown is now three words in a caller instead of forty lines, every repo gets it the same way, and a typo gets you zero PRs and a warning instead of a crashed run.
It also adds the robot that keeps groom callers' pinned versions up to date — groom callers pin the version in two places, and nobody had wired that up yet.
🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.