mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #292] [MERGED] feat(workflow-pins): fail CI when a docs/callers workflows_ref row contradicts the declaration #291
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#291
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/292
Author: @mattmillerai
Created: 9/16/2026
Status: ✅ Merged
Merged: 9/16/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-6508-docs-callers-workflows-ref-cross-check📝 Commits (2)
6f4dc40feat(workflow-pins): cross-check docs/callers workflows_ref rows against the declaration56504abfix(workflow-pins): harden the docs/callers workflows_ref cross-check📊 Changes
5 files changed (+432 additions, -1 deletions)
View changed files
📝
.github/workflow-pins/README.md(+12 -0)📝
.github/workflow-pins/check_workflow_pins.py(+155 -1)📝
.github/workflow-pins/tests/test_check_workflow_pins.py(+258 -0)📝
.github/workflows/test-workflow-pins.yml(+6 -0)📝
docs/callers/pr-derisk.md(+1 -0)📄 Description
ELI-5
The workflow-pins lint already keeps every reusable workflow's
workflows_refinput from carrying adefault:(a default would let a caller pinuses:to a fixed commit yet still load this repo's scripts from a moving branch — BE-5546). But the human-readable setup guides indocs/callers/have their own little "inputs" table, and nothing stopped a table there from sayingworkflows_refdefaults tomaineven though the workflow forbids it. A caller who copies that wrong row reopens the exact hole the lint closes. This PR teaches the lint to read those docs tables too and fail CI when a page contradicts the declaration.What this does
Adds a third check to
check_workflow_pins.py. For every reusable workflow that declares aworkflows_refworkflow_callinput asrequired: truewith nodefault:(the same state the existing no-default lint parses), it finds the matchingdocs/callers/<name>.mdpage and, if that page exists, locates its inputs-table row forworkflows_ref:main, a SHA, a<placeholder>, anything other than a required/no-default marker like—orrequired), the run fails, naming the docs file, the row's line number, and the workflow declaration it contradicts.workflows_refrow at all, that is a hard error too — absence of the row must not read the same as "not applicable", matching the discipline the checker already uses for a workflow that consumes the input but whose declaration it cannot locate.Only the required-no-default direction is asserted, so an optional / auto-derived input —
groom.yml'sdefault: ''self-pin — is deliberately left alone and its docs may keep documenting a default. The parser is text-level like the rest of the file (no PyYAML), skips fenced```yamlcaller examples and prose so neither is mistaken for the table row, and is wired intocheck_dirsotest-workflow-pins.ymlpicks it up with no workflow-file change.Acceptance
Reverting a compliant docs row to
| workflows_ref | main | … |on this branch makes the pins lint fail with, e.g.:::error file=docs/callers/pr-risk.md,line=120::the workflows_ref inputs-table row documents a default of main, but pr-risk.yml declares workflows_ref as required: true with no default. … See BE-6508.Restoring the row returns the run to green.
Corpus swept
Of the 11 workflows the lint tracks, 10 are required-no-default (
groom.ymlis the optionaldefault: ''self-pin and is excluded). Of those 10: 8 already carried a compliant— (**required**)/*(required)*row and pass unchanged;docs/callers/pr-derisk.mdhad noworkflows_refrow (fixed here); andrefresh-reviewers.ymlhas no page under its own name (see Residual).Tests
DocsDefaultLiteralRefTests(8),FindDocsRowTests(4),DocsCrossCheckTests(6) intests/test_check_workflow_pins.py, matching the file's string-fixture style — including the ticket's four cases: a docs row claimingmain→ hit with the right line number; a— (**required**)row → clean; a present page missing the row → hard error; and aworkflows_refin prose or a fenced```yamlblock → not mistaken for the row.Provenance
python3 -m unittest discover -s .github/workflow-pins/tests -p 'test_*.py'→ 334 passed, 0 failed;python3 .github/workflow-pins/check_workflow_pins.pyagainst.github/workflows→ OK (11 workflows, 0 problems); reverted a docs row tomain→ lint failed naming file+line+workflow, restored → green; the two failing-path CLI smoke steps fromtest-workflow-pins.yml(reintroduced default, unguarded checkout) still reject and do not leak a docs error into their fixture dirs.Residual
refresh-reviewers.ymlis uncovered by the docs cross-check. It declaresworkflows_refrequired-no-default, but its caller guide isdocs/callers/assign-reviewers.md, notrefresh-reviewers.md, so the by-basename mapping (docs/callers/<name>.md) finds no page and skips it. This is consistent with the ticket's "if the page exists" scoping, but it meansassign-reviewers.md— which today documents noworkflows_refrow at all — is never checked and could drift undetected. A follow-up should either add aworkflows_refrow toassign-reviewers.mdand teach the checker therefresh-reviewers→assign-reviewersname mapping, or reconcile the page name.docs/callers/pr-derisk.mdneeded aworkflows_refrow added. It was the one remaining drift the new check flags on the current tree (its "Inputs worth setting" table omittedworkflows_refentirely). I added the row, mirroringpr-risk.md, so this PR's own CI is green. This is arguably the sibling docs-sync ticket's territory rather than this check-only ticket's; it is the minimal docs edit required for the new check to pass onmain. If the docs-sync ticket intendedpr-derisk.mdto stay row-less, the reviewer should decide whether the row or a checker carve-out is preferred.maininstead.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.