约定式提交
约定式提交 (Conventional Commits)
概述
约定式提交规范是一种基于提交信息的轻量级约定,用于给提交信息增加人机可读含义。它提供了一组简单规则来创建清晰的提交历史,更有利于编写自动化工具。
通过在提交信息中描述功能、修复和破坏性变更,使这种惯例与语义化版本 (SemVer) 相互对应。
提交信息结构
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
结构说明
- 类型 (type): 必须,表示提交的类型
- 范围 (scope): 可选,表示影响的范围
- 描述 (description): 必须,简短描述变更内容
- 正文 (body): 可选,详细描述变更原因和影响
- 脚注 (footer): 可选,用于引用问题或标记破坏性变更
提交类型
核心类型
- feat: 新功能 (对应 SemVer 的 MINOR 版本)
- fix: 修复 bug (对应 SemVer 的 PATCH 版本)
扩展类型
- build: 构建系统或外部依赖的变更
- chore: 构建过程或辅助工具的变动
- ci: CI 配置文件和脚本的变更
- docs: 文档更新
- style: 代码格式调整 (不影响代码运行的变动)
- refactor: 代码重构 (既不是新增功能,也不是修复 bug)
- perf: 性能优化
- test: 测试相关变更
破坏性变更标记
方式一:在类型后添加 !
feat!: send an email to the customer when a product is shipped
方式二:在脚注中标记
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: add user authentication system
# 修复 bug
fix: resolve memory leak in data processing
# 文档更新
docs: update API documentation
# 代码重构
refactor: simplify user validation logic
带范围的示例
# 特定模块的新功能
feat(auth): add OAuth2 support
# 特定组件的修复
fix(ui): resolve button alignment issue
# 特定工具的配置
chore(deps): update webpack to v5
带正文的示例
feat: add dark mode support
This commit introduces a new dark mode feature that allows users to switch
between light and dark themes. The implementation includes:
- Theme toggle component
- CSS variables for color schemes
- Local storage persistence
- Automatic system preference detection
Closes #123
破坏性变更示例
feat!: migrate to new API structure
BREAKING CHANGE: The API endpoints have been restructured. All existing
clients will need to update their integration code to use the new
endpoint format.
Migration guide: https://docs.example.com/migration
与语义化版本的对应关系
提交类型 | SemVer 版本 | 说明 |
---|---|---|
fix | PATCH | 修复 bug,向后兼容 |
feat | MINOR | 新功能,向后兼容 |
包含 BREAKING CHANGE 的任何类型 | MAJOR | 破坏性变更 |
工具支持
自动化工具
- commitlint: 检查提交信息格式
- conventional-changelog: 自动生成 CHANGELOG
- semantic-release: 自动版本管理和发布
配置示例
// .commitlintrc.json
{
"extends": ["@commitlint/config-conventional"],
"rules": {
"type-enum": [2, "always", ["feat", "fix", "docs", "style", "refactor", "perf", "test", "build", "ci", "chore"]]
}
}
最佳实践
- 保持一致性: 团队统一使用相同的提交类型和格式
- 简洁明了: 描述要简洁但信息充分
- 使用现在时: 提交信息使用现在时态
- 首字母小写: 描述部分首字母小写
- 避免句号: 描述末尾不加句号
- 范围明确: 使用有意义的范围标识
常见问题
Q: 如果提交符合多种类型怎么办?
A: 回退并尽可能创建多次提交,保持每次提交的单一职责。
Q: 这会阻碍快速开发吗?
A: 它阻碍的是杂乱无章的开发方式,但有助于长期的项目维护和团队协作。
Q: 所有贡献者都需要遵循吗?
A: 不一定。如果使用 squash 工作流,维护者可以在合并时清理提交信息。
语义化版本 (Semantic Versioning)
概述
语义化版本是一种版本号命名规范,通过版本号传达软件更新的性质。版本号格式为:MAJOR.MINOR.PATCH
版本号组成
MAJOR (主版本号)
- 做了不兼容的 API 修改
- 破坏性变更
- 重大重构
MINOR (次版本号)
- 新增了向下兼容的功能
- 新功能添加
- 现有功能的增强
PATCH (修订号)
- 向下兼容的问题修正
- Bug 修复
- 性能优化
版本号规则
格式规范
MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]
示例
1.0.0 # 正式版本
1.0.0-alpha.1 # 预发布版本
1.0.0+20230901 # 构建版本
版本发布原则
0.y.z 阶段
- 开发阶段,API 不稳定
- 任何版本都可能包含破坏性变更
- 不建议在生产环境使用
1.0.0 及以后
- API 稳定,遵循语义化版本规范
- 向后兼容性得到保证
- 适合生产环境使用
与约定式提交的对应
提交类型 | 版本变更 | 说明 |
---|---|---|
fix | PATCH | 修复 bug |
feat | MINOR | 新功能 |
包含 BREAKING CHANGE | MAJOR | 破坏性变更 |
版本管理策略
开发阶段
0.1.0 → 0.2.0 → 0.3.0 → 1.0.0
稳定阶段
1.0.0 → 1.0.1 → 1.1.0 → 2.0.0
工具推荐
自动化版本管理
- semantic-release: 基于提交信息自动发布
- standard-version: 生成 CHANGELOG 和版本标签
- lerna: 多包项目的版本管理
配置示例
// package.json
{
"scripts": {
"release": "semantic-release"
},
"devDependencies": {
"@semantic-release/changelog": "^6.0.0",
"@semantic-release/git": "^10.0.0",
"@semantic-release/npm": "^9.0.0"
}
}
最佳实践
- 明确变更类型: 每次发布都要明确是 MAJOR、MINOR 还是 PATCH
- 及时发布: 修复 bug 后及时发布 PATCH 版本
- 文档更新: 版本变更要同步更新文档
- 测试验证: 发布前充分测试
- 变更日志: 维护详细的 CHANGELOG
常见场景
何时发布 MAJOR 版本
- API 接口变更
- 数据库结构变更
- 配置文件格式变更
- 依赖库的重大升级
何时发布 MINOR 版本
- 新增功能
- 现有功能增强
- 新增 API 接口
- 性能优化
何时发布 PATCH 版本
- Bug 修复
- 文档更新
- 代码格式调整
- 依赖包的小版本更新