首页
/ Composio CLI 发布全流程实战:Build CLI Binaries 工作流、Beta 构建与 Stable 晋升指南

Composio CLI 发布全流程实战:Build CLI Binaries 工作流、Beta 构建与 Stable 晋升指南

2026-09-09 10:06:31作者:伍希望

导读

本篇技术指南围绕 Composio 仓库中驱动独立 composio 二进制与安装器的 GitHub Release 流程展开,系统讲解如何通过 build-cli-binaries.yml 工作流完成自动 Beta 构建、手动 Beta 发布、Stable 晋升、发布后资产与安装验证,以及失败发布恢复。读完本文,你将掌握:何时该走 Beta 路径、何时该晋升 Stable、为什么 CLI 包绝不允许创建 Changeset、如何用 gh 命令核对候选版本并安全派发 promote-stable,以及如何判断一次发布是否真正完成。

本文基于仓库内 .agents/skills/cli-release/SKILL.md 及其配套手册 .agents/skills/cli-release/references/release-workflow.md 整理,并结合 build-cli-binaries.yml.github/scripts/cli-release 下的脚本实现进行源码级佐证。

发布契约:四条不可逾越的规则

在接触任何命令之前,先理解 CLI 发布流程的约束。这些规则决定了整个工作流的形态:

  • 绝不添加针对 @composio/cli@composio/cli-local-tools 的 Changeset。这两个包在 .changeset/config.jsonignore 列表中,Changesets 会忽略它们;一旦有人为它们添加 .changeset/*.md 条目,会卡死 ts.release.yml 的 TypeScript SDK 发布列车(具体机制见下文"Changeset 规则"一节)。
  • 合并到 next 分支且触碰 CLI 路径的提交 = 一次自动 Beta 构建。Beta 经过测试后,通过 promote-stable 工作流动作走正常 Stable 发布路径晋升。
  • 永远不要通过改动私有 CLI 的 package.json 来选择二进制版本。仓库中 ts/packages/cli/package.json 的版本字段是开发期哨兵值 0.0.0-development(见 ts/packages/cli/package.json),它不参与版本选择。若需要有意的 minor 或 major 版本,先构建一个显式指定版本的 Beta,再晋升这个经过测试的 Beta。
  • 在采取动作前,立即从 GitHub 解析 Beta 标签和工作流状态,绝不凭记忆虚构或复用过期的候选版本。Stable 晋升是生产写入操作,如果用户没有指名确切的 Beta 标签,必须先展示解析出的候选版本并取得明确确认,再派发。

发布流程的最后一步要求全程跟进:从派发成功到资产验证、安装测试全部通过之前,都不算完成

执行五步法

按以下步骤执行一次 CLI 发布:

  1. 归类请求:判断本次请求属于自动 Beta、手动 Beta、Stable 晋升,还是失败恢复。
  2. 只读预检:运行手册中的只读预检命令,确定确切的源提交(source commit)与发布标签(release tag)。
  3. 派发并观察:只派发被请求的那个工作流动作(build-betapromote-stable),并将返回的 run 观察到结束。
  4. 验证发布与下游检查:按手册核对已发布的 Release 与下游检查项。
  5. 汇报结果:报告已发布的标签、源 Beta 或提交、工作流 URL、资产状态、安装测试结果,以及任何遗留的后续事项。

真相源:谁来定义发布行为

手册明确列出了五个"真相源"文件,它们共同构成了 CLI 发布的权威定义:

真相源 职责
.github/workflows/build-cli-binaries.yml 拥有 Beta 与 Stable 的 GitHub Release 构建
.github/scripts/cli-release/resolve-release-target.sh 决定标签与源提交
.github/scripts/cli-release/verify-assets.sh 定义必需的资产集合
.github/workflows/cli.test-installation.yml 发布后验证安装器
.changeset/config.json 忽略 @composio/cli@composio/cli-local-tools 两个包

需要特别澄清:ts.release.yml 是 TypeScript SDK/npm 发布列车,它不是 CLI 二进制发布的正常路径。CLI 二进制走的是 build-cli-binaries.yml

从源码看,resolve-release-target.sh 是版本决策的核心:它对 push 事件、build-beta 派发、promote-stable 派发三种模式分别输出 release_tagrelease_versionprereleasemake_latest 等元数据(见 resolve-release-target.sh),供后续 build 与 release 作业消费。

选择路径:四种场景一张表

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

一个值得展开的细节:私有 CLI 的 package.json 使用开发期哨兵值,永远不参与选择二进制版本。如果发布负责人需要有意的 minor 或 major 版本,正确做法是派发一个显式版本号的 Beta,验证它,然后晋升这个确切的 Beta——而不是去改 package.json

版本决策的源码细节

resolve-release-target.sh 中有两个容易被忽视的实现细节,直接关系到发布正确性:

  1. 按真实 semver 顺序取最新 Stable:脚本明确注释指出,词法排序在此处是错误的——@composio/cli@0.2.9 在词法上排在 0.2.10 之后,一旦 patch 进入两位数,last 就会选中旧版本导致 Beta 版本倒退。因此它把版本三元组解析成数字并做数值排序(见 resolve-release-target.sh)。
  2. 滚动 Beta 标签格式:无显式版本时,Beta 基础版本为"最新 Stable 的 patch+1",标签形如 @composio/cli@<version>-beta.<RUN_NUMBER>,其中 RUN_NUMBER 保证每次运行唯一(见 resolve-release-target.sh)。显式版本必须满足 <major>.<minor>.<patch> 格式,且必须高于最新 Stable,否则脚本直接报错退出。

Changeset 规则:为什么 CLI 包被 Changesets 忽略

规则:只要 @composio/cli@composio/cli-local-tools 还留在 .changeset/config.jsonignore 列表中,就永远不要为它们创建 .changeset/*.md 条目。

原因(这是仓库中的真实故障模式):为被忽略的包添加 Changeset 会让 changesets/action 进入版本 PR 模式,但 changeset version 不会产生任何提交。于是 action 报错 No commits between next and changeset-release/next,阻塞无关的 SDK 发布。

这个故障机制在 ts/scripts/validate-changesets.mjs 中有完整的实现与报错文案印证:脚本读取 .changeset/config.jsonignore 列表,逐一检查待处理 changesets 的 release 目标,一旦发现指向被忽略包,就抛出错误并说明上述机制(见 validate-changesets.mjs)。

如果 CLI 变更需要面向用户的说明:直接更新 ts/packages/cli/CHANGELOG.md。该文件以 "Unreleased" 小节维护未发布变更(如升级命令的 spinner、下载进度、归档瘦身等补丁说明,见 ts/packages/cli/CHANGELOG.md)。交接前运行此守卫命令:

pnpm validate:changesets

检查候选版本:只用 GitHub 实时状态

不要从本地 tag 或记忆中的版本挑选 Beta。使用实时 GitHub 状态:

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))'

对选中的候选版本,要求它是已发布的预发布(published prerelease),并检查其提交与资产:

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 状态:

  • composio-linux-x64.zip
  • composio-linux-aarch64.zip
  • composio-darwin-x64.zip
  • composio-darwin-aarch64.zip
  • composio-skill.zip
  • checksums.txt

这六项清单在 verify-assets.sh 中定义,脚本注释明确要求它与 build-cli-binaries.yml 的四平台构建矩阵保持同步。为什么必须检查 state == "uploaded" 而非仅仅"存在于资产列表"?verify-assets.sh 的注释给出了答案:资产可能出现在列表中但仍在处理中(state != "uploaded"),这正是发布对外提供 404 的确切原因。脚本还采用"单次快照"方式查询——分别查询名称和状态会打开一个 time-of-check/time-of-use 间隙(见 verify-assets.sh)。

接着,按目标提交找到 Beta 的工作流运行,要求其全绿,包括可复用的安装测试作业

TARGET_COMMIT='replace-with-targetCommitish'

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

关键确认点:如果用户要求 Stable 发布但没有指名 Beta,展示解析出的候选版本,停下来等待确认再派发。Stable 晋升是生产写入,不能擅自执行。

构建手动 Beta

仅当用户明确要求构建 Beta 时才使用此路径。所选 ref 同时提供工作流定义与源提交。省略 version 得到常规的 next-patch Beta;提供确切的 major.minor.patch 基础版本则用于有意的 minor 或 major 发布。

SOURCE_BRANCH='replace-with-branch'

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

对于有意的 minor 或 major,提供比最新 Stable 更新的版本:

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

将返回的 run 观察到发布与安装测试结束。记住:Beta 不是 Stable 发布,它只是候选。

工作流侧的参数定义

build-cli-binaries.ymlworkflow_dispatch 输入定义了上述两个参数(见 build-cli-binaries.yml):

  • actionbuild-betapromote-stable,默认 build-beta
  • version:可选 semver 基础版本(如 0.3.0);省略时取最新 Stable 的下一个 patch。

派发时,resolve-release-target.sh 会校验:显式版本必须匹配 ^[0-9]+\.[0-9]+\.[0-9]+$,且必须高于最新 Stable;无版本时自动计算 next-patch(见 resolve-release-target.sh)。

晋升 Beta 到 Stable

首先从 Beta 标签推导 Stable 标签——去掉 beta 后缀

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

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

三种情况三种处理:

  • Stable 标签不存在:晋升可以进行。
  • 它是 draft:晋升可以恢复它。
  • 它已发布:停止。永远不要覆盖已发布的 Release

然后在 Beta 标签上派发工作流。所选 ref 提供不可变的源提交,工作流会校验它确实与 Beta 发布匹配,再重新构建:

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

晋升的源码级校验链

resolve-release-target.shpromote-stable 施加了一系列硬性校验(见 resolve-release-target.sh),值得逐一理解:

  1. ref 必须是 tagREF_TYPE != "tag" 时直接报错——promote-stable 必须用 --ref <beta-tag> 派发。
  2. 标签格式:所选 ref 必须匹配 @composio/cli@<version>-beta.<number> 正则。
  3. Beta 必须是预发布:通过 GitHub API 查询该标签对应的 Release,要求 prerelease == true
  4. 禁止重复晋升已发布的 Stable:用 gh release view 检查 Stable 标签(注释说明 REST /releases/tags/{tag} 对 draft 返回 404,因此用 gh release view 解析 draft 并暴露 isDraft)。若 Stable 已存在且是 draft,允许恢复;已发布则报错退出。
  5. 提交一致性:Beta release 的 target_commitish 必须等于当前派发所用的 COMMIT_SHA,否则报错——这保证了晋升确实来自被测试过的那个提交。

使用返回的 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

晋升路径上的三道发布安全门

build-cli-binaries.yml 的 release 作业围绕"先 draft、后发布"设计了三道闸门(见 build-cli-binaries.yml):

  1. 矩阵全绿才进发布路径:构建矩阵 fail-fast: false——单条腿失败不会取消兄弟任务,而是让所有平台失败同时暴露;更重要的是,release 作业只在 needs.build.result == 'success' 时运行,而该结果要求每一个矩阵腿都通过,因此局部平台集永远无法到达发布路径(见 build-cli-binaries.yml)。
  2. 先建 draft 再发布create-or-resume-draft.sh--draft 创建 Release 并挂载全部资产。draft 不触发 release: published 事件,也不会进入 /releases/latest 重定向,因此任何匿名消费者(install.sh、重定向)在资产挂载并验证完成之前都观察不到这个发布(见 create-or-resume-draft.sh)。
  3. 发布是唯一的暴露步骤gh release edit "$RELEASE_TAG" --draft=false --latest="$MAKE_LATEST" 是最后一个动作。脚本注释提醒不要在同一调用中编辑正文——已知的 GitHub PATCH 竞态会丢失与 draft 翻转同次调用中的正文修改,而 release notes 在 draft 创建时已生成。

此外还有按标签串行化:release 作业的 concurrency 组以解析出的标签为键(cli-release-${{ needs.prepare.outputs.release_tag }}),cancel-in-progress: false。两个快速 push 或重跑竞态时,串行输家会在 create-or-resume-draft.sh 的 "already published" 守卫处响亮失败——那个红 ❌ 是设计使然(见 build-cli-binaries.yml)。

验证完成:四个条件缺一不可

在满足以下全部条件之前,不要宣布发布完成:

  1. Build CLI Binaries 工作流成功完成。
  2. Stable Release 已发布,isDraft: falseisPrerelease: false
  3. 六个规范资产全部存在且处于 uploaded 状态。
  4. 工作流的安装测试矩阵通过。
gh release view "$STABLE_TAG" \
  --repo "$REPOSITORY" \
  --json tagName,isDraft,isPrerelease,publishedAt,targetCommitish,assets \
  --jq '{tagName,isDraft,isPrerelease,publishedAt,targetCommitish,assets:[.assets[] | {name,state}]}'

汇报内容应包含:Stable 标签、被晋升的 Beta、目标提交、工作流 URL、资产数量与状态、安装结果。

安装测试:发布后的独立验证

build-cli-binaries.yml 在发布成功后通过 uses: ./.github/workflows/cli.test-installation.yml 调用可复用安装测试工作流(见 build-cli-binaries.yml),传入刚发布的标签作为版本。这条 test-installation 作业独立于 build/release 链,专门验证安装器在发布之后依然可用。

失败恢复:五种场景的处置方案

失败场景 处置方案
构建矩阵失败 不应发布任何 Release。修复源码、产出新 Beta、晋升该候选版本
存在 draft 但发布未完成 检查失败原因,然后重跑或重新派发同一 Beta。draft 资产可安全地用 --clobber 替换
重复运行提示 Release 已发布 这是故意的安全失败。核实已发布的 Release 并停止重复运行
发布后安装测试失败 不要改动已发布的标签。通过新 Beta 与下一个 Stable patch 向前修复
TS 发布提示 release PR 无提交 移除指向被忽略 CLI 包的待处理 Changeset,把说明保留到 CLI changelog,运行 pnpm validate:changesets,让下一次 push 重试 SDK 发布列车

前两种场景对应 create-or-resume-draft.sh 的两条分支:检测到已存在 draft 时用 gh release upload ... --clobber 重传资产(幂等恢复);检测到标签已发布时输出错误并退出,拒绝改动线上发布(见 create-or-resume-draft.sh)。

发布产物形态:安装方式与配套资产

发布产物的消费端是安装器与 CLI 升级逻辑。工作流中的 create-install-instructions 作业会生成一份 INSTALL.md,展示三类安装方式:

  • 快速安装curl -fsSL https://composio.dev/install | sh,安装器会自动把 CLI 目录加入 zsh/bash/fish 的 PATH,重复运行不会产生重复条目。
  • 跳过 shell 配置COMPOSIO_INSTALL_SHELL=none 适合 CI 与 Docker 场景;也可显式指定 COMPOSIO_INSTALL_SHELL=zsh|bash|fish
  • 指定版本安装sh -s -- <release_tag>

手动安装时注意:CLI 会加载可执行文件旁边随附的支持文件,不要只把嵌套的 composio 文件单独移走。安装后可用 composio install --shell zsh|bash|fish 把 CLI 永久加入 PATH

仓库根目录的 install.shinstall/ 目录是安装器的实现本体,它们同样被列为 build-cli-binaries.yml push 触发路径的一部分——改动安装器会触发一轮新的 CLI 构建(见 build-cli-binaries.yml)。

归档配套校验:升级兼容性的守护

发布构建中还有一个容易被忽略的校验——verify-archive-companions.sh 检查每个发布归档的 codex-acp 适配器布局(见 verify-archive-companions.sh):

  • 四个平台路径必须齐全:缺失任一路径会破坏 2026-08-18 之前发布的 CLI 的 composio upgrade——旧客户端会按全部四个 codex-acp 路径验证下载的包,缺一个就拒绝。
  • 只在本平台路径放真实字节:归档只携带本机平台可执行的 codex-acp 二进制,其余三个平台是空占位符。这避免了"几百 MB 永远无法执行的死重"下载。

该脚本注释说明,这些打包规则还有单测覆盖,而此闸门是唯一检查真实归档的地方,防止打包管线改动悄悄回归(见 verify-archive-companions.sh)。

发布后的维护提醒

工作流中还有一个 continue-on-error 的软检查:烘焙的 toolkit slugs 新鲜度。composio execute 会根据烘焙的 toolkit slugs 决定本地解析 toolkit 还是付费进行 catalog 拉取——过期的列表不会出错,只会变慢。若 ts/packages/cli/src/generated/toolkit-slugs.ts 中的刷新时间超过 14 天,工作流会输出 warning,提示运行 "CLI - Update Toolkit Slugs" 工作流刷新(见 build-cli-binaries.yml)。这类软警告不阻塞发布,但属于发布负责人应知晓的后续事项。

小结

Composio CLI 的发布体系可以概括为一句话:一切发布都是 Beta 的产物,Stable 只晋升、从不重写。合并到 next 自动产生滚动 Beta;有意的版本变更通过显式版本 Beta 表达;Stable 晋升严格绑定被测试过的 Beta 提交,并以"draft 先行、资产验证、最后翻转发布"的顺序对外暴露;任何失败都优先向前修复而非回改线上标签。遵循 .agents/skills/cli-release/references/release-workflow.md 中的路径选择表、候选检查命令与完成验证清单,配合 pnpm validate:changesets 守卫,即可安全、可审计地完成一次 CLI 发布。

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
900
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
927
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
603
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
397
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525