CI/CD·5 min read·

Enforcing Commit Conventions (Conventional Commits) With CI

Adopt Conventional Commits and let CI enforce, lint, and validate them so releases and changelogs generate automatically.

NB

Netbay Cloud Team

Netbay Engineering

On this page

Commit messages are the smallest piece of code you write, and the most consistently ignored. Conventional Commits is a naming convention that turns those throwaway strings into structured data your tools can parse: fix a bug, and your release notes update themselves; bump a dependency, and semantic versioning knows it is a patch. The convention only pays off if it is enforced, and CI is the natural enforcer.

The convention in ten seconds

Every commit message starts with a type, then an optional scope in parentheses, then a colon and a description. The reserved types are fix (patch), feat (minor), and breaking-change indicators (major), with chore, docs, refactor, test, and style for the rest:

text
feat(auth): add password reset flow
fix(api): return 404 for unknown video ids
chore(deps): bump lodash to 4.17.21

A breaking change is marked either with a ! after the type or a footer line BREAKING CHANGE, and that is what bumps the major version. Everything else is determined by rules a machine can apply, which is exactly what makes it automatable.

Letting CI enforce the format

A commit-msg hook on each developer's machine is a nice first line, but hooks are bypassable and optional. CI enforces the contract for shared branches, so even a squashed merge has to obey. Tools such as commitlint give you both: a local hook for fast feedback and a CI job that rejects non-conforming messages.

json
{
  "extends": ["@commitlint/config-conventional"],
  "rules": {
    "subject-case": [2, "never", ["sentence-case", "start-case", "pascal-case"]],
    "body-max-line-length": [2, "always", 100]
  }
}

Add the job to your pipeline:

yaml
name: commitlint
on:
  pull_request:
jobs:
  lint-commits:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: wagoid/commitlint-github-action@v5
        with:
          configFile: commitlint.config.json

Now a PR containing a message like "fix stuff" fails the gate, and the author is told exactly what is wrong. That is enforcement with a teacher attached, which is how conventions actually spread.

Generating changelogs and versions automatically

Once CI trusts the messages, versioning and release notes are mechanical. The pattern is a release job that reads the commits since the last tag, applies the semver rule, bumps the version, and writes a changelog. Many teams use semantic-release, which does this in one pass:

bash
npx semantic-release

Configured with branches and plugins, semantic-release inspects the Conventional-Commits history, decides the next version, builds the changelog, and tags the release — all in CI, no human deciding "is this a minor or a patch."

conventional commit feat fix chore semantic-release read history bump version write changelog create tag messages become machine-readable release metadata

The breaking-change discipline

The whole scheme stands or falls on how honestly you declare breaking changes. A library that silently changes behavior without a breaking-change marker will generate a minor bump, and downstream consumers will break at upgrade time — the opposite of the safety the convention promises. CI can help by scanning for suspicious patterns (type-signature changes, removed exports) and flagging PRs that look breaking but lack the marker, prompting a human decision rather than silently assuming.

Squashing versus preserving history

A common question: do we squash, which collapses many messages into one, or keep full history? For a release-driven workflow, squash-merge with a well-written, conventional commit message works well because each PR becomes one release unit. Keep the type accurate to the whole change — if a PR mixes a fix and a feat, split it or let the bigger scope win, deliberately. Whatever you choose, record it in the contributing guide so the convention is unambiguous.

Takeaway: enforce Conventional Commits in CI and your changelog, versioning, and release process become automatic and trustworthy. The same pipeline discipline makes sense for any service you run on a Netbay VPS from Lucknow DC01, deployable in under a minute at netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance