Open source · MIT licensed
Catch bad commits before they merge.
Commit Check validates commit messages, branch names, authors and sign-offs against one cchk.toml — in your commit hook, in CI, on every pull request and inside your AI agent. When the fix is obvious, it hands you the line.
pip install commit-check- MIT licensed, no account needed
- Python 3.10 – 3.14 on Linux, macOS and Windows
- Signed build provenance on every release
- CLI and hook work with any Git host
Where it runs
One config file. Five places to enforce it.
Pick the entry point that matches how your team works. Every one reads the same cchk.toml and reports the same rule IDs — start with one, add the rest later.
-
Any forge, any CI
Command line
The engine itself, with JSON output and a Python API for scripts.
pip install commit-checkGetting started → -
Fastest feedback
pre-commit hook
Rejects a bad message on the laptop, before Git records it.
- id: check-messageHook guide → -
Most teams start here
Enforced in CI
GitHub Action
A required check no one can skip, with a PR comment and a job summary.
commit-check-action@v2Action guide → -
Zero YAML
GitHub App
Install once. Every push and pull request gets a check run, no CI minutes.
apps/commit-checkApp guide → -
For AI agents
MCP server
Your coding agent checks its own commit before it writes it.
uvx commit-check-mcpMCP guide →
commit-check-action
Every pull request, checked and explained.
The Action reports where your reviewers already look — a PR comment, the job summary, inline annotations — and exposes a JSON result the next step can gate on.
One report on the pull request, edited in place on every push.Turn it on with pr-comments: true
feat: add login page #128Open
alex force-pushed feature/add-login, rewording 2 commits
The same comment was updated. No new comment, no noise in the thread.
The full breakdown lands in the workflow run: each check, the value, the fix.Turn it on with job-summary: true
commit-check summary
Commit Check
2 of 5 checks failed
▾ Show all 5 checks
Squash merges turn the PR title into the commit, so the title is checked too.Turn it on with pr-title: true
add login page #128Open
feat: add login pageSave
feat: add login page #128Open
Checks
Commit Check / commit-check (pull_request)CC001 message · PR title (add login page)Re-running on the edited title…✔ PR title (feat: add login page)
Squash and merge creates this commit on main:
feat: add login page (#128)
Every commit in the pull request, checked against Conventional Commits.On by default: message: true
feat: add login page #128Open
Commit message
d87faca5584f4637d6defAnnotations 2 errors
CC001 message
Commit 2/3 (5584f46): The commit message should follow Conventional Commits.
value: bad msg
Suggest: Use <type>(<scope>): <description>, where <type> is one of: feat, fix, docs, …
CC001 message
Commit 3/3 (37d6def): The commit message should follow Conventional Commits.
value: Fix: handle empty password
Fix: fix: handle empty password
Branch names checked against Conventional Branch, with the rename to run.On by default: branch: true
feat: add login page #131Open
BranchFeature/Add-Login
CC201 The branch should follow Conventional Branch.
value: Feature/Add-Login
Fix: feature/Add-Login
Conventional Branch types
- feature/
- bugfix/
- hotfix/
- release/
- chore/
main and master always pass. Add your own types in cchk.toml.
Make it a required check
Branch protection does the rest: a violating commit cannot merge, however it was made.
Verified before it installs
The Action checks the wheel's signed build provenance and fails the step if it does not match.
Try it without blocking anyone
dry-run: true reports every finding as a warning and always exits 0.
What it checks
Rules grouped by what they protect.
A few are on by default. Turn on what your project needs, rule by rule, or set any rule to warn instead of fail.
-
Commit messages
CC001–CC012Conventional Commits, subject length, imperative mood, sign-off, and merge, revert, fixup or WIP commits.
Rejected: Fix: add streaming support
Accepted: fix: add streaming support
-
Branch names
CC201–CC202Conventional Branch naming, and whether the branch is rebased onto its target.
Rejected: my-new-thing
Accepted: feature/streaming-support
-
AI attribution
CC013–CC016Spots the trailers Claude Code, Cursor and others add. Forbid them, or require a disclosure instead.
Rejected: Co-authored-by: Claude
Accepted: Assisted-by: Claude
-
Author identity
CC101–CC102Names and emails that match the patterns you set — here
author_email_pattern = "@acme\.dev$"— so a build box cannot write itself into the history.Rejected: ec2-user <root@ip-10-0-0-12>
Accepted: Jane Doe <jane@acme.dev>
-
Pushes and files
CC301–CC304No force-pushes, no oversized files, no forbidden paths — caught at pre-push, before they leave the laptop.
Rejected: git push --force origin main
Rejected: assets/model.bin, 240 MB
-
Across an organization
One shared policy for every repository. Each repo inherits it and overrides only what differs.
inherit_from = "github:acme/.github:cchk.toml"
Organization guide →
Every finding
Not just “failed”. What failed, and the fix.
- A stable rule ID that links to its documentation.
- The exact value that was checked.
- Why it failed, in one sentence.
- A fix you can paste, whenever the correction is unambiguous.
$ echo "Fix: add streaming support" | commit-check -m
1CC001 message check failed ==>
2Fix: add streaming support
3The commit message should follow Conventional Commits.
4Suggest: Use "fix: add streaming support"
Docs: https://commit-check.com/rules/#cc001
- 1.6M+downloads on PyPI
- 160+repositories run the Action
- Apacheallowlists the Action for its projects' CI
In the CI ofApacheTexas InstrumentsMilaIstio EcosystemOpenDriveLaband more →
Pricing
Free for open source. Team plan, soon.
The CLI, the hook, the Action and the MCP server are MIT licensed — nothing to buy. Plans only cover the hosted GitHub App, the one surface we run for you.
Open Source
Free
Public repositories, on any account.
Install the App →Personal
Free
Private repositories on a personal account.
Install the App →Team
Coming soon
Private repositories in an organization. Until then, the Action covers private repositories for free.
Watch for the launch →
Nothing is blocked while you try it: without a config file the App reports its findings but leaves the check run neutral. GitHub's own commit-metadata rules sit behind its Enterprise plan — the arithmetic, and the caveats →
Questions¶
Does it read my source code?
No. The CLI validates commit metadata and never opens your files. The hosted App uses a blob-filtered fetch and a sparse checkout that materializes only the config files, so no other repository content is ever downloaded. Content scanning is deliberately out of scope.
Can a developer bypass it?
The pre-commit hook, yes: git commit --no-verify is one flag, and a local
hook is there for fast feedback. The enforcement boundary is CI. Make the Action or the App a required status check and a
violating change cannot merge, however it was committed.
Will turning it on block everyone tomorrow?
No. Without a config file the App reports in full but leaves the check neutral, and it never rejects a push. Most rules are off until you turn them on — the rules reference marks which start on.
What about the history I already have?
Only new commits are checked. Nothing asks you to rewrite what is already merged.
Does it only work on GitHub?
The CLI and the pre-commit hook run anywhere Git does — GitLab, Gitea, Bitbucket, a local machine. The Action and the App are GitHub-specific because they integrate with GitHub's check runs.
Do I need Node.js?
No. On a modern Python there are no runtime dependencies at all.
Which Python versions are supported?
3.10 through 3.14. CI runs the suite on all five, across Linux, macOS and Windows — fifteen combinations on every change.
How do I know the package I installed is the one you built?
Every release carries a signed
build provenance attestation
naming the workflow in this repository that built it. Check a wheel
yourself with gh attestation verify <file> --repo commit-check/commit-check;
the GitHub Action runs the same check before it installs anything, and
fails the step if verification does not pass.
Who is behind this?
Commit Check is written and maintained by Xianpeng Shen, who also runs the hosted App. The engine, the Action, the App and the MCP server are open source under the commit-check organization — if the hosted App ever stops, the GitHub Action reads the same config and reports the same rule IDs.
Start with two commands.
No config file needed. The defaults check Conventional Commits, Conventional Branch and subject length; tighten them when you are ready.
$ pip install commit-check
$ commit-check --message --branch
github-actionsbot commentededited
Commit Check
2 of 5 checks failed
bad msgFix: handle empty password▸ Show all 5 checks
All 5 checks passed
▸ Show all 5 checks
Rules reference