Skip to content

Gemini CLI 发布

发布周期和标签

我们将尽可能遵循 https://semver.org/ 的规范,但会指出何时或如果需要偏离。我们的每周发布将是次要版本增量,发布之间的任何错误或紧急修复将作为补丁版本发布到最新版本上。

每周二 UTC 时间约 20:00 会发布稳定版和预览版。推广流程如下:

  • 代码提交到 main 分支,并在每晚推送到 nightly
  • 代码在 main 分支上停留不超过 1 周后,将晋升到 preview 频道
  • 1 周后,最新的 preview 频道将晋升到 stable 频道
  • 根据需要,将针对 previewstable 频道发布补丁修复,每次补丁版本号都会递增。

预览版 (Preview)

这些发布版本未经充分验证,可能包含回归或其他未解决的问题。请帮助我们测试并使用 preview 标签进行安装。

bash
npm install -g @google/gemini-cli@preview

稳定版 (Stable)

这将是上周发布版本的完整推广版本,加上任何错误修复和验证。请使用 latest 标签。

bash
npm install -g @google/gemini-cli@latest

日构建版 (Nightly)

  • 新版本将于每天 UTC 时间 00:00 发布。这将是发布时 main 分支的所有更改。应假定存在待处理的验证和问题。请使用 nightly 标签。
bash
npm install -g @google/gemini-cli@nightly

每周发布推广

每周二,值班工程师将触发“推广发布”工作流。此单一操作可自动化整个每周发布过程:

  1. 将预览版推广到稳定版: 工作流识别最新的 preview 版本并将其推广到 stable。这将成为 npm 上的新 latest 版本。
  2. 将日构建版推广到预览版: 最新的 nightly 版本随后将被推广,成为新的 preview 版本。
  3. 为下一个日构建版做准备: 自动创建一个拉取请求并合并,以在 main 分支中更新版本号,为下一个日构建版发布做准备。

此过程可确保一致且可靠的发布周期,并最大限度地减少手动干预。

版本控制的真相来源

为确保最高可靠性,发布推广过程使用 NPM 注册表作为真相的单一来源,以确定每个发布频道(stablepreviewnightly)的当前版本。

  1. 从 NPM 获取: 工作流首先查询 NPM 的 dist-tagslatestpreviewnightly),以获取当前可供用户使用的软件包的确切版本字符串。
  2. 交叉检查完整性: 对于从 NPM 检索到的每个版本,工作流都会执行关键的完整性检查:
    • 验证存储库中是否存在相应的 git 标签
    • 验证是否已创建相应的 GitHub Release
  3. 发现不一致时停止: 如果 NPM 上列出的版本缺少 git 标签或 GitHub Release,工作流将立即失败。此严格检查可防止从损坏或不完整的先前版本进行推广,并向值班工程师发出发布状态不一致的警报,必须手动解决。
  4. 计算下一个版本: 仅当这些检查通过后,工作流才会继续根据从 NPM 检索到的受信任版本号计算下一个语义版本。

这种以 NPM 为先的方法,并辅以完整性检查,使得发布过程高度健壮,并可防止仅依赖 git 历史记录或 API 输出而可能出现的版本不一致问题。

手动发布

在需要超出常规日构建版和每周推广计划进行发布,且已包含在补丁流程中的情况,您可以使用“Release: Manual”工作流。此工作流提供了一种直接的方式来发布任何分支、标签或提交 SHA 的特定版本。

如何创建手动发布

  1. 导航到存储库的 Actions 选项卡。
  2. 从列表中选择 Release: Manual 工作流。
  3. 单击 Run workflow 下拉按钮。
  4. 填写必需的输入:
    • Version:要发布的精确版本(例如 v0.6.1)。这必须是带有 v 前缀的有效语义版本。
    • Ref:要从中发布的分支标签完整提交 SHA
    • NPM Channel:要发布到的 npm 频道。选项包括 previewnightlylatest(用于稳定发布)和 dev。默认为 dev
    • Dry Run:保留为 true 以运行所有步骤而不发布,或设置为 false 以执行实时发布。
    • Force Skip Tests:设置为 true 以跳过测试套件。不建议用于生产发布。
    • Skip GitHub Release:设置为 true 以跳过创建 GitHub Release,仅创建 npm 发布。
  5. 单击 Run workflow

然后,工作流将继续测试(如果未跳过)、构建并发布。如果在非 dry run 过程中工作流失败,它将自动创建一个包含失败详细信息的 GitHub issue。

回滚/前滚

如果发布版本出现严重回归,您可以通过更改 npm dist-tag 来快速回滚到先前的稳定版本或前滚到新的补丁版本。“Release: Change Tags”工作流提供了一种安全可控的方式来执行此操作。

这是回滚和前滚的首选方法,因为它不需要完整的发布周期。

如何更改发布标签

  1. 导航到存储库的 Actions 选项卡。
  2. 选择 Release: Change Tags 工作流。
  3. 单击 Run workflow 下拉按钮。
  4. 填写必需的输入:
    • Version:您希望标签指向的现有软件包版本(例如 0.5.0-preview-2)。此版本必须已发布到 npm 注册表。
    • Channel:要应用的 npm dist-tag(例如 previewstable)。
    • Dry Run:保留为 true 以记录操作而不进行更改,或设置为 false 以执行实时标签更改。
  5. 单击 Run workflow

然后,工作流将为 @google/gemini-cli@google/gemini-cli-core 软件包运行 npm dist-tag add 命令,将指定的频道指向指定的版本。

补丁

如果 main 分支上已修复的关键错误需要在 stablepreview 版本上进行补丁,则该过程现在高度自动化。

如何打补丁

1. 创建补丁拉取请求

有两种方法可以创建补丁拉取请求:

选项 A:通过 GitHub 评论(推荐)

在包含修复的拉取请求已合并后,维护者可以在同一 PR 上添加以下格式的评论:

/patch [channel]

  • channel(可选):
    • 无 channel - 同时修补 stable 和 preview 频道(默认,推荐用于大多数修复)
    • both - 同时修补 stable 和 preview 频道(与默认值相同)
    • stable - 仅修补 stable 频道
    • preview - 仅修补 preview 频道

示例:

  • /patch(同时修补 stable 和 preview - 默认)
  • /patch both(同时修补 stable 和 preview - 显式)
  • /patch stable(仅修补 stable)
  • /patch preview(仅修补 preview)

Release: Patch from Comment 工作流将自动查找合并提交 SHA 并触发 Release: Patch (1) Create PR 工作流。如果 PR 尚未合并,它将发布一条评论指示失败。

选项 B:手动触发工作流

导航到 Actions 选项卡并运行 Release: Patch (1) Create PR 工作流。

  • Commit:要在 main 分支上进行 cherry-pick 的提交的完整 SHA。
  • Channel:您要修补的频道(stablepreview)。

此工作流将自动执行以下操作:

  1. 查找频道的最新发布标签。
  2. 如果不存在,则从该标签创建发布分支(例如 release/v0.5.1-pr-12345)。
  3. 从发布分支创建新的热修复分支。
  4. 将您指定的提交 cherry-pick 到热修复分支。
  5. 从热修复分支创建拉取请求,指向发布分支。

2. 审查和合并

审查自动创建的拉取请求,以确保 cherry-pick 成功且更改正确。批准后,合并拉取请求。

安全提示: release/* 分支受分支保护规则保护。指向这些分支之一的拉取请求需要至少一次来自代码所有者的审查才能合并。这确保了没有未经授权的代码被发布。

2.5. 将多个提交添加到热修复(高级)

如果您需要在单个补丁发布中包含多个修复,可以在创建初始补丁 PR 后将其他提交添加到热修复分支:

  1. 从主要修复开始:在最重要的 PR 上使用 /patch(或 /patch both)来创建初始热修复分支和 PR。

  2. 在本地检出热修复分支

    bash
    git fetch origin
    git checkout hotfix/v0.5.1/stable/cherry-pick-abc1234  # 使用 PR 中的实际分支名称
  3. Cherry-pick 其他提交

    bash
    git cherry-pick <commit-sha-1>
    git cherry-pick <commit-sha-2>
    # 添加任意数量的提交
  4. 推送更新的分支

    bash
    git push origin hotfix/v0.5.1/stable/cherry-pick-abc1234
  5. 测试和审查:现有的补丁 PR 将自动更新您的其他提交。由于您现在要一起发布多个更改,请进行彻底测试。

  6. 更新 PR 描述:考虑更新 PR 标题和描述,以反映其包含多个修复。

此方法允许您将相关修复分组到单个补丁发布中,同时保持对包含内容和冲突解决方式的完全控制。

3. 自动发布

合并拉取请求后,将自动触发 Release: Patch (2) Trigger 工作流。然后,它将启动 Release: Patch (3) Release 工作流,该工作流将执行以下操作:

  1. 构建并测试修补后的代码。
  2. 将新的补丁版本发布到 npm。
  3. 创建新的 GitHub Release,包含补丁说明。

此完全自动化的过程可确保补丁的创建和发布一致且可靠。

故障排除:旧版分支工作流

问题:如果补丁触发工作流失败,并出现“Resource not accessible by integration”等错误,或引用不存在的工作流文件(例如 patch-release.yml),则表示热修复分支包含过时的工作流文件。

根本原因:合并 PR 时,GitHub Actions 会运行源分支(热修复分支)的工作流定义,而不是目标分支(发布分支)的工作流定义。如果热修复分支是从早于工作流改进的旧发布分支创建的,它将使用旧的工作流逻辑。

解决方案

选项 1:手动触发(快速修复) 从包含最新工作流代码的分支手动触发更新的工作流:

bash
# 对于跳过测试的预览频道补丁
gh workflow run release-patch-2-trigger.yml --ref <包含更新工作流的分> \
  --field ref="hotfix/v0.6.0-preview.2/preview/cherry-pick-abc1234" \
  --field workflow_ref=<包含更新工作流的分> \
  --field dry_run=false \
  --field force_skip_tests=true

# 对于稳定频道补丁
gh workflow run release-patch-2-trigger.yml --ref <包含更新工作流的分> \
  --field ref="hotfix/v0.5.1/stable/cherry-pick-abc1234" \
  --field workflow_ref=<包含更新工作流的分> \
  --field dry_run=false \
  --field force_skip_tests=false

# 使用 main 分支的示例(最常见情况)
gh workflow run release-patch-2-trigger.yml --ref main \
  --field ref="hotfix/v0.6.0-preview.2/preview/cherry-pick-abc1234" \
  --field workflow_ref=main \
  --field dry_run=false \
  --field force_skip_tests=true

注意:将 <包含更新工作流的分支> 替换为包含最新工作流改进的分支(通常是 main,但如果测试更新,也可能是功能分支)。

选项 2:更新热修复分支 将最新的 main 分支合并到您的热修复分支中,以获取更新的工作流:

bash
git checkout hotfix/v0.6.0-preview.2/preview/cherry-pick-abc1234
git merge main
git push

然后关闭并重新打开 PR 以使用更新的版本重新触发工作流。

选项 3:直接发布触发器 完全跳过触发工作流,直接运行发布工作流:

bash
# 替换为适当的 channel 和 release_ref 值
gh workflow run release-patch-3-release.yml --ref main \
  --field type="preview" \
  --field dry_run=false \
  --field force_skip_tests=true \
  --field release_ref="release/v0.6.0-preview.2"

Docker

我们还运行一个名为 release-docker.yml 的 Google Cloud Build。它会发布与您的发布匹配的 sandbox docker。一旦服务帐户权限得到解决,这也将迁移到 GH 并与主发布文件合并。

发布验证

推送新版本后,应执行烟雾测试,以确保软件包按预期工作。这可以通过本地安装软件包并运行一组测试来完成,以确保它们正常运行。

  • npx -y @google/gemini-cli@latest --version 以验证推送是否按预期工作,如果您没有进行 rc 或 dev 标签
  • npx -y @google/gemini-cli@<release tag> --version 以验证标签是否已正确推送
  • 这在本地具有破坏性 npm uninstall @google/gemini-cli && npm uninstall -g @google/gemini-cli && npm cache clean --force && npm install @google/gemini-cli@<version>
  • 建议通过执行一些 llm 命令和工具的基本运行来执行烟雾测试,以确保软件包按预期工作。我们将在未来对其进行更多规范化。

本地测试和验证:打包和发布流程的更改

如果您需要测试发布流程而不实际发布到 NPM 或创建公开的 GitHub Release,您可以从 GitHub UI 手动触发工作流。

  1. 转到存储库的 Actions 选项卡
  2. 单击“Run workflow”下拉菜单。
  3. dry_run 选项保留为选中状态 (true)。
  4. 单击“Run workflow”按钮。

这将运行整个发布过程,但会跳过 npm publishgh release create 步骤。您可以检查工作流日志以确保一切正常。

在提交对打包和发布流程的任何更改之前,对其进行本地测试至关重要。这可确保软件包将正确发布,并在用户安装时正常工作。

要验证您的更改,您可以对发布过程执行 dry run。这将模拟发布过程,而无需实际将软件包发布到 npm 注册表。

bash
npm_package_version=9.9.9 SANDBOX_IMAGE_REGISTRY="registry" SANDBOX_IMAGE_NAME="thename" npm run publish:npm --dry-run

此命令将执行以下操作:

  1. 构建所有软件包。
  2. 运行所有预发布脚本。
  3. 创建将发布到 npm 的软件包 tarball。
  4. 打印将要发布的软件包的摘要。

然后,您可以检查生成的 tarball,以确保它们包含正确的文件,并且 package.json 文件已正确更新。tarball 将在每个软件包目录的根目录中创建(例如 packages/cli/google-gemini-cli-0.1.6.tgz)。

通过执行 dry run,您可以确信对打包过程的更改是正确的,并且软件包将成功发布。

发布深度解析

发布过程为不同的分发渠道创建两种不同的工件:用于 NPM 注册表的标准软件包,以及用于 GitHub Releases 的单一、自包含的可执行文件。

以下是关键阶段:

阶段 1:发布前健全性检查和版本控制

  • 发生什么: 在移动任何文件之前,该过程可确保项目处于良好状态。这包括运行测试、代码检查和类型检查(npm run preflight)。根 package.jsonpackages/cli/package.json 中的版本号将更新为新的发布版本。

阶段 2:为 NPM 构建源代码

  • 发生什么: packages/core/srcpackages/cli/src 中的 TypeScript 源代码被编译为标准的 JavaScript。
  • 文件移动:
    • packages/core/src/**/*.ts -> 编译为 -> packages/core/dist/
    • packages/cli/src/**/*.ts -> 编译为 -> packages/cli/dist/
  • 原因: 开发过程中编写的 TypeScript 代码需要转换为纯 JavaScript,以便 Node.js 可以运行。core 软件包首先构建,因为 cli 软件包依赖于它。

阶段 3:将标准软件包发布到 NPM

  • 发生什么:@google/gemini-cli-core@google/gemini-cli 软件包运行 npm publish 命令。
  • 原因: 这会将它们作为标准的 Node.js 软件包发布。通过 npm install -g @google/gemini-cli 安装的用户将下载这些软件包,npm 会自动处理 @google/gemini-cli-core 依赖项的安装。这些软件包中的代码未捆绑成单个文件。

阶段 4:组装和创建 GitHub Release 工件

此阶段发生在 NPM 发布之后,并创建了单一文件的可执行文件,该文件允许直接从 GitHub 存储库使用 npx

  1. 创建 JavaScript Bundle:

    • 发生什么: 来自 packages/core/distpackages/cli/dist 的已构建 JavaScript,以及所有第三方 JavaScript 依赖项,都通过 esbuild 捆绑成一个单一的可执行 JavaScript 文件(例如 gemini.js)。node-pty 库因包含本机二进制文件而被排除在此捆绑包之外。
    • 原因: 这会创建一个单一的优化文件,其中包含所有必需的应用程序代码。它简化了希望在没有完整 npm install 的情况下运行 CLI 的用户的执行过程,因为所有依赖项(包括 core 软件包)都直接包含在内。
  2. 组装 bundle 目录:

    • 发生什么: 在项目根目录创建一个临时的 bundle 文件夹。单一的 gemini.js 可执行文件以及其他必需文件将放置在其中。
    • 文件移动:
    • gemini.js(来自 esbuild)-> bundle/gemini.js
    • README.md -> bundle/README.md
    • LICENSE -> bundle/LICENSE
    • packages/cli/src/utils/*.sb(沙盒配置文件)-> bundle/
    • 原因: 这会创建一个干净、自包含的目录,其中包含运行 CLI 和理解其许可证及用法所需的一切。
  3. 创建 GitHub Release:

    • 发生什么: bundle 目录的内容,包括 gemini.js 可执行文件,将作为工件附加到新的 GitHub Release。
    • 原因: 这使得 CLI 的单一文件版本可供直接下载,并启用了 npx https://github.com/google-gemini/gemini-cli 命令,该命令下载并运行此特定的捆绑工件。

工件摘要

  • NPM: 发布标准的、未捆绑的 Node.js 软件包。主要工件是 packages/cli/dist 中的代码,它依赖于 @google/gemini-cli-core
  • GitHub Release: 发布单一的、捆绑的 gemini.js 文件,其中包含所有依赖项,以便通过 npx 轻松执行。

这种双工件流程可确保传统 npm 用户和偏爱 npx 便利性的用户都能获得优化的体验。

通知

失败的发布工作流将自动创建一个带有 release-failure 标签的 issue。

当创建此类 issue 时,将向维护者的聊天频道发送通知。

修改聊天通知

通知使用 GitHub for Google Chat。要修改通知,请在聊天空间中使用 /github-settings

WARNING

以下说明描述了一种脆弱的变通方法,它依赖于聊天应用程序 UI 的内部结构。它很可能会在未来的更新中失效。

可用标签列表当前未正确填充。如果您想添加一个在存储库前 30 个标签中未按字母顺序排列的标签,则必须使用浏览器的开发者工具手动修改 UI:

  1. 打开浏览器的开发者工具(例如 Chrome DevTools)。
  2. /github-settings 对话框中,检查标签列表。
  3. 找到代表标签的 <li> 元素之一。
  4. 在 HTML 中,将该 <li> 元素的 data-option-value 属性修改为所需的标签名称(例如 release-failure)。
  5. 单击 UI 中修改后的标签以选中它,然后保存您的设置。

基于 MIT 许可证发布