Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/compare/tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ for the current state. GitHub's own rulesets are on
| [commitcheck](https://github.com/marketplace/commitcheck) | A hosted App that applies one regular expression, set in its web admin | Commit message, pull request title or description, by regex | GitHub App | Free for public repositories; $25 a month for private ones |
| [DCO app](https://github.com/apps/dco) and [DCO-2](https://github.com/cncf/dco2) | The sign-off check the Linux kernel and the CNCF use, with a remediation flow for missing sign-offs | `Signed-off-by` trailers | GitHub App | Free, open source |
| [PRLint](https://github.com/ewolfe/prlint), [PR Title Checker](https://github.com/marketplace/actions/pr-title-checker) | Regular expressions over pull request fields | Title, body, labels, branch | App / Action | Free, open source |
| **Commit Check** | One rule engine with [24 documented rules](../rules.md), run as a hook, a CLI, an Action, a hosted App or an MCP tool | Commit message, branch name, author name and email, sign-off, AI attribution, force pushes, file size and paths, tag names; the squash message of a pull request | All of the above | Free, open source; the App's private organization repositories move to a paid plan later |
| **Commit Check** | One rule engine with [22 documented rules](../rules.md), run as a hook, a CLI, an Action, a hosted App or an MCP tool | Commit message, branch name, author name and email, sign-off, AI attribution, force pushes, file size and paths, tag names; the squash message of a pull request | All of the above | Free, open source; the App's private organization repositories move to a paid plan later |

## What is different about Commit Check

Expand Down
22 changes: 22 additions & 0 deletions tests/docs_sync_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,28 @@ def test_every_rule_explains_itself(self):
f"{entry.rule_id} ({entry.check}) section is missing {required}"
)

def test_prose_rule_counts_match_the_catalog(self):
"""A page that counts the rules out loud must count them correctly.

The comparison table sells the engine on how much it covers, so a
stale number there is worse than no number: it is the one figure a
reader checks against the rules page. Every other test here proves a
rule is *documented*; none of them read a sentence that says how
many there are.
"""
expected = len(ALL_RULES)
for path in sorted(DOCS.rglob("*.md")):
if path.parent.name == "posts":
continue # blog posts are dated records; see AGENTS.md
for claimed in _PROSE_RULE_COUNT.findall(path.read_text(encoding="utf-8")):
assert int(claimed) == expected, (
f"{path.relative_to(DOCS.parent)} claims {claimed} rules, "
f"but the package defines {expected}"
)


#: A prose claim about how many rules exist, e.g. ``24 documented rules``.
_PROSE_RULE_COUNT = re.compile(r"(\d+) documented rules")

#: A pre-commit revision pin, e.g. ``rev: v2.13.1``.
_REV_PIN = re.compile(r"^\s*rev:\s*v(\d+\.\d+\.\d+)\s*$", re.M)
Expand Down