ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Composio CLI Docker E2E 测试体系:在纯净 Debian 容器中验证编译版 composio 二进制的完整实践

2026/9/10 15:33:57 拓冰建站 浏览量
Composio CLI Docker E2E 测试体系:在纯净 Debian 容器中验证编译版 composio 二进制的完整实践 Composio CLI Docker E2E 测试体系在纯净 Debian 容器中验证编译版 composio 二进制的完整实践【免费下载链接】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本文围绕仓库内 Docker CLI E2E 参考文档 展开系统讲解 Composio 仓库如何把bun build --compile编译出的独立composio二进制放进 scratch Debian 容器做端到端验证从测试套件目录约定、Dockerfile 多阶段构建、e2e()/runCmd测试 API到pnpm test:e2e:cli的完整验证流程。读完后你可以理解这套 E2E 体系的隔离模型与输出契约并能为 CLI 新增一个可运行的 E2E 套件。整体架构为什么用 scratch Debian 容器跑 CLICLI E2E 测试的核心思路是不在开发机上直接跑二进制而是把编译好的独立composio可执行文件放进一个尽可能干净的环境执行。架构文档 列出了这套体系的关键属性每个测试套件suite位于ts/e2e-tests/cli/suite-name/目录下每个套件包含e2e.test.ts和package.json两个核心文件每次命令调用都运行在一个全新的容器中避免状态串扰容器内运行时 shell 是 POSIXsh而非 bashHOME/tmp因此任何认证状态和 API 状态必须来自环境变量或命令内自行创建的文件例如whoami套件依赖COMPOSIO_USER_API_KEY环境变量stdout 不是 TTY因此 CLI 的piped-mode管道模式输出规则生效——CLI 会抑制所有装饰性输出彩色、spinner 等只输出机器可读的数据测试正是验证这一契约。CLI E2E README 进一步补充二进制通过bun build --compile在 Docker 镜像构建阶段编译产出一个无运行时依赖的自包含可执行文件测试用runCmd在容器内执行 shell 命令并对退出码、stdout、stderr 做断言。例如composio version out.txt这类重定向场景验证的就是“管道下只有干净数据”这条契约。当前仓库中实际存在的套件包括套件验证内容所需环境变量upgradecomposio upgrade能替换正在运行的 Linux 可执行文件无versioncomposio version的输出与退出码无whoamicomposio whoami打印 API keyCOMPOSIO_USER_API_KEY隔离工具是DockerCLI 版本解析为当前 monorepo 构建cli: [current]。套件模板每个 suite 的标准 package.json参考文档 给出了新增套件时的package.json模板{ name: e2e-tests/cli-suite-name, version: 0.0.0, private: true, type: module, scripts: { typecheck: tsc --noEmit, test:e2e: bun test e2e.test.ts, test:e2e:cli: bun test e2e.test.ts }, devDependencies: { e2e-tests/utils: workspace:* } }对照仓库中的真实套件version 套件的 package.json 与 upgrade 套件的 package.json 与模板完全一致包名为e2e-tests/cli-version/e2e-tests/cli-upgrade唯一依赖是 workspace 内的e2e-tests/utils。这个e2e-tests/cli-*命名不是随意的——仓库根目录 package.json 中定义了聚合命令test:e2e:cli: turbo test:e2e:cli --filtere2e-tests/cli-*也就是说所有 CLI 套件靠包名前缀被 Turbo 一次性筛出并执行这也是为什么新增套件必须遵守模板里的包名规范。镜像构建剖析Dockerfile.cli 的多阶段设计整个 E2E 体系的镜像由 Dockerfile.cli 构建它是参考文档中“scratch Debian 容器”说法的具体落地。构建分两个阶段阶段一buildernode:${NODE_VERSION}-slim通过 mise 安装bun和pnpm版本由 mise.toml/mise.lock 固定Node 则留在基础镜像上先拷贝pnpm-lock.yaml以利用层缓存再拷贝 workspace 配置文件与ts/packages/源码执行pnpm install --frozen-lockfile有意不用--mounttypecache注释说明会导致跨构建的原生绑定问题编译 CLI 二进制bun build ./src/bin.ts \ --env DEBUG_OVERRIDE_* \ --compile \ --production \ --outfile /out/composio构建composio run的伴生模块bun scripts/build-companion-modules.ts /out --host-only。注释里给出了两处体积优化的具体依据——--host-only让打包的 codex-acp 二进制只保留当前镜像平台全部平台会多约 870MB、多约 2 分钟构建时间而镜像永远执行不了那些平台构建完成后立即rm -rf /out/acp-adapters因为 E2E 测试不会调用 ACP 子代理保留它们会多约 224MB且删除与生成在同一层保证完全不进最终镜像。预创建/tmp/.composio目录用于绕过 Bun issue #7967。阶段二最终运行环境debian:bookworm-slimFROM debian:bookworm-slim ENV PATH/usr/local/bin:/bin ENV HOME/tmp二进制和composio run伴生模块一起拷入/usr/local/bin/二者必须保持同级伴生模块从dirname(process.execPath)解析否则 CLI 会认为安装损坏并进入 GitHub self-repair 路径;CLI 缓存目录/tmp/.composio一并拷贝CMD [/bin/sh]与文档中“运行时 shell 是 POSIX sh”的属性对应。HOME/tmp这一行正是参考文档强调的“认证和 API 状态必须来自环境变量或命令 setup”的根因——容器里没有用户目录可依赖测试必须自己构造状态如 version 测试 中用mkdir -p .composio printf ... .composio/update-check.json伪造更新检查结果再配合HOME$PWD让 CLI 读到它。编写测试e2e()、runCmd 与版本套件实战测试代码的入口是e2e-tests/utils源码在 ts/e2e-tests/_utils/src导出的e2e()。从 e2e.ts 的源码看它做了三件事校验传入的import.meta.url必须是file://URL从调用者文件位置自动推断套件工作目录和套件名inferCwd把调用者目录相对仓库根目录规范化为正斜杠路径最后交给runE2E执行。所以测试文件里无需手工声明自己是谁、住在哪个目录。version 套件 是一个完整的参考实现e2e(import.meta.url, { versions: { cli: [current], }, defineTests: ({ runCmd }) { beforeAll(async () { versionResult await runCmd(composio version); // 伪造“存在 99.0.0 新版本”的本地更新检查结果 updateAvailableResult await runCmd( mkdir -p .composio printf %s {lastChecked:2099-01-01T00:00:00.000Z,latestVersion:99.0.0} .composio/update-check.json HOME$PWD composio version --check ); // 捕获容器内生成的文件 redirectedResult await runCmd({ command: composio version out.txt, files: [out.txt], }); }, TIMEOUTS.FIXTURE); // 断言退出码、stdout 快照、stderr 为空、out.txt 内容…… }, });它验证了四个场景composio version的干净输出经sanitizeOutput去 ANSI、规范化换行、去首尾空白后应恰好等于 ts/packages/cli/package.json 中的版本号、--check检测到新版本时输出机器可读 JSONupdateAvailable: true、未知发布状态时不谎报“已是最新”checkStatus: unknown、以及 stdout 重定向到文件后终端无输出而out.txt内容正确。几个值得注意的工具细节文件捕获runCmd({ command, files: [out.txt] })会在执行后把容器内文件拷出作为result.files映射返回专门用于断言“CLI 写盘”的行为见 utils README 的 “runCmd with File Capture” 一节。超时常量TIMEOUTS定义在 const.ts其中DEFAULT: 5_000、FIXTURE: 120_000、LLM_SHORT: 30_000、LLM_LONG: 60_000。CLI 套件的beforeAll统一使用TIMEOUTS.FIXTURE因为它要串行执行多次容器命令。CLI 版本解析WELL_KNOWN_CLI_VERSIONS [current]const.tscurrent解析为ts/packages/cli/package.json中的版本也可通过COMPOSIO_E2E_CLI_VERSION环境变量或config.versions.cli覆盖。环境变量校验传给E2EConfig.env的变量若在启动时值为undefined测试会 fail-fast 并列出缺失变量名避免凭据缺失导致的静默失败。验证与运行从仓库根到单个套件参考文档给出的验证方式有两层全量运行仓库根目录pnpm test:e2e:cli该命令经 Turbo 用--filtere2e-tests/cli-*命中所有 CLI 套件并执行各自的test:e2e:cli脚本即bun test e2e.test.ts。迭代单个套件时聚焦运行参考文档建议“使用聚焦的 Turbo filter”CLI README 给出了等价的直接进入套件目录的方式cd ts/e2e-tests/cli/version pnpm test:e2e:cli cd ts/e2e-tests/cli/whoami pnpm test:e2e:cli cd ts/e2e-tests/cli/upgrade pnpm test:e2e:cli前置条件是本地已安装 Docker镜像构建与容器执行都依赖它whoami套件还需要在环境中提供COMPOSIO_USER_API_KEY。每次运行会生成结构化的DEBUG.log按运行时版本分组记录容器名、命令、耗时、退出码与 stdout/stderr 全量输出便于排查容器内命令失败的原因。小结与关键路径这套体系的设计取舍可以概括为三点用 scratch 容器排除本机环境噪声POSIX sh、HOME/tmp、每次命令全新容器用 piped-mode 输出契约保证测试断言的机器可读性用包名规范 Turbo filter 让套件数量增长时聚合命令自动扩展。新增一个 CLI E2E 套件时只需按e2e-tests/cli-suite-name模板建目录、写e2e.test.ts、复用Dockerfile.cli即可自动纳入pnpm test:e2e:cli。关键文件索引架构与套件模板.agents/skills/cli-e2e/references/docker-cli-e2e.md套件总览与运行说明ts/e2e-tests/cli/README.md镜像构建ts/e2e-tests/_utils/Dockerfile.cli测试框架实现ts/e2e-tests/_utils/src/e2e.ts、ts/e2e-tests/_utils/src/const.ts工具 API 文档ts/e2e-tests/_utils/README.md参考实现ts/e2e-tests/cli/version/e2e.test.ts聚合命令package.json 中的test:e2e: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),仅供参考