mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #179] [MERGED] feat(coderabbit-config): validate .coderabbit.yaml so a broken config fails its own PR (BE-7757) #186
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#186
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/179
Author: @mattmillerai
Created: 8/18/2026
Status: ✅ Merged
Merged: 8/18/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-7757-coderabbit-config-validate📝 Commits (2)
3f86ceefeat(coderabbit-config): validate .coderabbit.yaml so a broken config fails its own PR (BE-7757)959c374fix(coderabbit-config): close the review panel's findings on the validator (BE-7757)📊 Changes
17 files changed (+4966 additions, -4 deletions)
View changed files
📝
.github/bump-callers/README.md(+1 -0)➕
.github/coderabbit-config/README.md(+125 -0)➕
.github/coderabbit-config/check_coderabbit_config.py(+642 -0)➕
.github/coderabbit-config/requirements.txt(+53 -0)➕
.github/coderabbit-config/schema.v2.json(+2249 -0)➕
.github/coderabbit-config/schema_drift.py(+274 -0)➕
.github/coderabbit-config/tests/test_check_coderabbit_config.py(+398 -0)➕
.github/coderabbit-config/tests/test_schema_drift.py(+217 -0)📝
.github/dependabot.yml(+26 -0)➕
.github/workflows/bump-coderabbit-config-callers.yml(+161 -0)➕
.github/workflows/coderabbit-config-validate.yml(+202 -0)➕
.github/workflows/refresh-coderabbit-schema.yml(+279 -0)➕
.github/workflows/test-coderabbit-config-validate.yml(+190 -0)📝
AGENTS.md(+32 -4)📝
README.md(+1 -0)📝
docs/callers/README.md(+2 -0)➕
docs/callers/coderabbit-config-validate.md(+114 -0)📄 Description
ELI-5
CodeRabbit reads a
.coderabbit.yamlin your repo to know how to review your PRs. If that file breaks the rules of its own format, CodeRabbit throws away the whole file and reviews with generic defaults instead — every instruction you wrote silently stops mattering, and nothing looks different. Worse, it checks the file on the base branch, so the PR that broke it goes green and the damage shows up on the next person's PR, blamed on them.This adds a shared CI check that validates the file on the PR that changes it, so the breakage lands on the right diff, with an annotation on the right line.
What's here
.github/workflows/coderabbit-config-validate.ymlworkflow_callcheck.workflows_refREQUIRED, no default; checker loaded from this repo at the pinned ref, never from the caller's checkout..github/coderabbit-config/check_coderabbit_config.py, the vendoredschema.v2.json,schema_drift.py, hash-pinnedrequirements.txt, tests, README..github/workflows/test-coderabbit-config-validate.yml.github/workflows/bump-coderabbit-config-callers.ymlpreflight.sh+bump-callers.sh. Roster is a secret (CODERABBIT_CONFIG_CALLERS), seeded empty..github/workflows/refresh-coderabbit-schema.ymldocs/callers/coderabbit-config-validate.md, README catalog row, AGENTS.md, dependabotpipentry.Severity is split to mirror what CodeRabbit itself does, not what a schema library calls invalid: a YAML parse error, a
maxLengthviolation or a type/enum error fails (those are what it rejects the whole file for); an unknown/additional property warns (it strips those, so the config loads while everything under the key does nothing) unlessstrict_unknown_keys: true. A repo with no config passes, and says so — "no config here" must never read the same as "config validated clean" in a log.Verification
Repo suites — all green locally: the new
coderabbit-configsuite (35 tests), the 6 CLI smoke steps extracted from the test workflow and executed verbatim,check_workflow_pins.py(8 reusables, noworkflows_refdefault, every ref checkout guarded) + its 78 tests,test_paths_contract.sh(58 checks — the guard that this fleet'spaths:filter exactly matches theWATCHED/WATCHED_ASSETSit handspreflight.sh),test_bump_callers.sh,shellcheck, and the agents-md / cursor-review / groom / refresh-reviewers / workflow-pins suites.Against the artifacts the ticket names. I swept 18 org repos read-only for a
.coderabbit.yaml; 11 carry one. Running this checker over all 11 reproduces the ticket's Evidence table exactly:strict_unknown_keys: trueEach of the three is reported with the offending root key named, the correct source line, and a
Did you mean \reviews.tools`?hint. ZeromaxLength` violations org-wide — which is the second half of the ticket's point, and why a file-size check would have gated nothing. Repo names are redacted here: most are private and this repo is public.The half I am not fixing: the 3 invalid configs stay invalid — they are out of scope by the ticket's own design (one child ticket per repo, so each lands as its own PR in its own repo). And the check is currently wired to 0 of 11 repos: this PR ships the machinery, the fleet makes the rollout a follow-up.
The install path is exercised for real:
pip install --require-hashes --only-binary=:all:resolved cleanly for linux/cp312 in a dry run, including thetyping-extensionstransitive that a 3.13+ resolver silently drops. The same install runs in the test workflow, so a wrong hash set fails on the PR that broke it rather than in every consumer's CI.Judgment calls
The vendored schema, and the one dependency. This repo is stdlib-only on purpose, and this directory breaks that. Neither half has a stdlib answer: there is no YAML parser in the standard library, and the point of the check is to reproduce the verdict CodeRabbit's own Draft 2020-12 validator reaches — a hand-written subset validator would agree with the real one until it didn't, and the day it diverged the check would either gate nothing or fail a valid config. So the dependency is accepted and pinned hard: exact versions + sha256,
--require-hashes, and a Dependabotpipentry so the pins don't rot the way an unwatched inlinepip install x==1.2.3does. AGENTS.md now records the exception rather than still claiming stdlib-only.Not extending
agents-md-integrity.yml— a sibling workflow, per the ticket. Folding this in would push a Python dependency and a new failure mode onto every one of its callers, for a check about a different class of file.Failure modes fail loudly, in the right direction. Exit 2 (could-not-run) is distinct from exit 1 (config invalid), because "I could not check" must never look like "it's fine". Both the checker and the drift detector refuse a file that isn't a JSON Schema object rather than reporting "no drift" / "all valid" — a check that cannot fail is worse than no check. That is the concrete redirect-stub case the ticket names, and it's covered by a smoke test.
Path containment + injection.
config_fileis guarded against an absolute or../-escaping path and against an empty value (which would otherwise join to the repo root and report a clean pass over a repo nobody looked at). Every annotation is workflow-command-escaped — the strings come from a PR-author-controlled file, and YAML permits a newline in a quoted key.Unmet criteria and unexercised artifacts
comfy-conventionscaller is NOT in this PR. That acceptance criterion needs a commit in a different repository; I am scoped to one repo and one PR. It is a two-line caller plus a roster entry —docs/callers/coderabbit-config-validate.mdis the copy-pasteable version. The fleet entrypoint also needs oneworkflow_dispatchrun frommainafter merge (landing a fleet touches no path its own filter watches, so it fires no run of its own).tools:block are reviewed normally rather than defaulted — but I did not observe CodeRabbit's loader directly. If it turns out to be file-rejecting,strict_unknown_keysis the switch, and the default should flip.Refs BE-7757 — the ticket stays open: the caller wiring criterion is unmet above, and the three invalid configs it reports are still invalid, tracked on its children.
🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.