首页
/ Composio CLI 发布工作流全指南:从自动 Beta、稳定版提升到失败恢复的 GitHub Releases 实战

Composio CLI 发布工作流全指南:从自动 Beta、稳定版提升到失败恢复的 GitHub Releases 实战

2026-09-09 23:58:45作者:凌朦慧Richard

导读

本文基于 Composio 仓库中的 CLI Release Workflow 手册(配属 .agents/skills/cli-release/SKILL.md 技能),完整讲解独立 composio 命令行二进制与安装器所依托的 GitHub Release 发布体系:如何区分自动 Beta、手动 Beta、稳定版提升与失败恢复四条路径,如何用 gh CLI 预检候选 Beta、核对资产与安装测试,以及发布被中断或失败时如何安全恢复。读完本文,你将掌握一套可直接执行的发布操作手册,并理解 build-cli-binaries.ymlresolve-release-target.shverify-assets.sh 等底层脚本的判定逻辑与设计动机。

Sources Of Truth:谁在真正掌控 CLI 发布

CLI 二进制发布不依赖 npm 或 Changesets,而是由一组 GitHub Actions 工作流与脚本共同构成唯一事实来源(sources of truth):

事实来源 职责
build-cli-binaries.yml 拥有 Beta 与 Stable 两类 GitHub Release 的构建与发布
resolve-release-target.sh 决定发布 tag 与源 commit(三种模式:push 滚动 Beta、build-beta 派发、promote-stable 提升)
verify-assets.sh 定义并要求六个规范资产全部 uploaded
cli.test-installation.yml 发布后跨平台验证安装器与 shell 集成
.changeset/config.json @composio/cli@composio/cli-local-tools 加入 ignore 列表,使其脱离 Changesets 发布轨道

特别要注意:ts.release.yml 是 TypeScript SDK/npm 的发布列车,不是 CLI 二进制的常规发布路径。CLI 包在 ts/packages/cli/package.json 中被标记为 private(版本号为开发哨兵值 0.0.0-development),永远不通过 Changesets 发布到 npm;二进制资产只挂在 GitHub Release 上,install.shcomposio upgrade 从 Releases 下载,composio upgrade --beta 则解析最新的 CLI 预发布版本。

Choose The Path:先归类需求,再选择发布路径

动手前必须先判断本次请求属于哪一类,因为不同目标的入口、结果与验证方式完全不同:

目标 路径 结果
发布一个普通 CLI 变更 将已评审的 PR 合并到 next push 自动构建滚动 Beta(rolling beta)
从某分支构建 Beta 在该分支派发 build-beta 从该分支 commit 构建预发布版本
发布稳定版 CLI 在已有且经过测试的 Beta tag 上派发提升(promotion) Beta 的源 commit 被重建并以稳定 tag 发布
恢复失败的提升 检查 draft 后重跑或重新派发同一个 Beta 未发布的 draft 可被恢复并替换资产

build-cli-binaries.yml 的 push 触发条件限定了 CLI 相关路径(ts/packages/cli/**ts/packages/cli-local-tools/**install.shinstall/**mise.toml 等),也就是说只有真正改动 CLI 的合并才会触发自动 Beta。手动派发则通过 workflow_dispatchaction 输入(build-betapromote-stable)与可选 version 输入来控制。

一个关键约束来自 resolve-release-target.sh:私有 CLI 的 package.json 使用开发哨兵版本号,永远不会被用来选择二进制版本。如果发布负责人需要一次有意的 minor 或 major 版本,正确做法是:派发一个显式指定版本号的 Beta → 完整验证 → 再提升那个确切的 Beta。

Changeset Rule:永远不要为被忽略的 CLI 包创建 Changeset

@composio/cli@composio/cli-local-tools 位于 .changeset/config.jsonignore 列表中,因此严禁为它们创建 .changeset/*.md 条目。

一旦有人创建了指向被忽略包的 Changeset,会触发一个非常隐蔽的连锁故障:

  1. changesets/action 进入 version-PR 模式;
  2. changeset version 对被忽略的包不会产生任何 commit;
  3. action 最终以 No commits between next and changeset-release/next 失败,并阻塞无关的 SDK 发布

这一点在 ts/scripts/validate-changesets.mjs 的实现中有直接印证:findIgnoredChangesetReleases 会扫描所有待处理的 Changeset,凡命中 config.ignore 中包名的,直接抛出异常,错误信息明确说明“被忽略包的 Changeset 会让 release job 在打开空 PR 时失败”。

正确的替代做法是:如果 CLI 变更需要面向用户的说明,直接编辑 ts/packages/cli/CHANGELOG.md。交接前必须运行守卫命令:

pnpm validate:changesets

该命令定义在根 package.json 中,对应 ts/scripts/validate-changesets.mjs;同时 test/release-workflow.test.ts 会校验 .changeset/config.json 的 ignore 列表、工作流与脚本之间的一致性,防止这些约束悄然漂移。

Inspect Candidates:基于实时 GitHub 状态挑选 Beta

选择候选 Beta 时必须使用 GitHub 的实时状态,绝不从本地 tag 或记忆中的版本挑选,因为发布状态随时可能变化。

先列出最近 100 个 Release,过滤出已发布的 @composio/cli@ 预发布版本:

REPOSITORY=ComposioHQ/composio

gh release list \
  --repo "$REPOSITORY" \
  --limit 100 \
  --json tagName,isPrerelease,isDraft,publishedAt \
  --jq '.[] | select(.tagName | startswith("@composio/cli@")) | select(.isPrerelease and (.isDraft | not))'

对选中的候选,要求它必须是已发布的预发布版本(而非 draft),然后检查其 commit 与资产:

BETA_TAG='@composio/cli@0.0.0-beta.000'

gh release view "$BETA_TAG" \
  --repo "$REPOSITORY" \
  --json tagName,isDraft,isPrerelease,publishedAt,targetCommitish,assets \
  --jq '{tagName,isDraft,isPrerelease,publishedAt,targetCommitish,assets:[.assets[] | {name,state}]}'

合格的 Beta 必须满足 isDraft: falseisPrerelease: true,且以下六个规范资产全部处于 uploaded 状态(这六项与 verify-assets.sh 中的 expected 列表完全一一对应,并与构建矩阵的四个平台保持一致):

  • composio-linux-x64.zip
  • composio-linux-aarch64.zip
  • composio-darwin-x64.zip
  • composio-darwin-aarch64.zip
  • composio-skill.zip(随版本打包的 skills 包)
  • checksums.txt(由 generate-checksums.tsdist/binaries 下所有 zip 生成的校验和)

资产状态为何如此重要?verify-assets.sh 的注释点明了原因:一个资产可以出现在列表里但仍在处理中(state != "uploaded"),这正是发布后出现 404 的典型成因。所以该脚本采用有界重试(默认 VERIFY_ATTEMPTS=10 次、每次间隔 VERIFY_SLEEP_SECONDS=15 秒),且单次快照同时查询名称与状态,避免“检查与使用之间的时间窗口”。

找到 Beta 后,按其目标 commit 定位工作流运行记录,并要求其全绿(包括可复用的安装测试作业):

TARGET_COMMIT='replace-with-targetCommitish'

gh run list \
  --repo "$REPOSITORY" \
  --workflow build-cli-binaries.yml \
  --commit "$TARGET_COMMIT" \
  --limit 10

权限确认点:如果用户只要求“发布稳定版”但没有点名具体 Beta tag,那么你应该先展示解析出的候选,并在派发前停下征得明确确认——稳定版提升是一次生产环境的写入操作。

Build A Manual Beta:显式版本与非版本化 Beta

只有当用户明确要求构建 Beta 时才走这条路。选中的 ref 同时提供工作流定义与源 commit(这正是“该 ref 上定义的工作流构建该 ref 的代码”的原因)。

常规的 next-patch Beta(省略 version):

SOURCE_BRANCH='replace-with-branch'

gh workflow run build-cli-binaries.yml \
  --repo "$REPOSITORY" \
  --ref "$SOURCE_BRANCH" \
  --raw-field action=build-beta

有意的 minor 或 major 版本(必须比最新稳定版更新,例如 0.3.0):

gh workflow run build-cli-binaries.yml \
  --repo "$REPOSITORY" \
  --ref "$SOURCE_BRANCH" \
  --raw-field action=build-beta \
  --raw-field version=0.3.0

版本校验逻辑在 resolve-release-target.sh 中:version 必须匹配 <major>.<minor>.<patch>,且必须大于最新稳定版(version_is_greater 按数值比较,而非字典序——注释明确解释了为何字典序会在 patch 超过 9 时出错)。不传版本时,next_beta_base_version 取最新稳定版并 patch + 1 作为基础版本,最终 tag 形如 @composio/cli@<version>-beta.<RUN_NUMBER>(RUN_NUMBER 保证唯一性)。

派发后要持续观察运行直到发布与安装测试结束。请牢记:Beta 不是稳定版,它不触发 /releases/latest 重定向,也不能被匿名用户通过 install.sh 无参数安装获取(除非显式传 tag)。

Promote A Beta To Stable:从测试过的 Beta 提升稳定版

稳定版 tag 通过去除 Beta 后缀推导(${BETA_TAG%%-beta.*}),例如 @composio/cli@0.3.0-beta.123@composio/cli@0.3.0。先确认目标稳定 tag 的现状:

STABLE_TAG="${BETA_TAG%%-beta.*}"

gh release view "$STABLE_TAG" --repo "$REPOSITORY" --json tagName,isDraft,isPrerelease,publishedAt

按结果分三种情况:

  • 稳定 tag 不存在:可以继续提升;
  • 稳定 tag 是 draft:可以恢复该 draft(见下文失败恢复);
  • 稳定 tag 已发布:立即停止,绝不覆盖已发布的 Release

然后在 Beta tag 上派发工作流——选中的 ref 提供不可变的源 commit,工作流会先验证它与该 Beta Release 的目标 commit 一致,再重新构建:

gh workflow run build-cli-binaries.yml \
  --repo "$REPOSITORY" \
  --ref "$BETA_TAG" \
  --raw-field action=promote-stable

此处 --ref 传入的是 tag 而非分支。若命令返回了 URL 则直接使用;否则通过以下方式定位新派发,核对其创建时间与 actor 后再持续观察:

gh run list \
  --repo "$REPOSITORY" \
  --workflow build-cli-binaries.yml \
  --event workflow_dispatch \
  --commit "$TARGET_COMMIT" \
  --limit 5

gh run watch RUN_ID --repo "$REPOSITORY" --compact --exit-status

promote-stable 的底层防御在 resolve-release-target.sh 中层层把关:

  1. 必须派发在 tag 上(REF_TYPE == "tag"),否则报错退出;
  2. 该 tag 必须匹配 @composio/cli@<version>-beta.<number> 格式;
  3. 通过 GitHub API 校验该 tag 的 Release 确实是 prerelease;
  4. 若稳定 tag 已是 draft 则允许恢复(gh release view 能按名称解析 draft),若已发布则拒绝(REST 的 /releases/tags/{tag} 对 draft 返回 404,因此用 gh release view 判断 isDraft);
  5. 校验 target_commitish 与当前 COMMIT_SHA 完全一致——这保证了“稳定版对应的二进制就是被测试过的那个 Beta 的源码构建产物”。

Verify Completion:发布完成的五重验证

不要在任何一步缺失时宣布发布完成,全部满足才算完成:

  1. Build CLI Binaries 工作流成功结束;
  2. 稳定 Release 已发布,isDraft: falseisPrerelease: false
  3. 六个规范资产全部存在且 uploaded
  4. 工作流的安装测试矩阵通过;
  5. (隐含)提升来源的 Beta 本身是通过全部验证的。

用一条命令核对最终状态:

gh release view "$STABLE_TAG" \
  --repo "$REPOSITORY" \
  --json tagName,isDraft,isPrerelease,publishedAt,targetCommitish,assets \
  --jq '{tagName,isDraft,isPrerelease,publishedAt,targetCommitish,assets:[.assets[] | {name,state}]}'

汇报内容应包含:稳定 tag、被提升的 Beta、目标 commit、工作流 URL、资产数量与状态、安装测试结果。

值得展开的是发布管线内部的“先 draft 后 publish”设计(见 build-cli-binaries.ymlcreate-or-resume-draft.sh):Release 先以 draft 形式创建并附带全部资产——draft 不会触发 release: published 事件,也不会被 /releases/latest 重定向命中,因此任何匿名消费者(install.sh、重定向)都不可能在任何资产挂载并验证完成之前观察到这个发布;随后 verify-assets.sh 作为“响亮失败门”把关,最后一步才用 gh release edit --draft=false --latest=... 将其翻转为已发布。此外,release 作业对同一个 tag 使用 job 级并发组(cli-release-${{ needs.prepare.outputs.release_tag }})做串行化,防止两次快速 push 或重跑交错上传资产。

发布后的安装验证由 cli.test-installation.yml 承担:它作为可复用工作流被 build-cli-binaries.ymlworkflow_call 方式调用,在多平台矩阵(Ubuntu x64 / Ubuntu ARM64、macOS Intel / Apple Silicon,覆盖 bash 与 zsh)上真实执行 install.sh,验证 bundle 与入口符号链接、composio --version 执行、shell 启动文件中的托管 PATH 块(要求恰好一个 managed block,保证幂等)、自定义安装目录、卸载与错误处理等。这也是为什么发布负责人必须等到安装测试矩阵通过才能收工。

Failure Recovery:发布失败的分场景恢复手册

失败场景 处理方式
构建矩阵失败 任何 Release 都不应发布。修复源码,产出新的 Beta,再提升该候选
存在 draft 但发布未完成 检查失败原因后,重跑或重新派发同一个 Beta。draft 的资产可用 --clobber 安全替换(见 create-or-resume-draft.sh 的幂等恢复逻辑)
重复运行提示已发布 这是有意的安全失败。核实已发布的 Release 后停止重复运行。其机制是:按 tag 串行化后,先运行的已发布,后运行的撞上 already published 守卫并响亮地报错,而不是悄悄覆盖线上 Release
发布后安装失败 不要改动已发布的 tag。通过新的 Beta 与下一个稳定 patch 向前修复
TS 发布提示 release PR 无提交 删除指向被忽略 CLI 包的待处理 Changeset,将其说明保留在 CLI 的 CHANGELOG 中,运行 pnpm validate:changesets,让下一次 push 重试 SDK 发布列车

恢复操作的核心原则与源码守卫完全一致:draft 是“可恢复的中间状态”,已发布 tag 是“不可变的事实”。resolve-release-target.shpromote-stable 分支允许恢复 draft(打印 resuming (assets will be re-uploaded)),但遇到已发布 tag 直接 exit 1create-or-resume-draft.sh 同样只有两种情况会安全继续——draft 存在(clobber 重传)或 Release 完全不存在(新建),其余一律报错。理解这层设计后,遇到“红色 ❌”不应盲目重试,而应先确认 tag 的真实状态。

小结:一次发布的生命周期

把整套流程串起来,一次规范的 CLI 发布是这样的闭环:

  1. 合并 PR 到 next(仅 CLI 相关路径)→ 自动构建滚动 Beta;
  2. 基于 GitHub 实时状态挑选并验证候选 Beta(六个资产 uploaded、工作流与安装测试全绿);
  3. 若需要显式版本,派发 build-beta 并携带 version 输入;
  4. 在通过验证的 Beta tag 上派发 promote-stable,由脚本守卫完成 commit 一致性校验与“不覆盖已发布 tag”的保护;
  5. 先 draft 建 Release、校验资产、再翻转为发布,最后等待安装测试矩阵通过;
  6. 汇报稳定 tag、来源 Beta、目标 commit、工作流 URL、资产状态与安装结果;
  7. 若任何环节失败,按失败场景表恢复,且永远“向前修复”而不是改动已发布的 tag。

需要再次强调的是,这套 CLI 二进制发布体系与 TypeScript SDK 的 Changesets 发布是两套并行轨道:CLI 包被 .changeset/config.json 显式 ignore,其版本号由 GitHub Release tag(@composio/cli@<version>[-beta.<n>])唯一权威决定,而不是由 package.json 或 Changeset 决定。理解这条边界,是安全操作 Composio CLI 发布的起点。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525