Commit Message Validator - Programmatically validates commit messages against the [Conventional Commits](https://www.conventionalcommits.org/) specification.
- Before committing code
- In pre-commit hooks
- In CI/CD pipelines
- During code review
- To enforce team standards
Step 1: Validate Commit Message
Validate a commit message string against Conventional Commits format:
Format: ():
Types:
feat: A new featurefix: A bug fixdocs: Documentation only changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringperf: Performance improvementstest: Adding or updating testschore: Maintenance tasksci: CI/CD changesbuild: Build system changesrevert: Reverting a previous commit
Validation Rules:
- Must start with type (required)
- Scope is optional (in parentheses)
- Subject is required (after colon and space)
- Use imperative, present tense ("add" not "added")
- Don't capitalize first letter
- No period at end
- Can include body and footer (separated by blank line)
Implementation
Use this regex pattern for validation:
```javascript
const CONVENTIONAL_COMMIT_REGEX =
/^(feat|fix|docs|style|refactor|perf|test|chore|ci|build|revert)(\(.+\))?: .{1,72}/;
function validateCommitMessage(message) {
const lines = message.trim().split('\n');
const header = lines[0];
// Check format
if (!CONVENTIONAL_COMMIT_REGEX.test(header)) {
return {
valid: false,
error: 'Commit message does not follow Conventional Commits format',
};
}
// Check length
if (header.length > 72) {
return {
valid: false,
error: 'Commit header exceeds 72 characters',
};
}
return { valid: true };
}
```
Valid Examples:
```
feat(auth): add OAuth2 login support
fix(api): resolve timeout issue in user endpoint
docs(readme): update installation instructions
refactor(components): extract common button logic
test(utils): add unit tests for date formatting
```
Invalid Examples:
```
Added new feature # Missing type
feat:new feature # Missing space after colon
FEAT: Add feature # Type should be lowercase
feat: Added feature # Should use imperative tense
```
Pre-commit Hook (.git/hooks/pre-commit):
```bash
#!/bin/bash
commit_msg=$(git log -1 --pretty=%B)
if ! node .claude/tools/validate-commit.mjs "$commit_msg"; then
echo "Commit message validation failed"
exit 1
fi
```
CI/CD Integration:
```yaml
# .github/workflows/validate-commits.yml
- name: Validate commit messages
run: |
git log origin/main..HEAD --pretty=%B | while read msg; do
node .claude/tools/validate-commit.mjs "$msg" || exit 1
done
```
Output Format
Returns structured validation result:
```json
{
"valid": true,
"type": "feat",
"scope": "auth",
"subject": "add OAuth2 login support",
"warnings": []
}
```
Or for invalid messages:
```json
{
"valid": false,
"error": "Commit message does not follow Conventional Commits format",
"suggestions": [
"Use format: (): ",
"Valid types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert"
]
}
```
Example Commands:
```bash
# Validate a commit message
node .claude/tools/validate-commit.mjs "feat(auth): implement jwt login"
# Validate from stdin (e.g. in a hook)
echo "fix: incorrect variable name" | node .claude/tools/validate-commit.mjs
```
- Validate Early: Check commit messages before pushing
- Provide Feedback: Show clear error messages with suggestions
- Enforce in CI: Add validation to CI/CD pipelines
- Team Training: Educate team on Conventional Commits format
- Tool Integration: Integrate with Git hooks and IDEs