Composio CLI 发布全流程实战:Build CLI Binaries 工作流、Beta 构建与 Stable 晋升指南
【免费下载链接】composioComposio powers 1000+ toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composio
导读
本篇技术指南围绕 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.json 的ignore列表中,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 发布:
- 归类请求:判断本次请求属于自动 Beta、手动 Beta、Stable 晋升,还是失败恢复。
- 只读预检:运行手册中的只读预检命令,确定确切的源提交(source commit)与发布标签(release tag)。
- 派发并观察:只派发被请求的那个工作流动作(
build-beta或promote-stable),并将返回的 run 观察到结束。 - 验证发布与下游检查:按手册核对已发布的 Release 与下游检查项。
- 汇报结果:报告已发布的标签、源 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_tag、release_version、prerelease、make_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中有两个容易被忽视的实现细节,直接关系到发布正确性:
- 按真实 semver 顺序取最新 Stable:脚本明确注释指出,词法排序在此处是错误的——
@composio/cli@0.2.9在词法上排在0.2.10之后,一旦 patch 进入两位数,last就会选中旧版本导致 Beta 版本倒退。因此它把版本三元组解析成数字并做数值排序(见 resolve-release-target.sh)。 - 滚动 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.json 的ignore列表中,就永远不要为它们创建.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.json的ignore列表,逐一检查待处理 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: false、isPrerelease: true,且以下六个资产全部处于uploaded状态:
composio-linux-x64.zipcomposio-linux-aarch64.zipcomposio-darwin-x64.zipcomposio-darwin-aarch64.zipcomposio-skill.zipchecksums.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.yml的workflow_dispatch输入定义了上述两个参数(见 build-cli-binaries.yml):
action:build-beta或promote-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.sh对promote-stable施加了一系列硬性校验(见 resolve-release-target.sh),值得逐一理解:
- ref 必须是 tag:
REF_TYPE != "tag"时直接报错——promote-stable必须用--ref <beta-tag>派发。 - 标签格式:所选 ref 必须匹配
@composio/cli@<version>-beta.<number>正则。 - Beta 必须是预发布:通过 GitHub API 查询该标签对应的 Release,要求
prerelease == true。 - 禁止重复晋升已发布的 Stable:用
gh release view检查 Stable 标签(注释说明 REST/releases/tags/{tag}对 draft 返回 404,因此用gh release view解析 draft 并暴露isDraft)。若 Stable 已存在且是 draft,允许恢复;已发布则报错退出。 - 提交一致性: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):
- 矩阵全绿才进发布路径:构建矩阵
fail-fast: false——单条腿失败不会取消兄弟任务,而是让所有平台失败同时暴露;更重要的是,release 作业只在needs.build.result == 'success'时运行,而该结果要求每一个矩阵腿都通过,因此局部平台集永远无法到达发布路径(见 build-cli-binaries.yml)。 - 先建 draft 再发布:
create-or-resume-draft.sh以--draft创建 Release 并挂载全部资产。draft 不触发release: published事件,也不会进入/releases/latest重定向,因此任何匿名消费者(install.sh、重定向)在资产挂载并验证完成之前都观察不到这个发布(见 create-or-resume-draft.sh)。 - 发布是唯一的暴露步骤:
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)。
验证完成:四个条件缺一不可
在满足以下全部条件之前,不要宣布发布完成:
Build CLI Binaries工作流成功完成。- Stable Release 已发布,
isDraft: false且isPrerelease: false。 - 六个规范资产全部存在且处于 uploaded 状态。
- 工作流的安装测试矩阵通过。
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.sh 与 install/ 目录是安装器的实现本体,它们同样被列为build-cli-binaries.ymlpush 触发路径的一部分——改动安装器会触发一轮新的 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 发布。
【免费下载链接】composioComposio powers 1000+ toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考