本文へ移動
cccskills
無料GitHub で公開

brpc-release

Drive an Apache bRPC release end to end - confirm the release slot, draft Release Notes, bump version files, cut the tag, build/sign/checksum the source tarball, stage it to Apache SVN dist/dev, verify the candidate, and draft the VOTE/RESULT/ANNOUNCE mails. Use when cutting, resuming, or verifying a bRPC release ("发版 <version>", "release apache brpc", "准备 RC", "写投票邮件", "验证发布包", "check the release candidate").

インストール方法を見る

含まれるファイル(8)

  • SKILL.md16.2 KB
  • references/checklist.md6.6 KB
  • references/mail_templates.md9.4 KB
  • references/state_template.md2.6 KB
  • scripts/bump_version.sh6.6 KB
  • scripts/make_package.sh6.0 KB
  • scripts/release_notes.sh8.6 KB
  • scripts/verify_package.sh9.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Apache bRPC 发版

面向 Release Manager(RM)的发版助手。权威流程是 community/release_cn.md(英文 community/release_en.md), 本 skill 不取代它,只做三件事:编排顺序、自动化机械步骤、在不可逆操作前刹车。

铁律:这些命令永远不要代 RM 执行

发版有大量对外且不可撤回的动作。遇到下面这些,把命令打印出来让 RM 自己跑,然后等待他明确回报成功; 未收到成功确认前不得进入下一步:

动作为什么不能代跑
git push origin --tagstag 推到 apache/brpc 后立刻被镜像和下游 CI 抓取,回退要惊动 ASF INFRA
svn commit / svn mv写入 Apache 官方分发仓库;dist/release 下的内容会同步到全球镜像
gpg --detach-sign模型不能执行签名,也不能接触私钥口令;必须由 RM 在交互式终端执行
git config user.name / git config user.email发版不要求修改 Git 身份;模型不得读取后重写、覆盖或临时修改用户配置
发送任何邮件dev@ / announce@ 是公开存档,发出即无法撤回
发布 GitHub Release对外可见

改版本号、打本地 tag、打包、算校验和、生成草稿这些本地可逆操作可以直接做。

安全条款与强制检查

发版助手必须采用 fail-closed 原则:前置条件不明确或检查失败时立即停止,不猜测、不绕过,也不以 --force、临时改脚本或跳过校验的方式继续。

在任何会修改仓库或生成候选包的步骤前,必须逐项检查:

  1. 当前目录是预期的 Apache bRPC Git 仓库,且远端指向可识别的 bRPC 仓库;
  2. 目标版本符合 X.Y.Z 或 X.Y.Z-rcNN,目标分支严格为 release-X.Y;
  3. 当前分支已是目标 release 分支;minor 首发分支必须从 origin/master 创建,不能先改版本号再切分支;
  4. 工作区没有与本次步骤无关的未提交修改;发现用户修改时不得覆盖、丢弃或自动 stash;
  5. tag 不存在,或已存在且明确指向预期 commit;不得静默覆盖或移动 tag;
  6. 待发布 commit 来自目标 release 分支,且版本文件检查全部通过;
  7. 即将执行的操作不在上方“永远不要代 RM 执行”的列表中。

所有脚本必须使用严格模式、校验外部命令返回值,并将错误输出到 stderr。涉及版本号、分支、tag、 产物路径的参数不得直接拼接成未经验证的命令。日志和草稿不得包含私钥、密码、token、cookie 或其他凭据。 发版沿用仓库已有的 Git 身份,不要求 Apache 邮箱;模型不得执行任何修改本地或全局 Git 用户名、邮箱的命令。

依赖与登录态检查

每次启动、恢复会话,以及执行依赖外部服务的步骤前,必须先检查当前步骤所需的命令、网络、账号权限和 登录态。基础检查包括 git、bash;阶段 2/4 检查 gpg 和 ${APACHE_ID}@apache.org 私钥;阶段 5/8 检查 svn 与 Apache SVN 认证;阶段 6 检查网络和 SHA-512 工具;阶段 7 检查 gh、GitHub 登录态和对 apache/brpc 的访问权限。

检查失败时,将对应步骤标记为阻塞,汇报已完成项和其他可选下一步,等待 RM 选择;不得跳过检查、代填密码、 token 或私钥口令。具体命令和失败处理见 community/skills/README.md 的“执行前检查”。

每次开工前先做这三件事

  1. 读状态文件 ~/brpc_release/<version>/STATE.md。发版横跨数周,绝大多数会话是接着上次继续, 不要默认从头开始。文件不存在时,用 references/state_template.md 建一个。

  2. 确认版本号、RM 和 Apache ID:查 community/release_schedule.md 里的排期表,并向 RM 询问 Apache ID(仅用户名,不询问密码、token 或其他凭据)。Apache ID 用于以 --username 参数检出和操作 Apache SVN 仓库,并写入状态文件。补丁版本 ${MAJOR}.${MINOR}.${PATCH} 在已有的 release-${MAJOR}.${MINOR} 分支上发;minor 首发版本 ${MAJOR}.${MINOR}.0 要从 master 拉新分支。 先创建或切换 release 分支,再做任何版本号修改;不得在 master 或其他工作分支先改版本号。

  3. 确认目录约定(与 release_cn.md 一致,脚本也按这个假设):

    路径用途
    ~/brpcrelease 分支的 clone,打包在这里做
    ~/brpc_release/svn/dev/brpcApache SVN dist/dev 工作副本
    ~/brpc_release/<version>/本次发版的草稿、邮件、状态文件

每完成一个阶段,立刻回写 STATE.md(勾选 + 记下关键产物,如 tag 的 commit id、投票邮件链接)。

进度汇报与下一步选择

每完成一个步骤或收到 RM 对手工步骤的成功回报后,助手必须先读取并回写 STATE.md,再向 RM 汇报:

  1. 本次完成:列出刚完成的阶段或子步骤,以及产物路径、tag commit id、候选包 URL 等关键结果;
  2. 当前进度:列出已完成项和未完成项;对于被跳过的可选项,明确标记为“跳过”及原因;
  3. 前置条件/阻塞项:说明下一步是否需要 RM 执行 GPG、push tag、SVN commit/mv、发邮件或其他外部操作;
  4. 可选下一步:只列出当前前置条件已满足的步骤,按推荐顺序编号;如果工作可并行,明确标为“可并行”;
  5. 等待选择:停止执行,询问 RM 选择哪一项。除非 RM 明确指示连续执行,否则助手不能自动进入下一阶段。

推荐使用以下固定格式,保证跨会话可恢复:

当前发版进度:<version>
本次完成:
- [x] <刚完成的步骤与关键产物>

已完成:<编号列表>
未完成:<编号列表>
阻塞项:<无 / 需要 RM 执行的动作>

可选下一步:
1. <推荐步骤>
2. <可并行步骤>
3. <其他已满足前置条件的步骤>

请回复序号或直接说明希望继续的工作。

RM 可以随时选择任何前置条件已满足的未完成项,例如“先生成 Release Notes”“先验证本地产物”或“继续阶段 5”。 助手应先核对依赖关系,满足则执行并更新状态;不满足则解释所缺前置条件,并继续等待 RM 选择。

阶段地图

流程分 9 个阶段,跨度约 2 周。详细检查项在 references/checklist.md,邮件模板在 references/mail_templates.md——按需读取,不要一次性全读进来。

阶段 1 — 确认发布范围(约 1 周)

和社区确认本次发布范围,合入“计划发布但还没进来”的 PR,并冻结候选 commit 范围。 此时不生成 Release Notes;分支、版本和候选包尚未稳定,提前生成容易遗漏或反复返工。

阶段 2 — GPG 准备(非首次发版跳过)

先检查有没有可用的密钥:

gpg --list-secret-keys --keyid-format=long <apache-id>@apache.org

有输出就跳过。没有则照 references/checklist.md 的「GPG 首次设置」走完四步:建 4096 位 RSA 密钥 (邮箱必须是 Apache 邮箱)→ 发布公钥到 keyserver → 把 fingerprint 填进 https://id.apache.org → 把公钥追加进 SVN 的 KEYS 文件。

阶段 3 — 拉发版分支 + 改版本号

顺序不可颠倒:先拉/切换发版分支,确认当前分支正确,再改版本号。脚本会强制检查目标 release 分支、仓库身份和工作区状态;任一检查不通过都不会写文件。

export VERSION="<version>"
export APACHE_ID="<apache-id>"
export RELEASE_BRANCH="release-${VERSION%.*}"

# minor 首发版本才需要从 master 拉新分支
# 如工作区已有未提交修改,应先提交或暂存,不能为了切分支而提前改版本号
git checkout -b "$RELEASE_BRANCH" origin/master
git branch --show-current  # 必须输出 $RELEASE_BRANCH

# 改发布所需的硬编码版本号(幂等,可重复跑)
scripts/bump_version.sh "$VERSION"

# 只校验不修改
scripts/bump_version.sh "$VERSION" --check

脚本只更新发布元数据及用户文档;example/build_with_bazel_module/MODULE.bazel 中示例模块自身的 version 和示例依赖的 bRPC version 都不跟随本次发版修改。脚本结尾会扫描其他旧版本号残留。 另外检查 NOTICE 的年份(Copyright 2018-<当年>),年初发版时尤其容易漏。

发版过程中发现问题,一律在 release 分支上改,不要回 master。

阶段 4 — 打 tag、打包、签名、校验和

模型不得执行本阶段脚本,只能根据已确认的 Apache ID 和版本号向 RM 提供完整命令:

cd ~/brpc
BRPCUSERNAME="$APACHE_ID" community/skills/brpc-release/scripts/make_package.sh "$VERSION"

由 RM 在交互式终端执行。脚本会一次完成:校验工作区和版本号 → 创建本地 tag → 生成源码包 → 调用 GPG 并等待 RM 输入私钥口令 → 验证签名 → 生成并验证 .sha512。脚本不会修改 Git 用户名或邮箱, 也不会推送 tag。

模型提供命令后必须停止。只有 RM 明确回报脚本成功,并提供输出中的 tag commit id 后,才把阶段 4 标为完成并进入下一阶段;失败或结果不明确时不得继续。git push origin --tags 仍由 RM 单独执行。

阶段 5 — 上传到 Apache SVN dist/dev

如果状态文件中没有 Apache ID,先向 RM 询问;只记录 ID,不得询问、记录或代填密码。首次使用时, 可代 RM 使用 Apache ID 检出 SVN 工作副本(认证需要密码时由 RM 在终端交互输入):

export BRPCUSERNAME="$APACHE_ID"
mkdir -p ~/brpc_release/svn/dev/
svn --username="$BRPCUSERNAME" co https://dist.apache.org/repos/dist/dev/brpc/ ~/brpc_release/svn/dev/brpc

按 references/checklist.md 的「SVN 上传」小节,把三个文件(.tar.gz / .asc / .sha512) 放进 ~/brpc_release/svn/dev/brpc/<version>/,svn add 之后由 RM 执行 svn commit。 首次发版的 RM 还要先把公钥追加进 KEYS 并一起提交。

阶段 6 — 验证候选包

# 验证已上传到 dist/dev 的包(联网下载并全面校验)
scripts/verify_package.sh "https://dist.apache.org/repos/dist/dev/brpc/${VERSION}/"

# 或验证本地产物
scripts/verify_package.sh "${HOME}/brpc_release/${VERSION}"

对标仓库里已有的 community/apache-package-validator.sh(那个脚本依赖 wget 和 GNU coreutils), 本脚本是可在 macOS 直接运行的独立替代实现,并额外做一项文档里要求但那个脚本没覆盖的 检查:源码包与 GitHub tag 逐文件 diff。

自己验过一遍再发投票邮件——PMC 常见的 -1 原因见 references/checklist.md。

阶段 7 — 准备 Release Notes 并发起投票(至少 72 小时)

候选包验证通过后,以最终 tag 为边界生成 Release Notes 草稿:

export PREV_VERSION="<previous-version>"
# 使用本地 release tag 作为终点;tag 无需推送到 GitHub。
scripts/release_notes.sh "$PREV_VERSION" "$VERSION" \
  > "${HOME}/brpc_release/${VERSION}/notes-draft.md"

脚本以最终 tag 范围内的 GitHub PR 为唯一条目来源:每个合并 PR 只输出一项,并从 GitHub 获取 PR 标题和 作者;输出格式为 @GitHub-ID #PR-id,不生成显式 PR URL,GitHub Release 会自动识别链接。不会再按 commit 逐条生成。分类仍是 Feature / Bugfix / Enhancement / Other 的启发式猜测,必须人工核对完整性和准确性;没有 关联 GitHub PR 的 commit 会在草稿注释中单独提示,供人工确认归属。脚本按每批最多 50 个 PR 的 GraphQL 请求加载元数据,避免逐 commit 查询导致长时间等待。按渠道准备:

  • GitHub Release:完整 Release Notes,逐项保留 by @GitHub-ID (#PR-id),不附显式链接;分类内按功能主题 排序。同一 GitHub ID 的不同功能或修复必须作为独立条目保留;
  • 微信公众号:与 GitHub Release 保持相同的“新功能 / Bug 修复 / 功能增强”分类和 PR 条目粒度,每项保留 by @GitHub-ID (#PR-id),不写 PR URL。阅读相关 PR 的说明和必要上下文后,以自然中文润色功能描述; 不逐字直译、不照搬生硬的提交标题,无法确认含义时不臆测;
  • VOTE 邮件的 Release Note:只挑重要 PR,Feature 优先,不粘贴完整列表;
  • ANNOUNCE 邮件:只写几条主要变化,不标贡献者和 PR 编号。

从 references/mail_templates.md 取 [VOTE] 模板,填好版本号、精选 Release Note、 tag 的 commit id,草稿写到 ~/brpc_release/<version>/vote-mail.txt,由 RM 发到 dev@brpc.apache.org。邮件发出后,在 dev@brpc.apache.org 邮件归档 找到该 [VOTE] 邮件并复制其永久链接,立即写入 STATE.md 的“投票邮件链接”。

需要至少 72 小时 + 3 张 PMC binding +1。够票后从同一归档页面找到 [RESULT][VOTE] 邮件的永久链接, 回写到 STATE.md 的“已完成记录”,再用 [RESULT][VOTE] 模板宣布结果。

投票没过:在 release 分支修问题,回到阶段 3 重新打包,版本号不变但要重打 tag。

阶段 8 — 完成发布

依次(每一步都由 RM 执行):

  1. PMC 成员把包从 dist/dev 移到 dist/release(svn mv)
  2. 在 GitHub 对应 tag 上创建 Release,标题统一为 Apache bRPC ${VERSION}
  3. 等包同步到 Apache 镜像后,更新 https://brpc.apache.org/docs/downloadbrpc/ (在 apache/brpc-website 仓库,中英文都要改)
    • 签名和哈希链接前缀:https://downloads.apache.org/brpc/
    • 代码包链接前缀:https://dlcdn.apache.org/brpc/
  4. 用 [ANNOUNCE] 模板发信到 dev@brpc.apache.org 和 announce@apache.org —— 必须用个人 apache 邮箱、必须纯文本格式,announce@ 要人工审核约一天

阶段 9 — 收尾

  • 把 release 分支合回 master
  • 更新 community/release_schedule.md 里本次发版的实际日期
  • 微信公众号等外部渠道(可选)

完成上述事项并确认正式发布可下载后,助手应汇报可清理的本地发版产物,并由 RM 自行决定是否执行。 不得自动删除,也不得删除 Git 分支、tag、SVN 工作副本或 STATE.md。建议 RM 在确认无需保留本地 归档、且 STATE.md 已记录 tag commit id、SHA512、投票链接等关键事实后,执行:

export VERSION="<version>"

# 仅删除本次生成的本地源码包、签名、哈希和草稿;保留 STATE.md 作为发版记录。
rm -f "${HOME}/brpc_release/${VERSION}"/apache-brpc-"${VERSION}"-src.tar.gz{,.asc,.sha512}
rm -f "${HOME}/brpc_release/${VERSION}"/notes-draft.md \
      "${HOME}/brpc_release/${VERSION}"/wechat-draft.md \
      "${HOME}/brpc_release/${VERSION}"/{vote-mail,result-mail,announce-mail}.txt

# 若确认不再需要整个本次草稿目录,先检查内容,再由 RM 手工删除。
ls -la "${HOME}/brpc_release/${VERSION}"
# rm -rf "${HOME}/brpc_release/${VERSION}"

SVN 工作副本 ~/brpc_release/svn/dev/brpc 通常应保留供下次发版复用;若 RM 明确要清理,先确认不存在 未提交修改(svn status),再由 RM 手工删除该工作副本。

常见坑

  • 改了版本号却漏了文件:一定跑 bump_version.sh --check,别手改。
  • 在 master 上打 tag:所有发版操作都在 release-<major.minor> 分支。
  • sha512 文件里带路径:sha512sum 必须在 tarball 所在目录执行,否则校验方 --check 会失败。 脚本已处理。
  • macOS 没有 sha512sum:脚本会自动回退到 gsha512sum 或 shasum -a 512。
  • 投票邮件写错 commit id:填 tag 指向的 commit,不是分支 HEAD。
  • 只回 +1 不附检查项:PMC 投票必须列出检查了哪些项。

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

このスキルの問題を報告する