Agent Skills: Conventional Commits

When writing a git commit message. When task completes and changes need committing. When project uses semantic-release, commitizen, git-cliff. When choosing between feat/fix/chore/docs types. When indicating breaking changes. When generating changelogs from commit history.

UncategorizedID: Jamie-BitFlight/claude_skills/conventional-commits

Skill Files

Browse the full folder contents for conventional-commits.

Download Skill

Loading file tree…

conventional-commits/SKILL.md

Skill Metadata

Name
conventional-commits
Description
When writing a git commit message. When task completes and changes need committing. When project uses semantic-release, commitizen, git-cliff. When choosing between feat/fix/chore/docs types. When indicating breaking changes. When generating changelogs from commit history.

Conventional Commits

Compose commit messages following the Conventional Commits v1.0.0 specification for structured commit history, automated changelog generation, and semantic versioning.

When to Use This Skill

Use this skill when:

  • Creating git commit messages for structured projects
  • Validating commit message format against Conventional Commits specification
  • Setting up commit message validation with commitlint
  • Configuring changelog generation from commit history
  • Implementing semantic versioning automation
  • Reviewing commit messages for specification compliance
  • Training teams on commit message standards
  • Integrating with tools like semantic-release, commitizen, or git-cliff

Message Structure

<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

Components

| Component | Required | Description | Example | | ----------- | -------- | ---------------------------- | -------------------------------- | | type | Yes | Commit category | feat, fix, docs | | scope | No | Codebase section affected | (auth), (parser) | | description | Yes | Short summary of changes | add user authentication | | body | No | Detailed explanation | Multiple paragraphs with context | | footer | No | Breaking changes, issue refs | BREAKING CHANGE:, Refs: #123 |

Commit Types

Required Types (SemVer Impact)

These types are mandated by the Conventional Commits specification and directly affect semantic versioning:

flowchart LR
    Fix[fix: Bug fix<br/>for users] --> PatchVer[PATCH<br/>0.0.X]
    Feat[feat: New feature<br/>for users] --> MinorVer[MINOR<br/>0.X.0]
    Breaking[Any type with<br/>BREAKING CHANGE or !] --> MajorVer[MAJOR<br/>X.0.0]

    style PatchVer fill:#e1f5ff
    style MinorVer fill:#fff4e1
    style MajorVer fill:#ffe1e1

| Type | Description | SemVer | Example | | ------ | --------------------- | ------------- | ----------------------------------- | | feat | New feature for users | MINOR (0.X.0) | feat: add user authentication | | fix | Bug fix for users | PATCH (0.0.X) | fix: prevent crash on empty input |

Recommended Types (Angular Convention)

These types come from @commitlint/config-conventional based on Angular commit guidelines. They have no implicit SemVer effect unless they include BREAKING CHANGE.

| Type | Description | Example | | ---------- | ------------------------------------------- | ------------------------------------ | | build | Build system or external dependency changes | build: update webpack to v5 | | ci | CI configuration changes | ci: add Node 18 to test matrix | | docs | Documentation only changes | docs: update API reference | | perf | Performance improvement | perf: reduce bundle size by 20% | | refactor | Code change with no bug fix or feature | refactor: extract validation logic | | style | Code style changes (whitespace, formatting) | style: fix indentation | | test | Adding or correcting tests | test: add unit tests for parser |

Additional Common Types

| Type | Description | Example | | -------- | --------------------------------------- | ----------------------------- | | chore | Changes not modifying src or test files | chore: update .gitignore | | revert | Reverts a previous commit | revert: feat: add user auth |

Note: Teams can define custom types beyond feat and fix, but Angular convention types are widely supported by tooling.

Specification Rules

The following rules constitute the official Conventional Commits 1.0.0 specification per RFC 2119.

Type and Scope

  1. Commits MUST be prefixed with a type, consisting of a noun (feat, fix, etc.), followed by OPTIONAL scope, OPTIONAL !, and REQUIRED terminal colon and space.

  2. Type feat MUST be used when a commit adds a new feature.

  3. Type fix MUST be used when a commit represents a bug fix.

  4. A scope MAY be provided after a type. A scope MUST consist of a noun describing a codebase section surrounded by parenthesis, e.g., fix(parser):

  5. A description MUST immediately follow the colon and space after the type/scope prefix. The description is a short summary of code changes, e.g., fix: array parsing issue when multiple spaces were contained in string

Body

  1. A longer commit body MAY be provided after the short description, providing additional contextual information. The body MUST begin one blank line after the description.

  2. A commit body is free-form and MAY consist of any number of newline separated paragraphs.

Footer

  1. One or more footers MAY be provided one blank line after the body. Each footer MUST consist of a word token, followed by either a :<space> or <space># separator, followed by a string value (inspired by git trailer convention).

  2. A footer's token MUST use - in place of whitespace characters, e.g., Acked-by (this helps differentiate footer section from multi-paragraph body). Exception: BREAKING CHANGE MAY also be used as a token.

  3. A footer's value MAY contain spaces and newlines. Parsing MUST terminate when the next valid footer token/separator pair is observed.

Breaking Changes

  1. Breaking changes MUST be indicated in the type/scope prefix of a commit, or as an entry in the footer.

  2. If included as a footer, a breaking change MUST consist of uppercase text BREAKING CHANGE, followed by colon, space, and description, e.g., BREAKING CHANGE: environment variables now take precedence over config files

  3. If included in the type/scope prefix, breaking changes MUST be indicated by ! immediately before :. If ! is used, BREAKING CHANGE: MAY be omitted from footer, and commit description SHALL be used to describe the breaking change.

Additional Rules

  1. Types other than feat and fix MAY be used in commit messages, e.g., docs: update ref docs

  2. The units of information that make up Conventional Commits MUST NOT be treated as case sensitive by implementors, except BREAKING CHANGE which MUST be uppercase.

  3. BREAKING-CHANGE MUST be synonymous with BREAKING CHANGE when used as a token in a footer.

Description Best Practices

Based on Angular commit message guidelines:

Summary/Description Guidelines

  • Use imperative, present tense: "change" not "changed" nor "changes"
  • Do not capitalize first letter
  • No period (.) at the end
  • Keep entire header (type + scope + description) under 72 characters

Good Examples

feat: add validation for email input
fix: handle null pointer in user service
docs: update installation instructions
refactor: simplify authentication flow

Bad Examples (Avoid)

feat: Added validation for email input     # Past tense
fix: Handles null pointer in user service  # Third person
docs: Update installation instructions.    # Period at end, capitalized
FEAT: add validation                       # Uppercase type (inconsistent)

Body Guidelines

  • Use imperative, present tense (same as summary)
  • Explain motivation for the change
  • Include comparison of previous vs new behavior when helpful
  • Body MUST begin with one blank line after description
  • Recommended minimum: 20 characters when body is present

Breaking Changes

Methods to Indicate Breaking Changes

Three equivalent approaches:

  1. Footer notation:

    feat: allow provided config object to extend other configs
    
    BREAKING CHANGE: `extends` key in config file is now used for extending other config files
    
  2. Type suffix with !:

    feat!: remove support for Node 6
    
  3. Type+scope suffix with !:

    feat(api)!: send an email to the customer when a product is shipped
    

Rules

  • BREAKING CHANGE MUST be uppercase
  • BREAKING-CHANGE is synonymous when used as footer token
  • Breaking changes MUST correlate to MAJOR version bump in SemVer

Semantic Versioning Correlation

flowchart TD
    Start([Analyze Commits]) --> CheckBreaking{Any commit has<br/>BREAKING CHANGE<br/>or !?}
    CheckBreaking -->|Yes| Major[MAJOR bump<br/>X.0.0]
    CheckBreaking -->|No| CheckFeat{Any commit<br/>is feat?}
    CheckFeat -->|Yes| Minor[MINOR bump<br/>0.X.0]
    CheckFeat -->|No| CheckFix{Any commit<br/>is fix?}
    CheckFix -->|Yes| Patch[PATCH bump<br/>0.0.X]
    CheckFix -->|No| NoChange[No version change]

    Major --> End([Release])
    Minor --> End
    Patch --> End
    NoChange --> End

Commit Type to Version Mapping

| Commit Type | Version Bump | | ------------------------ | ------------- | | fix | PATCH (0.0.X) | | feat | MINOR (0.X.0) | | BREAKING CHANGE or ! | MAJOR (X.0.0) |

Reason: Enables automated semantic versioning based on commit history.

Validation Patterns

Header Validation Regex

^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?!?:\s.+$

Python Validation Example

import re

CONVENTIONAL_COMMIT_PATTERN = re.compile(
    r'^(?P<type>feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)'
    r'(?:\((?P<scope>[^)]+)\))?'
    r'(?P<breaking>!)?'
    r':\s'
    r'(?P<description>.+)$'
)

def validate_header(header: str) -> bool:
    """Validate commit header follows Conventional Commits."""
    return bool(CONVENTIONAL_COMMIT_PATTERN.match(header))

def parse_header(header: str) -> dict | None:
    """Parse commit header into components."""
    match = CONVENTIONAL_COMMIT_PATTERN.match(header)
    if not match:
        return None
    return {
        'type': match.group('type'),
        'scope': match.group('scope'),
        'breaking': bool(match.group('breaking')),
        'description': match.group('description'),
    }

Complete Examples

Simple Commits

feat: add user authentication
fix: prevent crash on empty input
docs: correct spelling of CHANGELOG

Commits with Scope

feat(lang): add Polish language
feat(parser): add ability to parse arrays
fix(auth): handle token expiration correctly

Breaking Changes

feat: allow provided config object to extend other configs

BREAKING CHANGE: `extends` key in config file is now used for extending other config files
feat!: send an email to the customer when a product is shipped
feat(api)!: send an email to the customer when a product is shipped
chore!: drop support for Node 6

BREAKING CHANGE: use JavaScript features not available in Node 6.

Multi-Paragraph Body with Footers

fix: prevent racing of requests

Introduce a request id and a reference to latest request. Dismiss
incoming responses other than from latest request.

Remove timeouts which were used to mitigate the racing issue but are
obsolete now.

Reviewed-by: Z
Refs: #123

Revert Commit

revert: let us never again speak of the noodle incident

Refs: 676104e, a215868

Performance Improvement

perf: reduce memory allocation in parser by 40%

Replace string concatenation with StringBuilder pattern.
Benchmark results show 40% reduction in heap allocations.

Refs: #456

Refactoring

refactor: extract authentication logic into separate module

Move auth-related functions from utils.py to auth.py.
No functional changes.

Build/CI Changes

ci: add Node 18 to test matrix
build: upgrade webpack from v4 to v5

- Update webpack.config.js for v5 compatibility
- Replace deprecated plugins
- Update all loader dependencies

Refs: #789

Test and Style Changes

test: add unit tests for user validation

Cover edge cases for email validation and password strength.
style: format code according to prettier config
chore: update .gitignore to exclude IDE files

Integration with Validation Tools

commitlint Configuration

Validate commits with commitlint using Angular configuration:

# Install commitlint
npm install --save-dev @commitlint/cli @commitlint/config-conventional

# Create configuration
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

# Test commit message
echo 'feat(api): add new endpoint' | npx commitlint

For comprehensive commitlint configuration guidance, activate the commitlint skill:

Skill(command: "commitlint")

Pre-commit Hooks

Enforce commit message format with pre-commit hooks. For complete pre-commit setup guidance, activate the pre-commit skill:

Skill(command: "pre-commit")

Changelog Generation

Generate changelogs from Conventional Commits using semantic-release:

// release.config.js
module.exports = {
  branches: ['main'],
  plugins: [
    '@semantic-release/commit-analyzer',
    '@semantic-release/release-notes-generator',
  ],
};

Or using git-cliff:

# cliff.toml
[git]
conventional_commits = true

Benefits

From the official specification:

  1. Automatically generating CHANGELOGs - Tools parse commit history and generate release notes
  2. Automatically determining semantic version bumps - Based on commit types landed
  3. Communicating nature of changes - To teammates, public, and stakeholders
  4. Triggering build and publish processes - CI/CD pipelines react to specific commit types
  5. Making it easier for people to contribute - Through structured commit history exploration

Frequently Asked Questions

Can I use custom types?

Yes. Types beyond feat and fix are not mandated by the specification but have no implicit SemVer effect unless they include BREAKING CHANGE. Teams commonly add types like wip, deps, security.

Is the specification case-sensitive?

Implementation-defined. Most tools normalize to lowercase. Exception: BREAKING CHANGE MUST be uppercase. Best practice: be consistent within your project.

What about merge commits?

Merge commits are typically ignored by changelog generators. They do not need to follow the format.

What if I use the wrong type?

Before merging/releasing: Use git rebase -i to edit commit history After release: Depends on tools and processes Worst case: Non-conforming commit is missed by tools based on the specification

Do all contributors need to use Conventional Commits?

No. With squash-based workflows, lead maintainers can clean up commit messages when merging. Many teams configure git systems to automatically squash commits from pull requests and present a form for entering proper commit messages.

How do I handle revert commits?

Use the revert type with a footer referencing reverted commit SHAs:

revert: let us never again speak of the noodle incident

Refs: 676104e, a215868

Related Skills

Commit message validation and enforcement:

  • commitlint - Configure and use commitlint for commit message validation
  • pre-commit - Set up pre-commit hooks for automated validation

Git workflow tools:

  • git-commit-helper - Generate commit messages from git diffs
  • semantic-release - Automate versioning and changelog generation

References

Official Documentation

Related Standards

Tools and Configurations