
自动化发布与版本变更(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
会为你处理所有繁琐的版本管理和发布事务。