Conventional Commits — Team Guidelines with Lots of Examples
The format (one line)
type(scope)!: subject
- type: one of
feat,fix,perf,refactor,chore,docs,test,build,ci,style,revert - scope (optional): focus area like
frontend,backend,api,db,billing,search,auth,infra - !: indicates a breaking change (also add a
BREAKING CHANGE:footer in the body)
Rules we enforce (team policy)
- Header
- Max 100 characters
- No trailing period
- Body (optional but recommended)
- Leave one blank line between header and body
- Explain what and why; wrap lines around ~72–100 chars
- Breaking changes
- Either:
feat(scope)!: ... - Or add a footer line:
BREAKING CHANGE: describe impact and migration
- Either:
SemVer mapping (cheat-sheet)
fix:→ PATCHfeat:→ MINORBREAKING CHANGEor!→ MAJOR
Copy-paste templates
Simple one-liner
type(scope): short imperative summary
With body, references, and breaking footer
type(scope)!: short imperative summary
Longer body explaining what changed and why. Include context and alternatives
considered if helpful.
BREAKING CHANGE: describe the impact and how to migrate.
Refs: #123, #124
Revert
revert: type(scope): original summary
This reverts commit <sha>.
Quick examples (expanded)
Features
feat(frontend): add dropzone upload with progressfeat(api): support cursor-based paginationfeat(auth): refresh-token rotation with inactivity timeoutfeat(search): enable fuzzy matching with trigram indexfeat(billing): add SEPA Direct Debitfeat(notifications): email templates with MJMLfeat(settings): dark mode toggle and persistencefeat(reports): export to CSV and XLSXfeat(files): resumable uploads with chunk retry
Fixes
fix(backend): parse CSV with semicolon delimiterfix(api): return 400 for invalid cursorfix(auth): handle expired refresh token gracefullyfix(db): correct uuid default in migrationfix(frontend): guard against undefined organizationfix(logging): redact secrets from error payloadsfix(cli): ensure --help exits with code 0fix(i18n): escape placeholders in translation strings
Performance
perf(db): batch inserts using COPYperf(cache): pipeline Redis writes to reduce RTTperf(api): reuse HTTP client to cut TLS handshakesperf(images): lazy-load thumbnails on listing page
Refactors
refactor(api): extract pagination utilsrefactor(auth): isolate token validation middlewarerefactor(db): rename column quantities -> items_jsonrefactor(ui): co-locate hooks with feature modulesrefactor(router): flatten nested controllers
Documentation
docs: update README with versioning instructionsdocs(contributing): add commit message guidedocs(api): examples for /licenses endpointsdocs(runbook): add on-call escalation steps
Tests
test: add unit tests for version endpointtest(e2e): onboarding happy-path scenariotest(api): contract tests for /auth/tokentest(fixtures): generate sample invoices
Build / CI / Chore / Style
build(docker): switch to multi-stage buildbuild(makefile): add target db.resetbuild(nix): pin flake inputs for reproducible buildsci(github): cache pnpm installsci(pipeline): run migrations before smoke testschore(deps): bump fastapi from 0.111 to 0.115chore(release): 2.0.0style(css): normalize heading sizes and spacingstyle: apply Prettier/Black formattingchore(lint): enable import order checks
Reverts & Breaking changes
revert: feat(api): support cursor-based paginationfeat!: drop Node 16 supportrefactor(api)!: remove deprecated v1 upload endpoints
Example breaking footer
feat(auth)!: enforce PKCE for public clients
BREAKING CHANGE: public clients must use PKCE. Add code_challenge and
code_verifier to the authorization code flow to migrate.
Detailed bug fix
fix(db): prevent transaction deadlock on concurrent updates
Use SELECT ... FOR UPDATE SKIP LOCKED to avoid blocking high-traffic updates
on the same organization row. This reduces average latency by ~35% under load.
Scopes: how to pick good ones
Use stable, short labels that match product areas or subsystems:
- Subsystems:
api,frontend,backend,db,auth,telemetry - Feature areas:
upload,billing,org,search,alerts,reports - Tooling/infra:
docker,nix,github,pipeline,helm,infra
Avoid one-off misc scopes; favor consistent names across repos.
Git tips (handy oneliners)
Commit with a body
git commit -m "feat(api): support cursor-based pagination" -m "Adds stable cursor encode/decode and validates limit." -m "Refs: #123"
Amend the last commit message
git commit --amend
Revert a commit
git revert <sha>
Recommended tooling
- Linting:
@commitlint/cli+@commitlint/config-conventional - Hooks: Husky or native Git hooks to enforce on commit/push
- Releases:
semantic-release(or similar) to tag & generate changelogs
Comments
Post a Comment