自动生成changelog
使用版本自动化工具(standard-version)及辅助提交工具(commitizen)
一、首先是commitizen的安装及使用
安装及配置
- 安装commitizen:
npm install commitizen -D
- 设置 changelog adapter适配器:
commitizen init cz-conventional-changelog -D --save-exact
上面的命令做了三件事: 安装 cz-conventional-changelog 适配器 npm 模块 将其保存到package.json的dependencies或devDependencies 将config.commitizen密钥添加到文件的根目录,package.json如下所示:
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
- 在 package.json,中增加如下脚本 :
"scripts": {
"commit" : "git-cz"
}
使用
- 首先我们先把更改的代码通过git add添加到本地缓存区;
- 运行npm run commit
二、standard-version的安装及使用
安装及配置
- 安装standard-version :
npm install standard-version -D
- 在 package.json,中增加如下脚本 :
"scripts": {
"release": "standard-version"
}
- 自定义配置
首先在项目的根目录下创建一个名为 .versionrc 或 .versionrc.json 或 .versionrc.js的文件(注意:如果您使用 .versionrc.js默认导出,则必须是配置对象或返回配置对象的函数)以下配置以.versionrc.js为例:
module.exports = {
// 文件输出路径
infile: 'docs/changelog/v4.0.1.md',
// 跳过
skip: {
bump: true, // 取得当前版本(比如package.json里面的version字段,这里我们定义了packageFiles,所以会从packageFiles.filename取),升版本:1.0.0 => 1.1.0 或者 1.0.0 => 2.0.0等(如何升级可以由参数控制)
changelog: false, // 自动产出changelog文档
commit: true, // 提交变动
tag: true // 在git中增加tag标识
},
// types为Conventional Commits标准中定义,目前支持https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional
// "type" commit 类型
// "section" 不同的 commit 类型所在 CHANGELOG.md 中的区域
// "hidden" 是否在 CHANGELOG.md 中显示
types: [
{ type: "feat", section: "新特性", hidden: false },
{ type: "fix", section: "Bug修复", hidden: false },
{ type: "docs", section: "文档", hidden: false },
{ type: "chore", section: "配置项", hidden: false },
{ type: "style", section: "格式", hidden: false },
{ type: "refactor", section: "重构", hidden: false },
{ type: "perf", section: "性能", hidden: false },
{ type: "test", section: "测试", hidden: false },
{ type: "build", section: "构建", hidden: false },
{ type: "ci", section: "CI", hidden: false },
{ type: "revert", section: "回滚", hidden: false },
],
// 对比版本的url
compareUrlFormat: "{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}",
// hash链接(commit的连接,例如:https://git.yoururl.com/blank91/ui/commit/f91dcfdebf89be24f550ccbbd8c4f03029b44812)
commitUrlFormat: "{{host}}/{{owner}}/{{repository}}/commit/{{hash}}",
//issue链接
issueUrlFormat: "http://yourissue/browse/RDC-{{id}}",
// 用于检测对问题的引用的前缀数组(必须有此项才会在changelog中显示bug连接,我们用的是jira)
issuePrefixes: ["RDC-"],
//server-version自动commit的模板
releaseCommitMessageFormat: "build: {{currentTag}}版本发布",
// 识别的tag前缀
'tag-prefix': 'rb',
// 预发版前缀
prerelease: "dev",
bumpFiles: [
{
filename: "version.json",
// The `json` updater assumes the version is available under a `version` key in the provided JSON document.
type: "json", // 也可以是 "plain-text", The `plain-text` updater assumes the file contents represents the version.
},
],
//需要server-version更新版本号的文件
packageFiles: [
{
filename: "version.json",
// The `json` updater assumes the version is available under a `version` key in the provided JSON document.
type: "json",
},
]
}
然后,由于我们配置了bumpFiles和packageFiles,所以我们还需要在根路径下创建一个version.json(如果配置中的type类型以是plain-text,则是version.txt)的文件,文件内容如下:
{
"version": "4.0.2"
}
注意: 如果是预发版就是"4.0.2-dev.0"(根据配置项中预发版前缀prerelease来定),不要前缀!
在我们自己的项目中是否适用?
我们的tag是自定义的,如: v4.0.0.rb13,但是standard-version只能识别最后几位是正常版本号的情况,如:v4.0.0。
解决方案:standard-version可以识别自定义的前缀,所以我们可以通过tag号的前缀来区分不同的项目。
默认情况下, standard-version只识别以v开头的tag,比如v1.0.0,识别自定义的前缀有如下两种方法:
- 通过以下命令
npx standard-version –t rb
或者
npm run release -- -t rb
注意: 通过脚本npm执行一定要注意两个横杠!
以上命令识别是以rb开头的tag号,如rb1.0.0
- 通过更改.versionrc配置文件
{
'tag-prefix': 'rb-v’
}
正常使用流程
- 首先是信息确认:
- .versionrc 配置文件信息确认,主要是infile、tag-prefix、packageFiles、bumpFiles;
- 已存在此前缀的tag
- 假如当前最后一个tag号为rb4.0.2,且目前已完成rb4.0.3的初步开发,打算预发布一版rb4.0.3-dev.0
npm run release -- --release-as patch --prerelease
结果:会生成rb4.0.2...rb4.0.3-dev.0之间changelog
- 若想再发布一个预发版:rb4.0.3-1,还是执行上述命令
npm run release -- --release-as patch --prerelease
结果:会生成rb4.0.2...rb4.0.3-dev.1之间changelog
- 当rb-v4.0.3要发最终版时
npm run release -- --release-as patch
结果:会生成rb4.0.2...rb4.0.3之间changelog
特殊情况下的使用
场景: 假如已经开发完rb4.0.1和rb4.0.2,并且已经开发了部分rb4.0.3,但是我还没生成rb4.0.1的changelog,并且我tag的命名方式是非标准的,比如:v4.0.1.rb1,我要如何生成rb4.0.1的changelog?
注意 前提: 此时还没有比 要生成日志的版本 大的版本号!详细请看 为什么要这么解决?同时也是standard-version获取changelog区间的原理
方案:
- 首先先打我们需要的命名格式的tag:先找到rb4.0.1最终版的commit_id,然后
# 命令 git tag <tagName> [commit_id]
git tag rb4.0.1 fef4b460c
- 找到rb4.0.2最终版的commit记录,基于此提交切出一个分支,此分支的最后一次提交记录也就是rb4.0.2的最终版的最后一次提交记录,在此分支上,执行
npm run release -- --release-as patch
效果图
为什么要这么解决?同时也是standard-version获取changelog区间的原理
首先匹配前缀(tag-prefix),如:'rb’
- previousTag:匹配符合规则的最后一个tag号,比如我们要求的前缀是rb,此时有v4.0.0、rb4.0.0、v4.0.1这么几个tag号,此时匹配到的就是rb4.0.0
- currentTag:显示的号是packageFiles中的版本号根据命令--release-as增加之后的版本号,比如:packageFiles文件中的version为4.0.0(如下"packageFiles配置"),若此时增主版本号(npm run release -- --release-as major),则此时currentTag为5.0.0;实际生成的是当前分支的最后一次提交记录,此时tag5.0.0还未生成,可以在配置项中添加配置自动生成tag,配置如下(.versionrc.js配置)
注意这里有个坑:如果你的previousTag和currentTag是一样的话,那就没有changelog
// packageFiles配置
{
"version": "4.0.0"
}
// .versionrc.js配置
{
skip: {
tag: false
}
}
常用配置
- -r, --release-as 手动指定发布类型(像npm的version类型) <major|minor|patch>
- -t, --tag-prefix 为要创建的git标记设置一个自定义前缀 [字符串] [默认值: "v"]
- -p, --prerelease 使用可选选项值进行预发布,以指定标记id [字符串]
所有配置请通过npx standard-version --help查询 或 查看官网