Conventional Commits
This skill provides the complete specification for Conventional Commits format, validation rules, and integration with semantic-release.
When to Use
✅ DO Use:
- Creating commit messages
- Validating commit format
- Suggesting commit messages
- Creating PR titles
- Understanding semantic-release behavior
- Grouping commits by context
❌ DON'T Use:
- For release commits (automatically generated by semantic-release)
- For temporary or debug commits
Commit Format
<type>(<scope>): <subject>
[optional body]
[optional footer(s)]
Commit Types
Allowed Types
feat: New feature (generates MINOR version: 1.0.0 → 1.1.0)fix: Bug fix (generates PATCH version: 1.0.0 → 1.0.1)docs: Documentation-only changes (no release by default)style: Formatting changes that don't affect code (no release by default)refactor: Code refactoring without functionality changes (no release by default)perf: Performance improvements (no release by default)test: Adding or fixing tests (no release by default)build: Build system or dependency changes (no release by default)ci: CI/CD configuration changes (no release by default)chore: Other changes that don't fit categories (no release by default)revert: Reverts a previous commit
Type Prioritization
When determining commit type, prioritize in this order:
feat- For new featuresfix- For bug fixesrefactor- For refactoring without behavior changesdocs- For documentation changestest- For adding/fixing testschore- For maintenance tasks
Scope
The scope should indicate the affected code area.
When to Use Scope
- Use scope when the change affects a specific module/component
- Omit scope when the change affects multiple areas or is general
Common Scopes
Generic examples:
domain- Domain entities and business logicservice- Service layerapi- API endpointsdb- Database operationsauth- Authentication/authorizationutils- Utility functionscomponent- UI componentsmodel- Data modelscontroller- Controllersvalidator- Validation logic
Project-specific examples:
logging- Logging, enrichers, formattershttp- HttpClient, handlersmiddleware- Middleware componentsmvc- MVC-related codewebapi- Web APIconfig- Configurationcore- Core functionalitytests- Test files
Context-Based Scope Detection
For context-based commits:
- Use the main folder/module name (e.g., if file is in
Core/Domain/, scope isdomain) - For projects without clear structure, use
coreor the main package name - Group files by similar context (same parent folder or namespace)
Subject
The subject is a short, clear description of the change.
Subject Rules
- Lowercase (except proper nouns)
- Imperative mood: "add feature" not "added feature" or "adds feature"
- Maximum 72 characters
- No period at the end
- Always in English
- Objective and clear
Valid Subject Examples
add TraceContextEnricher for OpenTelemetry supportcorrect mongo connection retry strategydocument auth headers for endpointsadd unit tests for CNPJ rulessimplify normalization logic
Invalid Subject Examples
- ❌
Added new feature(past tense, not imperative) - ❌
Adds support for X(third person, not imperative) - ❌
Add new feature.(ends with period) - ❌
Add new feature for logging that enriches trace context with TraceId SpanId and ParentSpanId(too long) - ❌
adicionar novo recurso(not in English)
Complete Commit Examples
Valid Commits
# Feature
feat(logging): add TraceContextEnricher for OpenTelemetry support
feat(domain): add loyalty card entity
feat(mvc): add RouteNameEnricher to include route name in logs
# Bug Fix
fix(service): correct mongo connection retry strategy
fix(middleware): ensure Activity is available in PreSendRequestHeaders
fix: resolve compiler warnings
# Documentation
docs(api): document auth headers for endpoints
docs: update README with new configuration options
# Refactoring
refactor(utils): simplify normalization logic
refactor(core): simplify CorrelationContext implementation
# Tests
test(validator): add unit tests for CNPJ rules
test(logging): add tests for TraceContextEnricher
# Performance
perf(http): optimize HttpClient correlation ID injection
# CI/CD
ci: update semantic-release configuration
# Chore
chore: update dependencies to latest versions
Invalid Commits
# ❌ No type
Add new feature for logging
# ❌ Incorrect type
feature: add TraceContextEnricher
# ❌ No colon
feat add new feature
# ❌ Title too long
feat(logging): add TraceContextEnricher that enriches trace context with TraceId SpanId and ParentSpanId from Activity.Current
# ❌ Non-imperative mood
feat: added new feature
feat: adds support for X
# ❌ Ends with period
feat(logging): add TraceContextEnricher.
# ❌ Not in English
feat(logging): adicionar novo recurso
Context-Based Commits
Golden Rule
One commit = one context (when possible)
Process
- Group changes by context/folder/module
- Make separate commits by context:
- Order by dependency (innermost layers first, interfaces last)
- If there's no clear dependency, order alphabetically
- Don't mix different types in the same context:
refactor(domain)separate fromfeat(domain)fix(service)separate fromtest(service)
Exceptions
- If all changes are from the same context and type, can be a single commit
- Formatting/linter changes can be grouped in
styleorchore
Breaking Changes
If there's a contract/API break:
- Use
!in the type:feat(api)!: rename endpoint for ... - Add footer:
BREAKING CHANGE: <short explanation in English>
Example:
feat(api): change method signature
BREAKING CHANGE: Method X now requires parameter Y instead of Z
This generates a MAJOR version (1.0.0 → 2.0.0).
Pull Request Format
PR Title (CRITICAL)
The PR title MUST follow EXACTLY the same semantic commit format, as semantic-release analyzes the merge commit title to determine whether to generate a new version.
Required Format:
<type>(<scope>): <subject>
PR Title Rules:
- MUST start with a valid type (
feat,fix,docs, etc.) - MUST have a colon (
:) after the scope (or after the type if there's no scope) - MUST be in lowercase (except proper nouns)
- MUST use imperative mood ("add feature" not "added feature")
- MUST NOT end with a period
- MUST have a maximum of 72 characters
- MUST NOT include PR number (GitHub adds it automatically)
PR Description Template
## Summary
Brief description of the implemented changes.
## Changes
- Item 1
- Item 2
- Item 3
## Release Type
- [ ] `feat` - New feature (MINOR)
- [ ] `fix` - Bug fix (PATCH)
- [ ] `BREAKING CHANGE` - Incompatible change (MAJOR)
## Related
- Closes #issue-number (if any)
## Checklist
- [ ] Code tested
- [ ] Documentation updated
- [ ] Tests added/updated
Validation Checklist
Before Suggesting Commit
- Type is correct (
feat,fix, etc.) - Scope is appropriate (or omitted if it doesn't make sense)
- Subject is in lowercase (except proper nouns)
- Subject is in imperative mood
- Subject has less than 72 characters
- Subject doesn't end with period
- Subject is in English
- Format is correct:
<type>(<scope>): <subject> - Commit files belong to the same context (or are related changes)
- If there's a breaking change, includes
BREAKING CHANGE:in the footer
Before Creating PR
Title Validation:
- Title starts with valid type (
feat,fix,docs, etc.) - Title has colon (
:) after scope/type - Title is in lowercase (except proper nouns)
- Title uses imperative mood
- Title doesn't end with period
- Title has maximum of 72 characters
- Title doesn't include PR number
- Format is correct:
<type>(<scope>): <subject>
If any validation fails, fix it before suggesting.
Semantic Release Integration
Semantic-release analyzes commits using the angular preset with the following rules:
feat:→ MINOR version (1.0.0 → 1.1.0)fix:→ PATCH version (1.0.0 → 1.0.1)BREAKING CHANGE:→ MAJOR version (1.0.0 → 2.0.0)- Other types (
docs,chore, etc.) → No release (unless configured)
Commits that don't follow the pattern are ignored and don't generate a release.
GitHub CLI Usage
When creating PRs, use GitHub CLI (gh) instead of git push:
# Create PR with title and body
gh pr create --title "<type>(<scope>): <subject>" --body "<description>"
# Create PR from current branch
gh pr create --head <branch-name> --title "<type>(<scope>): <subject>" --body "<description>"
Never use git push origin main - always create feature branches and PRs.
Key Principles
- Format Consistency: Always use
<type>(<scope>): <subject>format - Imperative Mood: Use "add", "fix", "update" (not "added", "fixed", "updated")
- Context Grouping: Group commits by context/module when possible
- Validation First: Always validate before suggesting commits
- Semantic Release: Format matters for automatic versioning
- English Only: All commit messages must be in English
- GitHub CLI: Use
gh pr createfor PRs, notgit push