关于cicd:自动产出changelog第二节自动产出

75次阅读

共计 10559 个字符,预计需要花费 27 分钟才能阅读完成。

背景

接上一篇《主动产出 changelog- 第一节:标准提交代码》调研的后续,本文将基于 angular.js 格局 的提交内容围绕自动化产出进行后续调研。钻研的方向为产出内容的工具是否反对各种自定义个性,是否帮忙咱们实现团队的格调及自动化过程中的一些问题。

简述

在调研的过程中大量的文章都会举荐应用 conventional-changelog/conventional-changelog 进行 changelog 的产出,而其余蕴含更丰盛性能的库背地应用的仍旧是这个工具进行内容的产出。其作者还制作了 conventional-changelog/standard-version 和 conventional-changelog/standard-release 两套性能更为丰盛的工具供咱们应用,standard-release 具备一个标准的应用前提,所以这个标准并不合乎咱们团队的状况,下文探讨将围绕 standard-version 进行。而另一个工具叫 release-it/release-it 的近三年比 conventional-changelog 更沉闷,具体抉择哪个工具好?上面将给出参考。

standard-version

我的项目装置

$ npm i --save-dev standard-version

package.json 加上上面这段内容后,调用 npm run release 应用

{
  "scripts": {"release": "standard-version"}
}

全局装置

$ npm i -g standard-version # 应用 standard-version

间接应用

$ npx standard-version

调用 standard-version 后会输入以下内容:

$ npx standard-version
√ bumping version in package.json from 0.2.0 to 0.2.1
√ bumping version in package-lock.json from 0.2.1 to 0.2.1
√ outputting changes to CHANGELOG.md
√ committing package-lock.json and package.json and CHANGELOG.md
√ tagging release v0.2.1
i Run `git push --follow-tags origin master && npm publish` to publish

standard-version 会为咱们做以下行为:

  1. 缓存以后文件变动
  2. 将历史回退至最初一个 git 标签的地位(查看 package.json 中提供的信息来定位 git 标签)
  3. 更新版本号
  4. 产出 changelog 文件
  5. 提交变动
  6. 打上新版本的 git-tag

产出的 changlog 长这个样子:

# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### 0.2.1 (2021-04-09)


### Features

* 首次化 ([9d06990](http://gogs.infzm.com:22403///commit/9d06990aa9d4c82acfe4b0fd9c28c65dbdd89715))
* 减少逻辑 ([e8667aa](http://gogs.infzm.com:22403///commit/e8667aa136bec4836765deb31b60a76c48cad017))
* 新增一行输入 ([c747a34](http://gogs.infzm.com:22403///commit/c747a347d2d53430c676b296bb2c06aacc4de937))

预览操作行为(不会理论执行),可应用 --dry-run 尝试操作:

$ npx standard-version --dry-run

到这步都是应用默认的形式进行,前面开始探讨自定义内容。

自定义

下面产出的 changelog 内容并不是每个团队都认可的,必然存在须要改变的冀望;其次还有在 CI/CD 工具中须要配合其余工具一并应用,对于 standard-version 丰盛的性能是否跳过也是一个重要的考量;最初一个是起自动更新版本号,版本号具备肯定的语意(具体参考这篇文章《应用 npm 命令行更新版本号》),是否反对更细化的管制,就是另一个重要的考量了。

所以最初须要弄清楚:

  • 是否自定义产出的 changelog 内容?能做何种水平的自定义呢?
  • 是否跳过一些 standard-version 提供的行为呢?
  • 是否自定义更新版本号呢?
自定义产出 Changelog 内容

官网文档中提到,要自定义配置能够抉择两种形式,写在 package.json 外面,或是令建一个 .versionrc 文件。standard-version 将会在这两处取得配置内容。上面选用独立文件的配置形式进行阐明。

创立 .versionrc 文件

$ touch .versionrc

.versionrc 内容为 JSON 格局,影响 changelog 产出设置的配置内容蕴含以下这些:

配置项 类型 形容
header String,字符串,反对 ’\n’ 文档的头部内容,默认值为:’# Changelog\n\nAll notable changes to this project will be documented in this file. See standard-version for commit guidelines.\n’
types Array, type 对象数组 用于配置输入的内容。type 对象蕴含:type 对应 commit 录入中的 type;section 展现的文字内容;hidden 是否暗藏;例子:{"type": "feat", "section": "Features", "hidden": false}
preMajor Boolean,布尔值 用于管制是否显示 1.0.0 版本之前的 changelog。
commitUrlFormat String,字符串 提交内容可拜访地址,默认:{{host}}/{{owner}}/{{repository}}/commit/{{hash}}
compareUrlFormat String,字符串 两个提交比照的可拜访地址,默认:{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}
issueUrlFormat String,字符串 发问内容地址,默认:{{host}}/{{owner}}/{{repository}}/issues/{{id}}
userUrlFormat String,字符串 提交人可拜访的地址,默认:{{host}}/{{user}}
releaseCommitMessageFormat String,字符串 用于格式化主动生成的公布落实音讯的字符串。
issuePrefixes Array<String> or String,字符串或者字符串数组 用于检索发问内容的标识,如:#39;默认是:['#']

格局文档来自这里:《Conventional Changelog Configuration Spec (v2.1.0)》,下面用到的模板变量(如:{{host}})在后面格局文档最初有提交。

整合到文件内容如上面例子:

{
    "header":"# 更新历史 \n\n",
    "types": [{"type": "feat", "section": "✨ Features | 新性能"},
        {"type": "fix", "section": "🐛 Bug Fixes | Bug 修复"},
        {"type": "perf", "section":"⚡ Performance Improvements | 性能优化"},
        {"type": "revert", "section":"⏪ Reverts | 回退"},
        {"type": "chore", "section":"📦 Chores | 其余更新"},
        {"type": "docs", "section":"📝 Documentation | 文档"},
        {"type": "style", "section":"💄 Styles | 格调", "hidden": true},
        {"type": "refactor", "section":"♻ Code Refactoring | 代码重构"},
        {"type": "test", "section":"✅ Tests | 测试"},
        {"type": "build", "section":"👷‍ Build System | 构建"},
        {"type": "ci", "section":"🔧 Continuous Integration | CI 配置"}
    ]
}

通过这个配置产出的文档内容如下:

# 更新历史 


## 0.2.0 (2021-04-12)


### 🔧 Continuous Integration | CI 配置

* 减少 CI 反对 ([a2c8ced](https://github.com/lpreterite/datagent/commit/a2c8ced34e83d06b01fa068c0f94b2916f1baf76))
* 更新版本号 ([f445127](https://github.com/lpreterite/datagent/commit/f4451270a124aacd105bcdc6fd28df4eb7f5be20))


### 📝 Documentation | 文档

* 更新 CHANGELOG 文件 ([6146cfa](https://github.com/lpreterite/datagent/commit/6146cfa0e9149f1dbd94dd135d79dd36441cf327))
* 更新文档 ([cd214b8](https://github.com/lpreterite/datagent/commit/cd214b87db3362f8a198a03941dc6e0f52a05d6b))
* 更新文档 ([c9dd688](https://github.com/lpreterite/datagent/commit/c9dd688f9f3f76b1d3068cb8ea73ee50dbe6229e))


### ⚡ Performance Improvements | 性能优化

* 更新代码 ([b45cfed](https://github.com/lpreterite/datagent/commit/b45cfedea4b695a9684f488f62188080b75e69a6))


### ✨ Features | 新性能

* 首次化 ([9d06990](https://github.com/lpreterite/datagent/commit/9d06990aa9d4c82acfe4b0fd9c28c65dbdd89715))
* 减少逻辑 ([e8667aa](https://github.com/lpreterite/datagent/commit/e8667aa136bec4836765deb31b60a76c48cad017))
* 新增一行输入 ([c747a34](https://github.com/lpreterite/datagent/commit/c747a347d2d53430c676b296bb2c06aacc4de937))


### 👷‍ Build System | 构建

* 更新依赖 ([fb5d568](https://github.com/lpreterite/datagent/commit/fb5d568de59ccf43cb2ccecc3acc95add07999a6))
* 更新本地设置 ([6665709](https://github.com/lpreterite/datagent/commit/66657097b5592228e93e7f3865b53ab80cc5610a))


### 📦 Chores | 其余更新

* 更新 cz-config 配置用于反对 vscode 插件配置 ([2a726a4](https://github.com/lpreterite/datagent/commit/2a726a471a12c5323a6ce5707a703f7e1af35927))
* 更新 package ([eda4316](https://github.com/lpreterite/datagent/commit/eda4316722a9d03f2fd5e60f61507a6e272ddc1b))
* 更新版本至 0.2.0 ([397e19c](https://github.com/lpreterite/datagent/commit/397e19c09e6c932b594e225c00a9018e1627e764))
* 移除 cz-conventional-changelog 配置 ([5b8cd88](https://github.com/lpreterite/datagent/commit/5b8cd88d11d1e0a3db4cc888d9115ef579937aae))

这里根本满足大部分团队对 Changelog 自定义的性能,如果还须要更深刻的个性化操作,能够基于 conventional-changelog-conventionalcommits 这个插件 templates 目录中的模板文件,而后在应用时设置 –preset 指向改变后的预设我的项目来满足自定义需要。反正我找了一圈官网提供的内容都没有找到更好的配置办法,突破口也是从 standard-version --help 中看到,再配合掘金网友提供的材料 (vue-cli-plugin-commitlint) 能力晓得门道。当然可能存在封装好能帮忙解决自定义问题的仓库,那位敌人晓得更具体的多谢告知一下,我后续会再欠缺这篇文章。

跳过特定流程

standard-version 工作流程蕴含几个环节,其实每个环节都可抉择跳过,具体能够在.versionrc 文件中减少配置来实现:

{
    "skip": {
        "bump": true, // 缓存变动,并重置 git 状态至最近的 tag 节点
        "changelog": true, // 主动产出 changelog 文档
        "commit": true, // 提交变动
        "tag": true // 在 git 中减少 tag 标识
    }
}

也能够通过命令行来实现:

$ npx standard-version --skip.changelog false
自定义提交
$ npx standard-version --message '%s 版本更新'

%s内容会被替换为以后的版本号。

吐槽一下,官网命令行提醒说 –message 已淘汰,倡议应用 releaseCommitMessageFormat。可是在其代码中却没找到 releaseCommitMessageFormat 这个选项的反对。代码传送门

指定语义化版本

这里有三个命令帮忙咱们解决问题:

  • --first-release 首次公布操作。这步操作并不会递进版本号。npx standard-version --first-release
  • --prerelease 预公布操作。npx standard-version -- --prerelease 版本会从 0.2.0 变为 0.2.0-0;npx standard-version -- --prerelease alpha能够减少前序,版本会从 0.2.0 变为 0.2.0-alpha.0。
  • --release-as 指定公布操作。npx standard-version -- --release-as minor 版本从 0.2.0 变为 0.3.0。

流程钩子

standard-version 在流程上更进一步的自定义管制,它提供了流程的执行前后的钩子设置,可用于运行命令行。比方 standard-version 不反对自定义的 issues 地址(见 issue#48),可通过在产出 changelog 后运行命令行进行替换。

{
    "standard-version": {
        "scripts": {"postchangelog": "replace'MY GITHUB URL''MY JIRA URL' CHANGELOG.md"}
    }
}

具体还有比拟多的其余钩子就不细说了,官网文档有具体阐明(见 #signing-commits-and-tags),这里只提供一个思路。

小结

总的来说 standard-version 还是能满足需要的达成生成 changelog 的工作。因为它是一个较老的我的项目了,团队主力都去保护 standard-release,对于standard-version 将来性能的改善推动效率不会太高。评估就是 能用

release-it

在扒完 standard-version 的源码后,对于前端我的项目的公布工程流程环节有了更深的理解。基于这样的背景下再学习 release-it 这个工具感觉,它真的是简略易懂。release-it 自身是交互式的工具,而下文探讨内容围绕着在 CI/CD 工具 内容运作,带上 –ci 参数就能进入静默模式。

装置

# 全局装置
$ npm i -g release-it

# 我的项目装置
$ npm i -D release-it

# 间接应用
$ npx release-it

release-it 具体的工作流程:

  • 同步远端内容
  • 更新版本号
  • 产出 changelog
  • 提交变动
  • 减少 git tag
  • 推送 tag 更新至远端

通过 --dry-run 更能看到具体的行为:

$ npx release-it --dry-run --ci

# 上面是执行过程
$ git diff --quiet HEAD
$ git rev-parse --abbrev-ref HEAD
$ git config --get branch.master.remote
$ git remote get-url origin
! git fetch
$ git describe --tags --match=* --abbrev=0
$ git symbolic-ref HEAD
$ git for-each-ref --format="%(upstream:short)" refs/heads/master
! git log --pretty=format:"* %s (%h)"
�🚀 Let's release git-flow-test (0.2.0...0.2.1)
Empty changelog
! npm version 0.2.1 --no-git-tag-version
$ git status --short --untracked-files=no
Empty changeset
! git add . --update
! git commit --message Release 0.2.1
! git tag --annotate --message Release 0.2.1 0.2.1
$ git symbolic-ref HEAD  [cached]
$ git for-each-ref --format="%(upstream:short)" refs/heads/master  [cached]
! git push --follow-tags
�🏁 Done (in 2s.)

release-it 反对更多的自动化操作,包含:公布至 npm、更新 github release,或是 gitlab 相干的反对都有,这里流程只关注 git 仓库相干的就不细说了。

自定义

探讨的方向仍旧是那几样:

  • 是否反对自定义 changlog 格局?
  • 是否反对跳过特定流程?
  • 是否反对自定义版本?

release-it 反对内容不像 standard-version 文档及配置散布在各个我的项目上,在其我的项目的 release-it.json 文件中已蕴含全副配置内容。

自定义 changelog

release-it 默认产出 changelog 办法是:git log --pretty=format:\"* %s (%h)\" ${from}...${to},能够在 release-it.json 文件第 4 行中看到。而须要按 angular 提交内容格局产出 changelog 则须要配置 release-it/conventional-changelog 插件进行设置。具体设置如下:

# .release-it.json
{
    "plugins": {
      "@release-it/conventional-changelog": {
        "infile": "CHANGELOG.md",
        "preset": {
          "name": "conventionalcommits",
          "header":"# 📋 更新历史 \n\n",
          "types": [{"type": "feat", "section": "✨ Features | 新性能"},
              {"type": "fix", "section": "🐛 Bug Fixes | Bug 修复"},
              {"type": "perf", "section":"⚡ Performance Improvements | 性能优化"},
              {"type": "revert", "section":"⏪ Reverts | 回退"},
              {"type": "chore", "section":"📦 Chores | 其余更新"},
              {"type": "docs", "section":"📝 Documentation | 文档"},
              {"type": "style", "section":"💄 Styles | 格调", "hidden": true},
              {"type": "refactor", "section":"♻ Code Refactoring | 代码重构"},
              {"type": "test", "section":"✅ Tests | 测试"},
              {"type": "build", "section":"👷‍ Build System | 构建"},
              {"type": "ci", "section":"🔧 Continuous Integration | CI 配置"}
          ],
          "commitUrlFormat":"https://github.com/lpreterite/datagent/commit/{{hash}}"
        }
      }
    }
}

值得注意的是 release-it/conventional-changelog 也是用 conventional-changelog 作为 changelog 产出外围。最终配置的格局还是和 conventional-changelog 一样。

这里不晓得为何 header 没有失效。

跳过特定流程

配置总体分为 4 个局部:git、npm、github、gitlab。默认开启 git 和 npm 环节性能。要跳过特定流程只须要在配置加上就能够了,比方上面配置将不执行 npm 环节的解决:

# .release-it.json
{
    "npm":{"publish":false}
}

在命令行传入能够这样应用:

$ npx release-it --no-npm.publish

某些配置是布尔值的,能够加上 no- 前缀将其值设置为false

git 环节局部还可细分为:

  • 提交变动 commit
  • 创立标签 tag
  • 推送至远端 push

如不须要推送至远端的行为能够在配置减少上面的内容:

# .release-it.json
{
    "git":{"push":false}
}

或是在执行命令加上

$ npx release-it --no-git.push

具体细节倡议查看 .release-it.json 配置文件,或是细读官网指南。

自定义提交内容

这个性能对于 CI/CD 工具来说是比拟重要的一环就独自拿出来说了,比方我应用的 CI/CD 工具 drone.io,把 [CI SKIP] 写在提交内容就能让它防止在主动解决管道内造成循环提交的问题。

在 release-it 中能够这样配置:

# .release-it.json
{
    "git":{"commitMessage": "ci: 更新版本至 ${version} | [CI SKIP]"
    }
}

在执行命令中能够这样写:

$ npx release-it --ci --git.commitMessage="ci: 更新版本至 ${version} | [CI SKIP]"
指定语义化版本

与 standard-version 不同,release-it 设计更贴近 npm version 命令,应用起来比拟容易了解。比方公布重大更新:

$ npx release-it major --ci

# 版本号从 0.2.0 变为 1.0.0

预公布局部因为整合了好几个性能在一个配置,这里须要特别强调一下:

# 整合起来的命令
$ npx release-it major --preRelease=beta

# 理论执行了三步
# 1. 版本号从 0.2.0 更新至 1.0.0-beta.0
# 2.npm 公布版本会打上 beta 标签,能够通过 npm i xxxx@beta 装置
# 3.github release 会打上 pre-release 标识

所以像我这种不须要整合性能的,须要拆开来应用

# 只响应 package.json 中的版本号
$ npx release-it major --preReleaseId=beta

# 设置 npm 发版时的标识为 beta
$ npx release-it major --npm.tag=beta

# 设置 github release 为预公布
$ npx release-it major --github.preRelease

细节能够浏览 pre-releases 局部的指南。

流程钩子

这个环节设计和 standard-version 差不多,细节倡议间接看官网文档就行了。

结尾

在学习应用的晦涩度(上手过程)来看,绝对 standard-version 我可能更偏差于应用 release-it。release-it 比拟年老更有生机,定位问题我感觉还是能简略从源码中找到的。调研过后,咱们团队接下来的自定义解决将应用 release-it 进行后续工作。之后还须要对接到 tower 与飞书实现工作更新及音讯告诉。

心愿这篇文章能对你起到帮忙。

正文完
 0