Conventional Commits

Conventional Commits and Semantic Release

Conventional Commits 1.0.0 (conventionalcommits.org (https://www.conventionalcommits.org/en/v1.0.0/ 96,043 )) gives the subject line a structure a program can parse: <type>[(scope)][!]: <description>, then an optional body and footers. The specification defines only two types, and ties them to Semantic Versioning (Semantic Version Tags): fix means a patch release and feat a minor release, while a ! before the colon or a BREAKING CHANGE: footer means a major release whatever the type. The widely used Angular 42,088 convention adds docs, test, refactor, perf, build, ci, chore and style, which trigger no release.

commitlint 18,754 (github.com/conventional-changelog/commitlint (https://github.com/conventional-changelog/commitlint 18,754 ), MIT, version 21.2.3) checks a message against such rules. Sam replaces BookNest's hand-written commit-msg hook of commit-msg Hook with it:

Checking commit messages with commitlint in the commit-msg hookShell
git switch -q main
npm install --save-dev --silent @commitlint/cli @commitlint/config-conventional
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.mjs
echo 'npx --no -- commitlint --edit "$1"' > .husky/commit-msg
echo "Add ?minRating= to /api/books" | npx commitlint
echo "feat(api): Add ?minRating= to /api/books" | npx commitlint
git add -A && git commit -qm "build: check commit messages with commitlint"
git push -q && git log --oneline -1
Output
⧗   --- input ---
Add ?minRating= to /api/books
✖   subject may not be empty [subject-empty]
✖   type may not be empty [type-empty]
...
⧗   --- input ---
feat(api): Add ?minRating= to /api/books
✖   subject must not be sentence-case [subject-case]
...
d396523 build: check commit messages with commitlint

The .mjs extension allows export in a commonjs package, and npx --no never downloads a missing commitlint. The second rejection surprises most people: the conventional rules want a lowercase description, the opposite of BookNest's old rule. Old commits stay as they are, and release tools skip what they cannot parse.

Semantic release is the payoff: a tool reads the messages since the last tag, computes the next version, writes the changelog and tags the release.

Tools that turn Conventional Commits into releases
Tool Runs What it does License
semantic-release 25.0.9 24,069 In CI on every push Versions, tags, publishes, writes release notes MIT
release-please 17.11.2 7,559 In CI (GitHub 29 ) Keeps a release pull request up to date Apache-2.0
commit-and-tag-version 13.2.1 655 Locally Bumps, writes CHANGELOG.md, commits and tags ISC
git-cliff 2.14.2 12,272 Anywhere Changelog from templates; Rust binary MIT or Apache-2.0

semantic-release needs CI and push rights, so it belongs to GitHub. Here BookNest uses commit-and-tag-version, the maintained fork of the deprecated standard-version 7,984 , which touches only the local repository (Release and Hotfix Branches).