本文主要解决以下问题:
- 如何使用工具生成符合Angular commit规范的message?
- 如何通过gitHoos验证message是否符合规范?
- 如何使用工具自动生成changelog?
如果你想了解更详细的过程,请认真往下阅读;如果你想快速查看如何使用,请看『总结』目录。
前言
在一个多人协作的项目中,简洁清晰易懂的代码提交注释是能够快速定位问题的有效方式。commit message应该说明本次提交的目的。
对比下面这两张代码提交commit log图:
第一张:message没有实际的意义,看不出来本次提交改动的范围。
第二张:message简洁清晰易懂,可以看出当前是新增功能、修复问题等,并可看出此次提交影响的范围。
通过上面两张图可以看出,message写的符合规范是多么的重要!
那我们在日常工作中,仅仅通过人工去输入message,无法完全保证message提交的规范性。
接下来介绍一种社区比较流行的规范Angular 规范,并且通过工具去生成符合这种规范的message信息。
Angular commit规范
规范格式概览
<type>(<scope>): <subject> #header部分
// 空一行
<body>
// 空一行
<footer>
复制代码
Header 是必需的,Body 和 Footer 可以省略。
规范格式详解
Header
Header部分只有一行,包括三个字段:type(必需)、scope(可选)和subject(必需)。
type
用于说明本次commit的类型
只允许使用下面7个标识
- feat:新功能(feature)
- fix:修补bug
- docs:文档(documentation)
- style: 格式(不影响代码运行的变动)
- refactor:重构(即不是新增功能,也不是修改bug的代码变动)
- perf: 性能提升(提高性能的代码改动)
- test:测试
- build:构建过程或辅助工具的变动(webpack等)
- ci:更改CI配置文件和脚本
- chore:不修改src或测试文件的其他更改
- revert:撤退之前的commit
如果type为feat、fix、perf、revert,则该 commit 将肯定出现在 Change log 之中。其他情况(docs、chore、style、test)由你决定,要不要放入 Change log,建议是不要。
scope
用于说明本次commit影响的范围,比如首页、详情页等。
subject
用于说明本次commit的简短描述,不超过50个字符。
Body
用于本次commit的详细描述,可以分成多行
举例(实际应用应说明具体改动):
more info...
- first changes...
- second changes...
复制代码
Footer
只用于下面两种情况
不兼容变动
如果当前代码与上一个版本不兼容,则 Footer 部分以BREAKING CHANGE开头,后面是对变动的描述、以及变动理由和迁移方法。
举例:
vue-next changelog.md:github.com/vuejs/vue-n…
BREAKING CHANGE: `getTextMode` compiler option signature has changed from
``ts
(tag: string, ns: string, parent: ElementNode | undefined) => TextModes
``
to
``ts
(node: ElementNode, parent: ElementNode | undefined) => TextModes
``
复制代码
关闭Issue
如果当前 commit 针对某个issue,那么可以在 Footer 部分关闭这个 issue 。
Closes #123, #234
复制代码
Revert(可忽视)
还有一种特殊情况,如果当前 commit 用于撤销以前的 commit,则必须以revert:开头,后面跟着被撤销 Commit 的 Header。
revert: feat(pencil): add 'graphiteWidth' option
This reverts commit 667ecc1654a317a13331b17617d973392f415f02.
复制代码
Body部分的格式是固定的,必须写成This reverts commit .,其中的hash是被撤销 commit 的 SHA 标识符。
如果当前 commit 与被撤销的 commit,在同一个发布(release)里面,那么它们都不会出现在 Change log 里面。如果两者在不同的发布,那么当前 commit,会出现在 Change log 的Reverts小标题下面。
Commitizen 生成message工具
Commitizen是一个撰写合格 Commit message 的工具。
全局安装commitizen
npm install -g commitizen
复制代码
项目初始化commitizen
在项目目录里,运行下面的命令,使其支持 Angular 的 Commit message 格式
// 使用npm包cz-conventional-changelog进行初始化
commitizen init cz-conventional-changelog --save --save-exact
复制代码
执行完上述命令后,会往package.json
文件中的devDependencies
中加入cz-conventional-changelog
包,并且自动增加config
配置项,如下:
"devDependencies": {
"cz-conventional-changelog": "^3.3.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
复制代码
之后,凡是用到git commit
命令,一律改为git cz
。这时就会出现选项,用来生成符合格式的commit message。
我们也可以在package.json
文件中的script
中配置命令:
"scripts": {
...
"commit": "git cz"
},
复制代码
之后在执行git commit
时,直接运行npm run commit
即可!
完整版生成message示例
如果想生成Breaking changes
,请在Are there any breaking changes?
的时候选y
gitHooks验证message规范性
请戳快速了解Vue如何添加git hooks钩子(pre-commit、commit-msg)
生成changelog
介绍
如果你的所有commit都符合Angular commit规范
,那么发布新版本时,就可以通过脚本自动生成changelog。
生成的changelog文档包括以下几个部分:
- Features(对应type: feat)
- Bug Fixes(对应type: fix)
- Code Refactoring (对应type: refactor且breaking changes为y)
- Performance Improvements(对应type: perf)
- Reverts (对应type: revert)
- BREAKING CHANGES (显示body中为BREAKING CHANGES的内容)
每个部分都会罗列相关的 commit ,并且有指向这些 commit 的链接。当然,生成的文档允许手动修改,所以发布前,你还可以添加其他内容。
conventional-changelog
用来生成changelog的工具
安装
npm install -g conventional-changelog
复制代码
生成changelog
使用下述命令可生成changelog:
conventional-changelog -p angular -i CHANGELOG.md -s
复制代码
上面命令不会覆盖以前的 Change log,只会在CHANGELOG.md的头部加上自从上次发布以来的变动。
如果你想生成所有发布的 Change log,需要运行下面的命令:
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
复制代码
为了方便使用,可以将其写入package.json
的scripts
字段。
{
"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
}
}
复制代码
以后,直接运行下面的命令即可。
npm run changelog
复制代码
示例
1. commit log如图:
2. 生成的changelog如图:
总结
1. 生成message
npm install -g commitizen
// 切换至项目目录
commitizen init cz-conventional-changelog --save --save-exact
// 命令行执行git cz生成commit message
git cz // 或者package.json配置`scripts`
复制代码
2. 验证message规范性
// 安装lint-staged
npm install lint-staged --save-dev
// package.json
"gitHooks": {
"pre-commit": "lint-staged",
"commit-msg": "node build/verify-commit-msg.js"
},
"lint-staged": {
"*.{js,vue}": [
"vue-cli-service lint",
"git add"
]
}
// verify-commit-msg.js
const chalk = require("chalk");
const msgPath = process.env.GIT_PARAMS;
const msg = require("fs")
.readFileSync(msgPath, "utf-8")
.trim();
const commitRE = /^(build|chore|ci|docs|feat|fix|wip|perf|refactor|revert|style|test|temp|)(\(.+\))?: .{1,50}/;
// 根据正则表达式校验提交的message是否符合团队规范
if (!(commitRE.test(msg) || msg.indexOf("Merge") === 0)) {
console.error(
` ${chalk.bgRed.white(" ERROR ")}
[${chalk.red(msg)}] 是 ${chalk.red("无效的提交消息格式")}
${chalk.red("自动生成更新日志需要正确的提交消息格式 例如:")}
${chalk.green("issue-1 feat(模块): 预发布环境增加 A 模块")}
${chalk.green("issue-2 fix(文案): 修复错误文案")}`
);
// 以非0值退出,放弃提交
process.exit(1);
}
复制代码
3. 生成changelog
// 安装
npm install -g conventional-changelog
// 生成全部changelog
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
// 生成自上次版本号变更以来changelog
conventional-changelog -p angular -i CHANGELOG.md -s
复制代码
常见问题
1. gitHooks钩子验证时,仅可保留下述方式的其中一种:
.git/hoos/
目录下,去掉.sample
后缀后生效的钩子,如
package.json
中通过gitHoos
定义的钩子,可自定义通过npm包或者js文件去校验
2. 每一次版本发布记得修改package.json中的version版本,生成changelog需根据版本号去生成