持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
困境
每次写完git commit记录后,还要在不同的地方同步当前项目的进展,是不是感觉很麻烦?因为懒得去写或者在git里面复制粘贴很麻烦,所以要想办法把提交信息归纳到变更记录的文档里面,需要的时候,直接复制粘贴就好了。
在解决如何自动生成变更日志这个问题前,需要先探讨一个问题,就是如何生成规范的git提交信息?
因为在日常提交commit时,各种五花八门的提交信息会导致维护项目时难以为继,并且如果自动生成了日志,也会导致格式不统一,在汇报时也难以做相关类目的统计。
本文介绍的是目前社区提出较为通用的提交规范称为:Conventional Commits。下面就开始实战一下:
本篇文章不会详细介绍规范的内容,如果有兴趣可以自行研究相关细节。
后面会通过自动化插件来生成符合规范的commit,因此笔者认为在本文中你无需了解更多细节增加学习成本,导致概念太多看不下去。
初始化项目
快速创建一个项目并且初始化,方便后面的演示。
# 创建新的目录
mkdir changelog
# 切换到新建目录下
cd changelog
# 初始化npm项目
npm init -y
# 初始化git
git init
安装commitizen
建议不用git commit
命令填写git提交信息(因为这样容易出错,并且你有可能会忘记一些规范的要求)。而是通过commitizen
来自动生成。
commitizen
会询问一些问题,它会根据开发者的回答来生成符合Conventional Commits
标准的提交信息。
输入以下命令安装
# 安装commitizen
npm install --save-dev commitizen
# 初始化Conventional Commits规范适配器
npx commitizen init cz-conventional-changelog --save-dev --save-exact
上面介绍的适配器,只是其中一种,社区还提供了很多其它的适配器,你可以去项目页面查看。如果这些都没法满足你┓( ´∀` )┏,你也可以自己写一个。
最后一步,需要在package.json
中添加一个script
... // 此处省略其它配置
"scripts": {
..., // 此处省略其它配置
"commit": "cz"
}
... // 此处省略其它配置
此时你的package.json应该是这样的:
{
"name": "changelog",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"commit": "cz"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"commitizen": "^4.2.4",
"cz-conventional-changelog": "^3.3.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
创建.gitignore
文件,并将node_modules
添加到git忽略中
如果是mac或Linux可以运行下面指令完成:
echo "node_modules" > .gitignore
下面我们开始使用commitizen
来生自动生成commit
# 添加改动
git add .
# 运行 commitizen
npm run commit
此时你会看到下面的内容:
可选项如下:
feat
: 新的功能fix
: 修复bufdocs
: 只修改文档style
: 不影响代码含义的修改(比如:空格、格式化、添加缺少的分号等)refactor
: 重构代码(既不修复错误,也不增加功能)perf
: 提高性能test
: 添加测试或纠正现有测试build
: 影响构建系统或外部依赖的变化(如glup、npm等)ci
: ci配置文件和脚本的改变 (如:Travis、Circle)chore
: 其它不修改src或测试文件的改动revert
: 回滚之前的提交
此处选择feat
并回车。
接着需要指定变动的范围(如:某个组件、某个功能、某个文件等,此项可以跳过)
此处填写某个范围
并回车
接着需要写一个针对这次提交改动的简短描述
此处填写一个简短的描述
并回车
接着需要写一个针对这次提交改动的详细描述(可以跳过) 此处填写
一个超长的描述
并回车
接着需要确认是否有重大变更,如果有则输入y
回车后需要写具体地重大变更内容,如果没有则输入N
即可 此处输入
y
回车后填写有重大变更
并回车
接着需要确认是否与某个未关闭的issue有关联,如果有则输入y
回车后需要写具体影响的issue,如果没有则输入N
即可 此处输入
y
回车后我们填写完成 #1
此时我们可以看到,一条提交信息就自动生成完毕
通过git log
命令查看刚刚生成的内容,此时我们完成了自动化生成提交信息的功能。
使用husky+commitlint
如果你的小伙伴没有通过commitizen
生成提交信息,而是使用了git commit
命令,这个时候就需要强制检查提交信息是否符合规范。
接下来将使用+commitlint
和husky
来进行检查,执行下面的命令
# 安装 commitlint cli 以及 conventional插件
npm install --save-dev @commitlint/config-conventional @commitlint/cli
# 安装 Husky
npm install husky --save-dev
配置commitlint
新建commitlint.config.js
文件,并添加下面的内容:
module.exports = {extends: ['@commitlint/config-conventional']};
使用下面的指令,在提交commit前,检查提交信息。
# 激活husky钩子
npx husky install
# 添加husky的commit-msg钩子,在提交前对提交信息进行检查
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
可以在package.json中的scripts.prepare
中添加husky install
来确保每个使用的人在使用项目前都会激活husky
钩子。
下面来测试一下husky
是否正常工作。
输入下面的指令,将会新建一个文件,并添加到git后进行提交(如果非mac或Linux,可以自己手动创建文件)
touch new-feature
git add new-feature
git commit -m "这是一个新的改动"
可以看到,husky
很好地拦截了不符合规范的提交,并做了提示。
接下来,我们输入一个符合规范的提交
git commit -m "feat: 这是一个新的改动"
你可以看到提交成功了,此时终于把git提交信息规范化搞定了!!接下来就是最重要的自动生成日志环节:
使用release-it自动生成变更日志
在github中,新建一个名为changelog
的仓库,并且添加远程端地址:
PS: 你可以在你的git仓库中创建一个
将本地的内容先push到远程端,由于生成项目时,可能会有文件默认生成,因此加上-f
参数,强推一下master到远程端
git push --set-upstream origin master -f
接下来我们安装release-it
:
npm init release-it
一路回车,按照默认配置进行配置。初始化完成后我们需要注意以下几点:
当前不需要在npm
进行发布,因此需要在.release-it.json
中添加下面的配置,禁用npm发布:
"npm": {
"publish": false
}
为了兼容当前的提交信息格式,还需要执行下面的指令安装一个插件:
npm install @release-it/conventional-changelog --save-dev
如果想使用angular默认的changelog生成规范,只需要进行下面的配置就可以了:
"plugins": {
"@release-it/conventional-changelog": {
"preset": "angular",
"infile": "CHANGELOG.md",
"ignoreRecommendedBump": true, // 笔者希望自己选择 bump 的策略,而不是按照推荐的策略,因此将此选项打开
"strictSemVer": true // 笔者希望发布的版本号必须是 strict-semver 的版本号,因此将此选项打开
}
}
如果有兴趣,可以查阅插件文档进行更多的配置。
这里要注意一点:默认配置下,只会有feat
和fix
的提交会在changelog中显示出来(在文末会介绍如何让其他类型的提交信息也在changelog中展示出来,并且对类型标题做定制)。
插件会自动生成tag,我们需要自定义一下生成tag时的提交信息。在配置项中加入下面的配置,来完成提交信息的自定义:
"git": {
"commitMessage": "chore(tag): release v${version}"
}
先把之前的改动都提交一下,再执行release操作,指令如下:
git add .
git commit -m "feat: 添加新的功能配置"
npm run release
上图中,release-it
询问你下一个版本的版本号,此版本号的选择需要基于semver规范,你可以阅读一下规范文档。或者笔者从一篇博客中找到下面一幅图能很直观地解释区别(图片来源地址)
在这里选择patch (1.0.1)
,一路默认回车。
完成后就可以在github中看到release信息
同样你的CHANGELOG.md
文件也自动生成了
回顾一下之前提交的内容,你会发现:
- 所有
feat
类型的提交都被按照顺序归纳到了Features
下方。 - 所有的重大变更,单独被拎了出来,归纳在
BREAKING CHANGES
下方。
如果你希望定制这个Features
文案该怎么做?而且就像前文说的,目前的changelog只展示feat
和fix
,如果希望展示其它的提交,又该怎么做?
定制changelog
我们默认传入的"preset": "angular"
相当于下面的配置:
"preset": {
"name": "conventionalcommits",
"types": [
{"type": "feat", "section": "Features"},
{"type": "fix", "section": "Bug Fixes"},
{"type": "chore", "hidden": true},
{"type": "docs", "hidden": true},
{"type": "style", "hidden": true},
{"type": "refactor", "hidden": true},
{"type": "perf", "hidden": true},
{"type": "test", "hidden": true}
]
},
根据官方文档的配置指引
如果现在要让docs
类型的标题为📚文档
,feat
和fix
类型更换一下文案。
那么只要在.release-it.json
文件中,改动下面的配置即可:
"plugins": {
"@release-it/conventional-changelog": {
- "preset": "angular",
"infile": "CHANGELOG.md",
"ignoreRecommendedBump": true,
"strictSemVer": true,
+ "preset": {
+ "name": "conventionalcommits",
+ "types": [
+ {
+ "type": "feat",
+ "section": "✨新功能"
+ },
+ {
+ "type": "fix",
+ "section": "🐛问题修复"
+ },
+ {
+ "type": "docs",
+ "section": "📚文档"
+ }
+ ]
+ }
}
}
添加一个README.md
文档,并且输入以下指令,看一下配置的效果。
git add .
git commit -m "docs: 添加README.md文档"
npm run release
发版成功后,你就能在你的release内看到下面的内容:
添加的docs
类型成功显示在📚文档
的标题下。同样以此类推,你可以设置你需要显示的提交类型及其相关的标题,让你的CHANGELOG看起来更加符合你的习惯。
如果你不知道用什么emoji来表达你的类型,可以看看这个项目,给你一些启发的灵感:gitmoji.dev/
经过一番操作,终于目标达成,以后同步项目改动只需要把changelog文档丢出来,或者在该文档内复制相关内容就好啦!
本文的示例仓库地址是:github.com/zyc95/chang…