自动生成changelog

1,673 阅读5分钟

自动生成changelog

使用版本自动化工具(standard-version)及辅助提交工具(commitizen)

一、首先是commitizen的安装及使用

安装及配置

  1. 安装commitizen:
 npm install commitizen -D
  1. 设置 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"
  }
} 
  1. 在 package.json,中增加如下脚本 :
"scripts": { 
  "commit" : "git-cz" 
}

使用

  1. 首先我们先把更改的代码通过git add添加到本地缓存区;
  2. 运行npm run commit

image.png

二、standard-version的安装及使用

安装及配置

  1. 安装standard-version :
npm install standard-version -D
  1. package.json,中增加如下脚本 :
"scripts": {
  "release": "standard-version"
}
  1. 自定义配置

首先在项目的根目录下创建一个名为 .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,识别自定义的前缀有如下两种方法:

  1. 通过以下命令
npx standard-version –t rb
或者
npm run release -- -t rb 

注意: 通过脚本npm执行一定要注意两个横杠

以上命令识别是以rb开头的tag号,如rb1.0.0

  1. 通过更改.versionrc配置文件
{
  'tag-prefix': 'rb-v’
}

正常使用流程

  1. 首先是信息确认:
  • .versionrc 配置文件信息确认,主要是infile、tag-prefix、packageFiles、bumpFiles;
  • 已存在此前缀的tag
  1. 假如当前最后一个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

  1. 若想再发布一个预发版:rb4.0.3-1,还是执行上述命令
npm run release -- --release-as patch --prerelease

结果:会生成rb4.0.2...rb4.0.3-dev.1之间changelog

  1. 当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区间的原理

方案:

  1. 首先先打我们需要的命名格式的tag:先找到rb4.0.1最终版的commit_id,然后
# 命令 git tag <tagName> [commit_id]
git tag rb4.0.1 fef4b460c
  1. 找到rb4.0.2最终版的commit记录,基于此提交切出一个分支,此分支的最后一次提交记录也就是rb4.0.2的最终版的最后一次提交记录,在此分支上,执行
npm run release -- --release-as patch

效果图

image.png

为什么要这么解决?同时也是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查询 或 查看官网