The Commit Validator ensures that commit messages in a pull request follow specified patterns or formats, helping maintain a consistent commit history in your repository.
Configuration
Regex pattern(s) that commit messages should match
Regex pattern(s) for commit messages to ignore
Skip validation for merge commits (starting with “Merge ”)
Only validate the first commit in the PR
Only validate the last commit in the PR
Custom message to display when validation fails
Basic Usage
validate:
- type: "commit"
match: "^(feat|fix|docs): .+"
ignore_merge_commits: true
Examples
Validate that commit messages follow the Conventional Commits format:
validate:
- type: "commit"
match: "^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\\(\\w+\\))?: .+"
ignore_merge_commits: true
message: "Commit messages must follow conventional commit format: type(scope): description"
Issue Reference Required
Ensure commits reference an issue number:
validate:
- type: "commit"
match: ".*\\(#\\d+\\)$"
message: "Commit messages must reference an issue number at the end, e.g., 'Fix login bug (#123)'"
Validate Only the Last Commit
For squash-and-merge workflows, you might only care about the last commit:
validate:
- type: "commit"
match: "^(feat|fix|docs): .+"
last_only: true
message: "The last commit message must follow the required format"
Ignore Certain Commit Patterns
Skip validation for certain types of commits:
validate:
- type: "commit"
match: "^[A-Z].*"
ignore: "^(Merge |Revert |Automated )"
ignore_merge_commits: true
message: "Commit messages must start with a capital letter"
Pattern Matching
The Commit Validator uses JavaScript regular expressions for pattern matching. When specifying patterns, remember:
- Patterns are case-sensitive by default
- Some characters need to be escaped with a backslash (
\)
- In YAML, backslashes need to be double escaped (
\\)
For case-insensitive matching, use the i flag: "/pattern/i"
How It Works
Retrieve Commits
The validator fetches all commits in the PR from the GitHub API
Filter Commits
Applies filtering based on ignore_merge_commits, first_only, or last_only settings
Check Patterns
For each commit, checks if the message matches required patterns and doesn’t match ignored patterns
Return Result
Returns a validation result with status (pass, fail, or error) and a message listing any non-conforming commits
Complete Rule Example
ruleset:
- name: "Conventional Commits"
when:
- "pull_request.opened"
- "pull_request.synchronize"
validate:
- type: "commit"
match: "^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\\(\\w+\\))?: .+"
ignore_merge_commits: true
message: "Commit messages must follow the conventional commit format"
on_success:
- label:
add: ["conventional-commits"]
on_failure:
- comment:
body: |
Please ensure all your commit messages follow the conventional commit format:
```
<type>(<optional scope>): <description>
[optional body]
[optional footer(s)]
```
Where `type` is one of: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
Example: `feat(auth): implement login functionality`
The following commits don't follow this format:
{{ validation_summary }}
Best Practices
Enable ignore_merge_commits to avoid validation errors on automated merge commits
Provide helpful error messages explaining the expected format
Consider combining with the title validator for a consistent history
For squash-and-merge workflows, use last_only: true
Complex validation rules may be frustrating for contributors; consider providing commit message templates