A GitHub Action that checks git commit messages for:
- Grammar issues using the LanguageTool API
- Structure quality using the Anthropic API (checks if the commit explains WHY, not just WHAT)
git-commit-linter/
├── bb.edn # Babashka project configuration
├── git-commit-linter # Main executable script
├── src/
│ └── commit_linter/
│ ├── core.clj # Main application logic
│ └── api.clj # API integration (LanguageTool & Anthropic)
└── resources/
└── test/ # Test commit message files
├── good-commit.txt
├── bad-commit.txt
└── ...
Add this action to your workflow to automatically check commit messages:
- name: Lint commit messages
uses: your-username/git-commit-linter@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
The GitHub Action performs two checks on commit messages:
Grammar Check (LanguageTool API):
- Sends the message to LanguageTool API for grammar analysis
- If errors exceed the threshold, the action fails
- Otherwise, warnings are displayed but the check passes
Structure Check (Anthropic API, if configured):
- Uses Claude to analyze if the message explains WHY the change was made
- Scores the message from 0-10 on how well it explains the rationale
- Provides feedback and suggestions for improvement
- Fails if score is below threshold and doesn't explain why
- Skipped if ANTHROPIC_API_KEY is not provided
Create .github/workflows/commit-lint.yml
in your repository:
name: Commit Message Linter
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
commit-lint:
runs-on: ubuntu-latest
name: Check Commit Messages
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch full history for commit checking
- name: Lint commit messages
uses: your-username/git-commit-linter@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Lint commit messages with custom settings
uses: your-username/git-commit-linter@v1
with:
commit-message: ${{ github.event.head_commit.message }} # Check specific message
max-grammar-errors: 2
min-structure-score: 8
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
skip-grammar-check: false
skip-structure-check: false
fail-on-error: true # Set to false to only show warnings
Input | Description | Required | Default |
---|---|---|---|
commit-message |
Specific commit message to check (defaults to last commit) | No | "" |
max-grammar-errors |
Maximum grammar errors allowed | No | 3 |
min-structure-score |
Minimum structure score required (0-10) | No | 7 |
anthropic-api-key |
Anthropic API key for structure checking | No | "" |
skip-grammar-check |
Skip grammar checking entirely | No | false |
skip-structure-check |
Skip structure checking entirely | No | false |
fail-on-error |
Whether to fail the action on errors | No | true |
Output | Description |
---|---|
grammar-status |
Status of grammar check (passed, warning, failed, skipped, error) |
grammar-errors |
Number of grammar errors found |
structure-status |
Status of structure check (passed, failed, skipped, error) |
structure-score |
Structure score (0-10) |
structure-feedback |
Feedback from structure check |
overall-status |
Overall status (passed, warning, failed) |
- name: Lint commit messages
id: commit-lint
uses: your-username/git-commit-linter@v1
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
- name: Comment on PR with results
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const status = '${{ steps.commit-lint.outputs.overall-status }}';
const grammarErrors = '${{ steps.commit-lint.outputs.grammar-errors }}';
const structureScore = '${{ steps.commit-lint.outputs.structure-score }}';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## Commit Message Analysis
- **Overall Status**: ${status}
- **Grammar Errors**: ${grammarErrors}
- **Structure Score**: ${structureScore}/10`
});
-
Anthropic API Key (optional): Add your Anthropic API key as a repository secret named
ANTHROPIC_API_KEY
for structure checking. -
Repository Access: Ensure the action has access to checkout your repository with full commit history if you want to check multiple commits.
For testing the linter locally during development:
# Install Babashka
# Check a commit message
bb check-commit --file resources/test/good-commit.txt
# Or use the main script directly
./git-commit-linter --file resources/test/good-commit.txt