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.jsonCargo.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 键。

2. .release-please-manifest.json - 版本清单

这个文件是 release-please 用来记录状态的,它存储了每个包的最新发布版本。

版本清单示例

{
  ".": "0.0.1"
}

这里的键 . 对应 release-please-config.jsonpackages 下的键。值 "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"

  1. 开发新功能
    开发者从 main 分支创建一个新分支 dev

    git switch -c dev
    
  2. 编写代码并提交
    开发者完成了一个新功能,并使用 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
    
  3. 创建并合并 PR
    开发者创建一个从 devmain 的 PR。经过代码审查后,这个 PR 被合并到 main 分支。

  4. release-please 自动触发
    main 分支上的 push 事件触发了 .github/workflows/release-please.yaml 工作流。

  5. 生成 Release PR

    • release-please 检查 main 分支,发现自上个版本 0.1.0 以来,新增了 featfix 类型的提交。
    • 根据 feat 提交,它决定将版本从 0.1.0 升级到 0.2.0 (minor 版本提升)。
    • release-please 会自动创建一个新的 PR,标题通常是 chore(main): release 0.2.0
  6. 审查 Release PR
    这个自动创建的 PR 包含了以下文件变更:

    • CHANGELOG.md 新增了 v0.2.0 的章节,包含了上述 featfix 提交的记录。
    • 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
  7. 合并 Release PR,完成发布

    • 团队审查通过后,合并这个 Release PR。
    • 这次合并再次触发 release-please 工作流。
    • 这一次,release-please 识别出这是一个它自己创建的 Release PR,于是它会执行最后一步:
      • 在 GitHub 上创建一个名为 v0.2.0Git 标签
      • 在 GitHub 上创建一个名为 v0.2.0Release,并将 CHANGELOG.md 中对应版本的内容作为 Release Notes。

至此,一个完整的自动化发布流程就完成了!你的团队只需专注于按规范提交代码,release-please 会为你处理所有繁琐的版本管理和发布事务。