Conventional Commits
Guide to using Conventional Commits specification in AI Web Feeds
Overview
AI Web Feeds uses the Conventional Commits specification for all commit messages. This provides a structured format that enables automated changelog generation, semantic versioning, and clear project history.
Format
Each commit message consists of a header, optional body, and optional footer:
<type>(<scope>): <subject>
[optional body]
[optional footer]Header (Required)
The header has a special format that includes a type, optional scope, and subject:
<type>(<scope>): <subject>
│ │ │
│ │ └─> Summary in present tense. Not capitalized. No period at end.
│ │
│ └─> Scope: core|analytics|monitoring|nlp|cli|web|docs|tests|deps|ci|etc.
│
└─> Type: feat|fix|docs|style|refactor|perf|test|build|ci|chore|revertRules:
- Maximum 100 characters
- Type and subject are required
- Scope is recommended but optional
- Subject is lowercase, imperative mood ("add" not "added" or "adds")
- No period at the end
Commit Types
| Type | Description | Changelog Section | Example |
|---|---|---|---|
feat | New feature | Features | feat(core): add RSS feed parser |
fix | Bug fix | Bug Fixes | fix(analytics): correct topic count calculation |
docs | Documentation only | Documentation | docs(api): update fetch endpoint examples |
style | Code style/formatting (no logic change) | - | style(core): format with ruff |
refactor | Code refactoring (no feature/fix) | - | refactor(storage): simplify query builder |
perf | Performance improvement | Performance | perf(nlp): optimize embedding generation |
test | Add/update tests | - | test(validate): add edge case coverage |
build | Build system/dependencies | - | build(deps): update pydantic to 2.5.0 |
ci | CI/CD changes | - | ci(workflow): add caching for npm deps |
chore | Other changes (no src/test modification) | - | chore(release): bump version to 0.2.0 |
revert | Revert previous commit | - | revert(feat): remove experimental feature |
Scopes
Scopes indicate which part of the codebase is affected:
Core Package Scopes
core- Core functionalitymodels- Data models and schemasstorage- Database and persistenceload- Feed loading and fetchingvalidate- Validation logicexport- Export functionalityenrich- Enrichment pipelinelogger- Logging utilitiesutils- Utility functionsconfig- Configuration management
Phase-Specific Scopes
analytics- Phase 002: Analytics & Discoverydiscovery- Phase 002: Feed discoverymonitoring- Phase 003: Real-time monitoringrealtime- Phase 003: Real-time featuresnlp- Phase 005: NLP/AI featuresai- Phase 005: AI-powered features
Component Scopes
cli- Command-line interfaceweb- Web documentation siteapi- API endpoints
Infrastructure Scopes
db- Database changesschema- Schema definitionsmigrations- Database migrationsdata- Data files (feeds.yaml, topics.yaml)
Meta Scopes
docs- Documentationtests- Test infrastructuredeps- Dependenciesci- CI/CD pipelinetooling- Development toolsrelease- Release management
Examples
Feature Addition
feat(analytics): add topic trending analysis
Implement z-score based trending detection for topics with
configurable thresholds and time windows.
Closes #123Bug Fix
fix(load): handle malformed RSS feed dates
Parse dates with lenient mode and fallback to current timestamp
when feed dates are invalid or missing.
Fixes #456Documentation
docs(cli): add examples for export command
Add usage examples for JSON, OPML, and CSV export formats
with filtering options.Breaking Change
feat(api)!: redesign feed validation endpoint
BREAKING CHANGE: The /validate endpoint now returns structured
validation results instead of boolean. Update client code:
Before:
- GET /validate?url=<url> → { "valid": true }
After:
- GET /validate?url=<url> → { "status": "valid", "issues": [] }
Closes #789Multiple Scopes
feat(core,analytics): integrate embedding generation
Add sentence-transformers support for generating feed embeddings
with batch processing and caching.Body Guidelines
The body is optional but recommended for:
- Complex changes requiring explanation
- Breaking changes (required)
- Performance impacts
- Migration instructions
Format:
- Separate from header with blank line
- Wrap at 100 characters
- Use imperative mood
- Explain "what" and "why", not "how"
Footer Guidelines
Footers are optional and used for:
Issue References
Closes #123
Fixes #456, #789
Relates to #101Breaking Changes
BREAKING CHANGE: <description>Deprecations
DEPRECATED: <what is deprecated and alternative>Co-authors
Co-authored-by: Name <email@example.com>Interactive Commits with Commitizen
For interactive commit creation, use commitizen:
# Initialize (one-time setup)
npx commitizen init cz-conventional-changelog --save-dev --save-exact
# Create commits interactively
npx cz
# or
git czCommitizen will prompt you for:
- Type of change
- Scope of change
- Short description
- Longer description (optional)
- Breaking changes (optional)
- Issue references (optional)
Tools Integration
Pre-commit Hook
Conventional commits are enforced via pre-commit hook:
# .pre-commit-config.yaml
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v3.0.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]Commitlint
Validation rules are defined in commitlint.config.js:
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', ['feat', 'fix', 'docs', ...]],
'scope-enum': [2, 'always', ['core', 'analytics', ...]],
'subject-case': [2, 'never', ['sentence-case', 'start-case', ...]],
'header-max-length': [2, 'always', 100],
},
};CI/CD Validation
GitHub Actions validates commits on PRs:
# .github/workflows/ci.yml
conventional-commits:
name: Validate Conventional Commits
if: github.event_name == 'pull_request'
steps:
- name: Validate PR commits
run: |
npx commitlint --from ${{ github.event.pull_request.base.sha }} \
--to ${{ github.event.pull_request.head.sha }}Common Patterns
Feature Development
feat(scope): add new capability
feat(scope): enhance existing feature
feat(scope): implement X supportBug Fixes
fix(scope): correct incorrect behavior
fix(scope): handle edge case in X
fix(scope): prevent Y when ZRefactoring
refactor(scope): simplify X logic
refactor(scope): extract Y into separate module
refactor(scope): rename X to Y for clarityPerformance
perf(scope): optimize X operation
perf(scope): cache Y results
perf(scope): reduce memory usage in ZDocumentation
docs(scope): add X documentation
docs(scope): update Y examples
docs(scope): clarify Z behaviorValidation
Test your commit message format:
# Test with commitlint
echo "feat(core): test message" | npx commitlint
# Validate last commit
npx commitlint --from HEAD~1
# Validate range
npx commitlint --from HEAD~5 --to HEADBest Practices
✅ Good Commits
feat(analytics): add topic clustering algorithm
fix(load): handle timeout for slow RSS feeds
docs(api): add authentication examples
perf(nlp): optimize embedding batch processing
test(validate): add schema validation edge cases❌ Bad Commits
# Too vague
fix: bug fix
# Not imperative mood
feat(core): Added new parser
# Capitalized subject
feat(core): Add new parser
# Period at end
feat(core): add new parser.
# Missing scope (when appropriate)
feat: add trending analysis
# Wrong type
feat(core): fix typo in READMEChangelog Generation
Conventional commits enable automated changelog generation:
# Generate changelog
npx standard-version
# Preview next version
npx standard-version --dry-run
# First release
npx standard-version --first-releaseResources
FAQ
Why conventional commits?
- Automated Changelog: Generate release notes automatically
- Semantic Versioning: Determine version bumps (major/minor/patch)
- Clear History: Understand changes at a glance
- Better Collaboration: Consistent format across team
- Tooling Integration: Enable automation and analysis
What if I forget the format?
Use commitizen for interactive prompts:
npx czOr refer to this guide!
Can I use multiple scopes?
Yes, separate with commas:
feat(core,cli): add new export formatWhat about merge commits?
Merge commits follow the same format:
Merge pull request #123 from feature-branch
feat(analytics): add trending detectionHow do I indicate breaking changes?
Three ways:
!after scope:feat(api)!: redesign endpoint- Footer:
BREAKING CHANGE: description - Both (recommended for visibility)
Support
For questions or issues with conventional commits:
- Check this documentation
- Review commitlint.config.js
- Open an issue on GitHub