Lightweight command-line validation for Co-authored-by commit trailers.
coauthorcheck works in any Git repository, regardless of the project's language or build system.
You can use coauthorcheck in one of these three ways:
- as a
pre-commitcommit-msghook for immediate local feedback - in GitHub Actions to validate branch or pull request commits before merge
- directly from CLI
Add this to .pre-commit-config.yaml:
repos:
- repo: https://github.com/simoncraf/coauthorcheck
rev: v0.5.0
hooks:
- id: coauthorcheck
stages: [commit-msg]Then install the hook:
pre-commit install --hook-type commit-msgThis is required because coauthorcheck validates the final commit message file, and commit-msg is the Git hook that receives that file.
The easiest GitHub integration is the reusable composite action:
- uses: simoncraf/coauthorcheck-action@v0.2.0
with:
range: origin/main..HEADYou can also install it from GitHub Marketplace: coauthorcheck Marketplace Action
Validate commits introduced by branch pushes:
name: Validate Co-authored-by trailers
on:
push:
branches:
- "feature/**"
- "feat/**"
jobs:
validate-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate branch commits
uses: simoncraf/coauthorcheck-action@v0.2.0
with:
range: origin/main..HEADValidate commits introduced by a pull request:
name: Validate Co-authored-by trailers on PR
on:
pull_request:
branches:
- main
jobs:
validate-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate PR commits
uses: simoncraf/coauthorcheck-action@v0.2.0
with:
range: origin/${{ github.base_ref }}..HEADSee docs/integrations.md for local hooks, JSON output, PR comments, and more workflow examples.
When validation fails, coauthorcheck also prints a suggested corrected trailer line. If multiple issues affect the same trailer, they are merged into one canonical fix suggestion.
coauthorcheck .git/COMMIT_EDITMSG
coauthorcheck HEAD
coauthorcheck HEAD~5..HEAD
coauthorcheck main..HEAD
coauthorcheck origin/main..HEAD
coauthorcheck --file .git/COMMIT_EDITMSG
coauthorcheck --commit HEAD
coauthorcheck --range HEAD~5..HEADPositional input is auto-detected in this order:
- values containing
..or...are treated as commit ranges - existing paths are treated as commit message files
- everything else is treated as a commit ref
Use the explicit flags when you want fully unambiguous scripting.
Check the installed CLI:
coauthorcheck --helpInstall from PyPI:
pip install coauthorcheckOr with uv:
uv tool install coauthorcheckOr with pipx:
pipx install coauthorcheckAfter installation, run:
coauthorcheck --helpValidate the commit message currently being edited:
coauthorcheck .git/COMMIT_EDITMSGValidate only the commits introduced by your current branch compared with main:
coauthorcheck main..HEADValidate only the commits introduced by your branch compared with the remote default branch:
coauthorcheck origin/main..HEADValidate the last few commits on the current branch:
coauthorcheck HEAD~3..HEADcoauthorcheck supports repository-local configuration from either:
pyproject.tomlunder[tool.coauthorcheck].coauthorcheck.toml
Configuration is resolved in this order:
--config <path>- nearest
.coauthorcheck.toml - nearest
pyproject.tomlwith[tool.coauthorcheck] - built-in defaults
When config files are auto-discovered, coauthorcheck searches upward from the current working directory. This means running the tool from a nested folder in the repo still finds the repo-level config.
Example using pyproject.toml:
[tool.coauthorcheck.rules]
name_parts = "warning"
github_handle = "warning"
incorrect_casing = "error"
invalid_format = "error"
malformed_email = "error"
missing_email = "error"
missing_name = "error"
email_domain = "error"
[tool.coauthorcheck.policy]
minimum_name_parts = 2
allowed_email_domains = ["example.com"]
blocked_email_domains = ["users.noreply.github.com"]
allow_github_noreply = falseExample using .coauthorcheck.toml:
[rules]
name_parts = false
github_handle = "warning"
incorrect_casing = "error"
invalid_format = "error"
malformed_email = "error"
missing_email = "error"
missing_name = "error"
email_domain = "error"
[policy]
minimum_name_parts = 1
allowed_email_domains = ["example.com"]
blocked_email_domains = ["users.noreply.github.com"]
allow_github_noreply = trueUse an explicit config file with:
coauthorcheck --config .coauthorcheck.toml main..HEADRule values can be:
false: disable the ruletrueor"error": enable the rule as an error"warning": enable the rule as a warning
email_domain is a special policy rule. If you enable it, you must also configure allowed_email_domains, blocked_email_domains, allow_github_noreply, or a combination of them under [tool.coauthorcheck.policy] in pyproject.toml or under [policy] in .coauthorcheck.toml.
name_parts uses the minimum_name_parts policy value. The default is 2, which preserves the current "first and last name" behavior. Set minimum_name_parts = 1 to relax the rule, or a higher value such as 3 to require more name parts.
Example:
[tool.coauthorcheck.rules]
email_domain = "warning"
name_parts = "error"
[tool.coauthorcheck.policy]
minimum_name_parts = 3
allowed_email_domains = ["example.com", "company.com"]
blocked_email_domains = ["users.noreply.github.com"]
allow_github_noreply = falseWith that configuration:
- co-author names must contain at least three parts
- emails from the listed domains are allowed
- emails from blocked domains are rejected
- GitHub noreply addresses are explicitly rejected
- emails from other domains produce an
email-domainissue - if exactly one allowed domain is configured,
coauthorcheckcan suggest a corrected email domain - enabling
email_domainwithoutallowed_email_domains,blocked_email_domains, orallow_github_noreplyis a configuration error
Only error-level issues fail the command with exit code 1. Warnings are reported but do not fail the run.
Unknown rule names or invalid values are treated as configuration errors.
See docs/rules.md for a detailed explanation of each rule.
See docs/integrations.md for pre-commit, GitHub Actions, JSON output, and PR comment examples.
Use coauthorcheck --format json ... for machine-readable output in CI and automation.
JSON issue objects also include a suggestion field when a corrected trailer can be proposed.
Set up the local environment:
uv syncRun the CLI from the project environment:
uv run coauthorcheck --helpRun the tool from another repository by changing into that repository first and then invoking the executable from this project:
cd /path/to/other-repo
/path/to/coauthorcheck/.venv/Scripts/coauthorcheck.exe main..HEADIn Git Bash, use /c/... style paths:
/path/to/coauthorcheck/.venv/Scripts/coauthorcheck.exe main..HEADRun the test suite:
uv run pytestRun the linter:
uv run ruff check .