patternbashModerate
Semantic versioning enforcement with commitlint in CI
Viewed 0 times
commitlintconventional commitssemantic versioningPR lintfetch-depthbreaking change
Error Messages
Problem
Teams adopt conventional commits informally but inconsistently. Commits like 'fix stuff' or 'WIP' pollute the history, break changelog generation, and make it impossible to automate version bumps.
Solution
Enforce conventional commits with commitlint in CI:
commitlint.config.js:
# .github/workflows/lint-commits.yml
on:
pull_request:
types: [opened, synchronize, reopened, edited]
jobs:
commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install --no-save @commitlint/cli @commitlint/config-conventional
- run: |
npx commitlint \
--from ${{ github.event.pull_request.base.sha }} \
--to ${{ github.event.pull_request.head.sha }} \
--verbosecommitlint.config.js:
module.exports = { extends: ['@commitlint/config-conventional'] };Why
Blocking the PR until all commits pass commitlint enforces the convention at the point of code review, not after the fact. fetch-depth: 0 is required so commitlint can access all commits in the PR range.
Gotchas
- Squash-merge PRs only need the PR title to follow convention—individual commit messages don't matter if you squash
- fetch-depth: 0 fetches the entire repo history which is slow on large repos; use fetch-depth with a computed depth instead
- Breaking changes must use feat!: or include 'BREAKING CHANGE:' in the footer—not in the subject line
Revisions (0)
No revisions yet.