自动化发布与版本变更(1)
release-please 自动化版本管理与发布指南
release-please 是一个强大的自动化工具,它可以根据你的 Git 提交历史,自动决定版本号、生成 CHANGELOG,并创建发布 PR。它遵循 Conventional Commits (详情请看自动化发布与版本变更(2)) 规范,使得版本管理和发布流程变得异常简单和标准化。
这篇文档将带你从零开始,了解它的核心概念、如何配置,以及怎样将其无缝集成到你的 CI/CD 流程中。
使用 release-please 自动化版本管理与发布
release-please 是一个由 Google 开发和维护的开源工具,旨在帮助开发者自动化版本控制和软件包发布流程。它通过解析遵循 Conventional Commits 规范的 Git 提交消息,自动确定下一个版本号、生成更新日志(CHANGELOG),并创建一个“发布 PR”(Release PR)。一旦该 PR 被合并,release-please 就会自动创建 GitHub Release 和对应的 Git 标签。
这种自动化的方式极大地简化了发布流程,减少了手动操作的错误,并确保了版本历史和变更日志的规范性和一致性。
核心概念
Conventional Commits
这是 release-please 工作的基础。它是一种结构化的提交消息格式。
feat: ...表示引入了新功能,对应 minor 版本升级 (e.g.,1.2.3->1.3.0)。fix: ...表示修复了 Bug,对应 patch 版本升级 (e.g.,1.2.3->1.2.4)。feat!: ...或BREAKING CHANGE: ...(在提交消息的脚注) 表示引入了破坏性变更,对应 major 版本升级 (e.g.,1.2.3->2.0.0)。- 其他类型如
chore:,docs:,style:,refactor:,perf:,test:等默认不会触发版本升级,但会一并记录在 CHANGELOG 中。
Release PR
当 release-please 检测到 main 分支上有可以触发新版本的提交时,它不会立即创建发布,而是会创建一个包含所有版本变更的 Pull Request。这个 PR 通常包含了:
- 版本号的提升(例如,在
package.json或Cargo.toml中)。 - 更新后的
CHANGELOG.md文件。 .release-please-manifest.json中版本号的更新。
这个设计允许团队在正式发布前对版本变更和 CHANGELOG 进行审查。
Manifest 文件
这是一个 JSON 文件(默认为 .release-please-manifest.json),用于追踪每个包的上一个发布版本。release-please 依据此文件中的版本号来计算下一个版本号。
快速上手:配置详解
我们通过一个具体的例子来讲解如何配置 release-please。假设我们有一个混合项目,包含 Rust 后端和前端代码,我们希望统一管理它们的版本。
1. release-please-config.json - 行为配置文件
这是 release-please 的核心配置文件,用于定义它的行为、要管理的包以及需要更新版本号的文件。
配置文件示例
{
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"include-v-in-tag": true,
"include-component-in-tag": false,
"packages": {
".": {
"release-type": "simple",
"changelog-path": "CHANGELOG.md",
"extra-files": [
{
"type": "toml",
"path": "app/Cargo.toml",
"jsonpath": "$.package.version"
},
{
"type": "toml",
"path": "crates/mycrate/Cargo.toml",
"jsonpath": "$.package.version"
},
{
"type": "json",
"path": "web/frontend/package.json",
"jsonpath": "$.version"
}
]
}
}
}
字段解析:
$schema: 指向官方的 JSON Schema,可以在编辑器中获得自动补全和校验,强烈建议保留。include-v-in-tag: 设置为true时,创建的 Git 标签会带上v前缀,例如v1.0.1。include-component-in-tag: 在单仓库多包配置中,是否在标签中包含包名。对于单一版本管理,设为false。packages: 定义要管理的软件包。.是一个特殊的键,表示将整个仓库作为一个“根”包来管理版本。这对于统一管理版本的 Monorepo 非常有用。
release-type: 指定发布类型。simple是一个通用类型,不针对任何特定语言。你也可以使用语言特定的类型(如rust,node,python),它们会自动查找并更新标准版本文件(如Cargo.toml,package.json),从而无需配置extra-files。但在混合项目中,simple+extra-files提供了更高的灵活性。changelog-path: 指定生成的CHANGELOG.md文件的位置,默认为CHANGELOG.md。extra-files: 这是最强大的配置之一。它允许你更新任意文件中指定的版本号。type: 文件类型,可以是json,toml,yaml等。path: 文件的相对路径。jsonpath: 一个 JSONPath 表达式,用于精确定位文件中需要更新的版本号字段。- 对于 TOML:
$.package.version意味着更新[package]表下的version键。 - 对于 JSON:
$.version意味着更新根对象的version键。
- 对于 TOML:
2. .release-please-manifest.json - 版本清单
这个文件是 release-please 用来记录状态的,它存储了每个包的最新发布版本。
版本清单示例
{
".": "0.0.1"
}
这里的键 . 对应 release-please-config.json 中 packages 下的键。值 "0.0.1" 是当前已发布的版本。当 release-please 运行时,它会从这个版本开始计算下一个版本。
注意: 你需要手动创建并提交这个文件的初始版本。之后
release-please会自动维护它。
3. 集成到 GitHub Actions
最后一步是创建一个 GitHub Actions 工作流,让 release-please 在代码合并到主分支时自动运行。
在项目根目录下创建 .github/workflows/release-please.yaml:
name: Release Please
on:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
id: release
with:
# release-please 创建的 Release PR 的标题
release-type: simple
# 指向你的配置文件
config-file: release-please-config.json
# 指向你的清单文件
manifest-file: .release-please-manifest.json
# (可选) 后续步骤:当 Release 成功创建后执行构建和发布
# - name: Run build and publish
# if: ${{ steps.release.outputs.release_created }}
# run: |
# echo "A new release was created!"
# # ...
字段解析:
on.push.branches: 设置工作流在main分支有push事件时触发。这是关键,因为我们通常在 PR 合并到main后才进行发布。permissions:release-please-action需要contents: write权限来提交文件变更(如CHANGELOG.md)和创建 Git 标签/Release,以及pull-requests: write权限来创建和更新 Release PR。steps.release.with:release-type,config-file,manifest-file: 这些参数直接告诉 Action 使用我们的自定义配置。如果你使用默认配置,这些可以省略。
完整工作流程示例
现在,让我们把所有部分串起来,看看 release-please 在实际开发中的工作流程。
当前状态: .release-please-manifest.json 中的版本是 "0.1.0"。
-
开发新功能
开发者从main分支创建一个新分支dev。git switch -c dev -
编写代码并提交
开发者完成了一个新功能,并使用 Conventional Commits 规范提交代码。# ... 修改代码 ... git add . git commit -m "feat(api): add user authentication endpoint" git commit -m "fix(web): correct button alignment on login page" git push origin dev -
创建并合并 PR
开发者创建一个从dev到main的 PR。经过代码审查后,这个 PR 被合并到main分支。 -
release-please自动触发
main分支上的push事件触发了.github/workflows/release-please.yaml工作流。 -
生成 Release PR
release-please检查main分支,发现自上个版本0.1.0以来,新增了feat和fix类型的提交。- 根据
feat提交,它决定将版本从0.1.0升级到0.2.0(minor 版本提升)。 release-please会自动创建一个新的 PR,标题通常是chore(main): release 0.2.0。
-
审查 Release PR
这个自动创建的 PR 包含了以下文件变更:CHANGELOG.md新增了v0.2.0的章节,包含了上述feat和fix提交的记录。app/Cargo.toml中的版本号变为0.2.0。crates/mycrate/Cargo.toml中的版本号变为0.2.0。web/frontend/package.json中的版本号变为0.2.0。.release-please-manifest.json中的版本号更新为0.2.0。
-
合并 Release PR,完成发布
- 团队审查通过后,合并这个 Release PR。
- 这次合并再次触发
release-please工作流。 - 这一次,
release-please识别出这是一个它自己创建的 Release PR,于是它会执行最后一步:- 在 GitHub 上创建一个名为
v0.2.0的 Git 标签。 - 在 GitHub 上创建一个名为
v0.2.0的 Release,并将CHANGELOG.md中对应版本的内容作为 Release Notes。
- 在 GitHub 上创建一个名为
至此,一个完整的自动化发布流程就完成了!你的团队只需专注于按规范提交代码,release-please 会为你处理所有繁琐的版本管理和发布事务。