约定式提交
约定式提交
约定式提交
概念
一种用于给提交信息增加人机可读含义的规范
为什么使用约定式提交
根据 Conventional Commits 里的说法:
- 自动化生成 CHANGELOG
- 基于提交的类型,自动决定语义化的版本变更
- 向同事、公众与其他利益关系者传达变化的性质
- 触发构建和部署流程
- 让人们探索一个更加结构化的提交历史,以便降低对你的项目做出贡献的难度
Angular 的 Conventional Commits
当然也有其他的规范,但感觉这个比较泛用
网站:https://www.conventionalcommits.org/zh-hans/v1.0.0/(有中文)
这是一个社区驱动的项目,旨在为Git提交消息制定标准。Angular遵循这个标准。
提交结构
提交说明的结构如下所示:
原文:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
译文:
<类型>[可选 范围]: <描述>
[可选 正文]
[可选 脚注]
提交说明包含了下面的结构化元素,以向类库使用者表明其意图:
- 常用
- fix: 类型 为 fix 的提交表示在代码库中修复了一个 bug(这和语义化版本中的 PATCH 相对应)。
- feat: 类型 为 feat 的提交表示在代码库中新增了一个功能(这和语义化版本中的 MINOR 相对应)。
- BREAKING CHANGE: 在脚注中包含 BREAKING CHANGE: 或 <类型>(范围) 后面有一个 ! 的提交,表示引入了破坏性 API 变更(这和语义化版本中的 MAJOR 相对应)。 破坏性变更可以是任意 类型 提交的一部分。
- 除 fix: 和 feat: 之外,也可以使用其它提交 类型 ,例如 @commitlint/config-conventional(基于 Angular 约定)中推荐的 build:、chore:、 ci:、docs:、style:、refactor:、perf:、test:,等等。
- build: 用于修改项目构建系统,例如修改依赖库、外部接口或者升级 Node 版本等;
- chore: 用于对非业务性代码进行修改,例如修改构建流程或者工具配置等;
- ci: 用于修改持续集成流程,例如修改 Travis、Jenkins 等工作流配置;
- docs: 用于修改文档,例如修改 README 文件、API 文档等;
- style: 用于修改代码的样式,例如调整缩进、空格、空行等;
- refactor: 用于重构代码,例如修改代码结构、变量名、函数名等但不修改功能逻辑;
- perf: 用于优化性能,例如提升代码的性能、减少内存占用等;
- test: 用于修改测试用例,例如添加、删除、修改代码的测试用例等。
- 脚注中除了
BREAKING CHANGE: <description>
,其它条目应该采用类似 git trailer format 这样的惯例。
其它提交类型在约定式提交规范中并没有强制限制,并且在语义化版本中没有隐式影响(除非它们包含 BREAKING CHANGE)。 可以为提交类型添加一个围在圆括号内的范围,以为其提供额外的上下文信息。例如 feat(parser): adds ability to parse arrays.。
示例
包含了描述并且脚注中有破坏性变更的提交说明
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
包含了 !
和 BREAKING CHANGE 脚注的提交说明
chore!: drop support for Node 6
BREAKING CHANGE: use JavaScript features not available in Node 6.
不包含正文的提交说明
docs: correct spelling of CHANGELOG
包含范围的提交说明
feat(lang): add polish language
包含多行正文和多行脚注的提交说明
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
如何生成对应的ChangeLog
见后文
- 官方使用效果:https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog/CHANGELOG.md
- 官方开源仓库:https://github.com/conventional-changelog/conventional-changelog
【补充】个人补充
需要注意,这里并不包括有时我们很常用的 add
、remove
、change
这种
另外如果团队没约束或不自动生成 ChangeLog 的情况下还是怎么舒服怎么来吧
启发:
另外,我们会发现这约定式提交其实还有一个特点:面向ChangeLog约定。
搞清楚了这点就会发现他的设计逻辑原理,以及搞清楚这套设定和我们平时弄的有什么实质区别。
自用更关心在自己所认为的添加,而约定式通常将用户关心的内容抽象出来。例如用户最关心的 Top3:
- feat
- fix
- BREAKING CHANGE
这几个意外的大多是用户没那么关心的。通常也不会被自动收集到ChangeLog中
【扩展】如何通过插件强制约定式提交
Husky我见过,其他目前没怎么听过
- Git Hooks
- Husky
- 一个流行的Git hooks管理工具
- lint-staged
- Commitizen
- IDE集成工具
【扩展】如何自动生成 ChangeLog
【以下内容来源GPT】
可以使用一些工作来自动生成 ChangeLog:
Conventional Changelog
一个基于Conventional Commits规范的工具,它可以生成结构化的变更日志。通常与standard-version
或semantic-release
一起使用
使用方法:
安装依赖
npm install conventional-changelog-cli --save-dev
生成Changelog
npx conventional-changelog -p angular -i -o CHANGELOG.md -s
配置文件(可选)
module.exports = { preset: 'angular', // 其他配置项... };
集成到发布流程
可以将此步骤集成到CI/CD流程中,自动在每次发布时更新Changelog
使用效果:
- 官方使用效果:https://github.com/conventional-changelog/conventional-changelog/blob/master/packages/conventional-changelog/CHANGELOG.md
- 官方开源仓库:https://github.com/conventional-changelog/conventional-changelog
Semantic Release
Semantic Release 是一个持续交付工具,它可以根据你的提交消息自动推断出新的版本号,并自动生成变更日志
Git-Release
对于简单的项目,也可以考虑使用一些轻量级的脚本或工具,如git-release
,它可以根据提交信息生成简单的变更日志
自定义脚本
#!/bin/bash
echo "# Changelog" > CHANGELOG.md
git log --format="%H %s%n%an%n%ad%n%b" --date=short --reverse | awk '
BEGIN { print "## [Unreleased]" >> "CHANGELOG.md" }
{ if ($1 ~ /^[0-9a-f]{40}$/) { printf("\n\n## [%s]", $2); next }
else if ($1 ~ /^feat/) { printf("\n- %s", $0) }
else if ($1 ~ /^fix/) { printf("\n- %s", $0) }
}
END { print "\n" >> "CHANGELOG.md" }
' >> CHANGELOG.md