ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Oh My CodeX CI 加速实战:用 dist 产物复用与聚焦门禁消除重复构建工作

Oh My CodeX CI 加速实战:用 dist 产物复用与聚焦门禁消除重复构建工作 Oh My CodeX CI 加速实战用 dist 产物复用与聚焦门禁消除重复构建工作【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex本文是一份围绕 Oh My CodeX 仓库 CI 工作流精简改造的技术指南。项目当前的持续集成见 .github/workflows/ci.yml曾长期在多个并行 lane 中重复执行依赖安装、TypeScript 类型检查、构建与仅报告性质的覆盖率统计本指南完整解析这套保留发布安全信号、削减重复劳动的清理方案单一 Node 20 构建产物如何供给编译后测试与覆盖率门禁、Node 22 如何以聚焦 smoke lane 保留跨运行时信心、昂贵的全量覆盖率报告为何从必需路径中移除以及 Rust 覆盖率摘要 lane 与crates/omx-sparkshell清单路径的落地方式。读完本文你将掌握如何在不牺牲发布安全性的前提下设计出可审查、可维护、fail-closed 的增量式 CI 架构并理解与之配套的本地验证命令与 PR 模板校验清单的对应关系。一、问题背景CI 中重复劳动从何而来Oh My CodeX 是一个同时包含 TypeScript 源码CLI、配置、Agent 编排、MCP 服务器、Hooks、团队模式、验证逻辑与多个 Rust crateomx-api、omx-explore、omx-mux、omx-runtime、omx-runtime-core、omx-sparkshell的多语言仓库。早期 CI 的痛点在于重复依赖安装多个测试与覆盖率 lane 各自执行npm ci同一份依赖树被反复安装重复类型检查TypeScript-only 检查在多个运行时矩阵上重复执行重复构建测试 lane 与覆盖率 lane 各自执行npm run builddist被反复编译报告型覆盖率冗余全量 TypeScript 与全量 Rust 的覆盖率 artifact 报告report-only每次 CI 运行都会生成却只用于产出报告、不充当发布门禁。清理的目标非常明确保留 release-safety 信号减少重复工作。改造后的 CI 将测试、类型检查、覆盖率三种信号分别交给最合适的 lane避免任何一条路径做两遍相同的事。该 PR 的清理理由与验证命令已记录于 docs/prs/dev-ci-slowness-cleanup.md本节及后续内容即围绕其展开。二、方案总览四个关键设计决策清理方案的核心骨架可以概括为四条原则它们共同决定了新的 CI 拓扑一个 Node 20 构建产物喂养所有编译后 lanebuild-distjob 只构建一次dist以ci-dist-node20artifact 形式上传后续test、coverage-team-critical、ralph-persistence-gate、build、native-cache-integrity等 lane 直接下载复用不再各自重建TypeScript-only 检查收敛到单一运行时typechecklane 不再使用运行时矩阵只在 Node 20 上跑npx tsc --noEmit与npm run check:no-unused同时保留check:no-unused门禁Node 22 保留为聚焦 smoke lane跨运行时信心由test矩阵中的node-version: 22 / lane: smoke分支承担避免清理掉全部跨运行时信号覆盖率从报告 artifact收敛为必需门禁全量 TypeScript/Rust 覆盖率 artifact 报告不再进入必需 CI 状态路径保留两类必需信号——Rust 测试/覆盖率摘要workspace crates/omx-sparkshell/Cargo.toml以及强制的 team/state 覆盖率门禁。这一拓扑在每个 job 上都体现为明确的if:条件与needs:依赖且全部 job 都定义了timeout-minutes避免卡死的 Actions 运行无限挂起该约定被 src/verification/tests/ci-rust-gates.test.ts 逐一断言。三、核心机制一单一 dist artifact 的构建与复用3.1 构建一次build-distjobbuild-dist是编译后消费方的前置依赖其要点见 .github/workflows/ci.yml使用 Node 20 cache: npm的setup-node执行npm ci --ignore-scripts跳过生命周期脚本保证构建环境干净执行npm run build——对应 package.json 中定义的构建脚本先清空dist再跑tsc最后为dist/cli/omx.js设置可执行位通过actions/upload-artifactv4以ci-dist-node20名称上传dist/并设置if-no-files-found: error强制产物必须存在。3.2 复用多次消费方统一下载test、coverage-team-critical、ralph-persistence-gate、build、native-cache-integrity五个 job 均以needs: [changes, build-dist]声明依赖并通过actions/download-artifactv8将ci-dist-node20解压到dist目录。以testjob 为例.github/workflows/ci.yml在npm ci之后、执行测试之前先下载预构建产物再调用node dist/scripts/run-test-files.js test-roots运行分组测试。测试断言明确要求消费方 lane 中不得出现npm run build见 src/verification/tests/ci-rust-gates.test.ts从而把重复编译从结构上杜绝。3.3 编译后脚本与源码检出模式预构建产物的一个隐含前提是仓库中提供编译后版本的执行入口供已下载dist的 CI lane 使用。例如 src/scripts/run-compiled-ci.ts 会根据工作区特征判断运行场景通过src/catalog/manifest.json、docs/troubleshooting.md、.github/workflows/ci.yml三个哨兵文件判定为源码检出时依次执行verify:native-agents、verify:plugin-bundle、verify:capabilities-lock、verify:prompt-guidance、test:node与 catalog 文档校验否则按已安装包模式运行smoke-packed-install、nested-help-routing、mcp-parity等测试并对omx各子命令--help、version、api、sparkshell、notepad、project-memory、trace、code-intel做 CLI 冒烟。该脚本的OMX_AUTO_UPDATE0、OMX_NOTIFY_FALLBACK0、OMX_HOOK_DERIVED_SIGNALS0环境变量注入也保证了在 CI 上下文中不会触发自动更新或通知回退等副作用。四、核心机制二类型检查单运行时化 Node 22 聚焦 smoke lane4.1typecheck从矩阵收敛到单运行时改造前的 TypeScript-only 检查在多个 Node 版本上重复执行改造后typecheckjob 移除matrix:固定在 Node 20 上执行两条命令.github/workflows/ci.ymlnpx tsc --noEmit npm run check:no-unused其中check:no-unused对应 package.json 的tsc -p tsconfig.no-unused.json用于检查未使用的局部变量与参数是原文档明确要求保留的门禁。测试 src/verification/tests/ci-rust-gates.test.ts 断言typecheckjob 不含matrix:、固定node-version: 20同时要求testjob 中存在 Node 22 的 smoke 分支以此锁定类型检查只跑一遍、跨运行时验证由 smoke 承担的契约。4.2test矩阵Node 20 三 lane Node 22 smoketestjob 的矩阵.github/workflows/ci.yml采用include方式精确定义node-versionlane测试目录test-rootscatalog-check20team-state-runtimedist/team/__tests__、dist/state/__tests__、dist/ralph/__tests__、dist/ralplan/__tests__、dist/runtime/__tests__false20hooks-notify-platformdist/hooks/__tests__、dist/hooks/code-simplifier/__tests__、dist/hooks/extensibility/__tests__、dist/notifications/__tests__、dist/mcp/__tests__、dist/hud/__tests__、dist/verification/__tests__、dist/openclaw/__tests__false20cli-core-restdist/autopilot/__tests__、dist/cli/__tests__、dist/agents/__tests__、dist/autoresearch/__tests__、dist/catalog/__tests__、dist/compat/__tests__、dist/config/__tests__、dist/modes/__tests__、dist/planning/__tests__、dist/scripts/__tests__、dist/session-history/__tests__、dist/subagents/__tests__、dist/utils/__tests__、dist/visual/__tests__true22smoke不指定 test-roots走独立冒烟步骤falsesmoke lane 的职责由两段步骤承担.github/workflows/ci.yml一是执行npm run test:team:cross-rebase-smoke:compiled验证跨 rebase 冒烟二是通过node --test直接跑一组打包/契约/explore/sparkshell/compat 测试如packaged-script-resolution、package-bin-contract、explore、sparkshell-cli、smoke-packed-install等。这正是原文档 reviewer notes 中保留 Node 22 smoke lane避免清理掉全部跨运行时信号的落地实现。4.3OMX_NODE_TEST_FORCE_EXIT自托管残留句柄的兜底对于team-state-runtime与hooks-notify-platform两个 laneCI 通过OMX_NODE_TEST_FORCE_EXIT1强制 Node 测试运行器在完成后退出.github/workflows/ci.yml规避自托管 runner 上进程/平台句柄残留导致的挂起——这是与超时兜底并列的又一层稳定性设计。五、核心机制三覆盖率从报告 artifact收敛为必需门禁5.1 移除 report-only 全量覆盖率 job原文档明确report-only full TypeScript and Rust coverage artifact jobs从必需 CI 状态路径中移除。所谓 report-only是指这些 job 只生成覆盖率报告 artifact不参与任何发布/合并门禁判定却消耗昂贵的构建与测试时间。对应测试 src/verification/tests/ci-rust-gates.test.ts 断言工作流中不存在coverage-ts-full:job也不存在needs.coverage-ts-full.result引用。需要说明的是仓库仍然保留了全量覆盖率脚本package.json 中的coverage:ts:full/coverage:ts:full:compiled使用c8 --all --src dist并输出到coverage/ts-full它们作为本地贡献者按需使用的工具存在只是不再进入每次 CI 的必需路径。5.2 保留的必需门禁一team/state 覆盖率coverage-team-criticaljob.github/workflows/ci.yml是强制门禁而非报告它下载ci-dist-node20产物后执行npm run coverage:team-critical:compiled该命令对应 package.jsonc8 --all --src dist/team --src dist/state \ --include dist/team/**/*.js --include dist/state/**/*.js \ --exclude **/__tests__/** \ --reportertext-summary --reporterlcov --reporterjson-summary \ --report-dir coverage/team \ --check-coverage \ --lines78 --functions90 --branches70 --statements78 \ node dist/scripts/run-test-files.js dist/team/__tests__ dist/state/__tests__要点拆解作用域仅覆盖dist/team与dist/state多 Agent 团队编排与状态管理是发布安全最敏感的区域排除测试文件自身阈值行覆盖率 ≥ 78%、函数覆盖率 ≥ 90%、分支覆盖率 ≥ 70%、语句覆盖率 ≥ 78%由--check-coverage强制未达标即失败报告输出同时产出 text-summary、lcov、json-summary 三种格式job 随后读取coverage/team/coverage-summary.json将 Lines/Functions/Branches/Statements 汇总表写入 GitHub Step Summary并上传team-critical-coverageartifact 供归档本地对应CONTRIBUTING.md 记录了同一门禁的本地命令npm run coverage:team-critical说明 CI 与本地行为一致本地版本先npm run build再跑 compiled 版本。该门禁的语义在本次清理中未变原文档 validation 中注明coverage:team-critical:compiled未在本地重跑因为它在 CI 中语义不变只是消费方改用了预构建产物。5.3 保留的必需门禁二Rust 测试 覆盖率摘要Rust 侧不再产出昂贵的全量覆盖率 artifact 报告取而代之的是rust-testsjob.github/workflows/ci.yml中的测试 摘要模式mkdir -p coverage/rust cargo llvm-cov --workspace --summary-only | tee coverage/rust/workspace-summary.txt cargo llvm-cov --manifest-path crates/omx-sparkshell/Cargo.toml --summary-only | tee coverage/rust/omx-sparkshell-summary.txt两点值得注意--summary-only意味着只输出摘要文本、不生成 lcov/JSON 等重型 artifact测试 src/verification/tests/ci-rust-gates.test.ts 明确断言rust-testsjob 中不得出现--lcov、output-path或Upload Rust coverage artifact步骤显式点名crates/omx-sparkshell/Cargo.toml由于该 crate 不在默认 workspace 成员的常规测试路径内其 manifest 位于 crates/omx-sparkshell/Cargo.toml声明二进制omx-sparkshell并依赖omx-mux必须用--manifest-path单独执行覆盖否则其测试与覆盖率信号会静默丢失。两条摘要随后以 code block 形式写入 job summary供 PR 审查者直接查看。六、lane 检测与 fail-closed 门禁让精简可审查精简不是一刀切而是让每个 job 依据改动范围决定是否激活。changesjob.github/workflows/ci.yml用一次git diff计算出八个输出full_suite、docs_changed、docs_only、ts_changed、rust_changed、native_changed、shared_config_changed、reason分类规则包括docs/、missions/、README/CHANGELOG 等 → docs 类src/**/*.ts|tsx|mts|cts、src/compat/fixtures/、playground/→ TS 类crates/、Cargo.lock、Cargo.toml→ Rust 类dist-workspace.toml、crates/omx-(api|explore|mux|runtime-core|runtime|sparkshell)/→ native 类.github/、templates/、prompts/、skills/、plugins/、biome.json、tsconfig*.json、package(-lock).json、Cargo.*、dist-workspace.toml→ shared config 类。fail-closed 设计是这套系统的安全底线测试见 src/verification/tests/ci-rust-gates.test.ts命中 shared config 或存在无法归类的路径unknown.length 0时强制full_suitetrue宁可多跑不可漏检无法解析 diff 提交、空 diff 等场景同样强制全量刻意不使用workflow 级的paths:/paths-ignore:过滤触发器.github/workflows/ci.yml因为路径级触发器会让required checks进入 pending 状态而无法满足合并要求测试断言见 src/verification/tests/ci-rust-gates.test.ts。最终由ci-status聚合 job.github/workflows/ci.yml统一判定对每个 lane激活时必须是success未激活时允许success或skipped否则报错并输出失败清单与 lane 选择原因。这套语义在 src/verification/tests/ci-rust-gates.test.ts 中被建模为 8 种组合的确定性真值表。七、本地验证命令与 PR 模板清单的映射7.1 PR 模板的验证基线.github/PULL_REQUEST_TEMPLATE.md 要求普通贡献以dev为基分支与 CONTRIBUTING.md 一致并在 Validation 段列出三条基线命令npm run build、npm test、omx doctor仅当 setup/config 行为变化时。本 PR 的清理文档刻意补充了这些基线命令与 CI lane 的对应关系让审查者能快速核对本地跑过什么、CI 会跑什么。7.2 本 PR 的验证矩阵摘自原文档 Validation 段命令作用结果python3yaml.safe_load(.github/workflows/ci.yml)解析工作流并确认 job 元数据存在通过npx tsc --noEmitTypeScript 类型检查通过npm run check:no-unusedno-unused 门禁对应 CItypechecklane通过npm run lintBiome lintsrc通过npm run build编译dist通过node --test dist/verification/__tests__/ci-rust-gates.test.js dist/cli/__tests__/package-bin-contract.test.js工作流/包契约测试含必需 Rust 测试/覆盖率摘要门禁通过python3断言 job 图确认 report-only 覆盖率 job 已移除、必需门禁仍在通过cargo llvm-cov --workspace --summary-only与cargo llvm-cov --manifest-path crates/omx-sparkshell/Cargo.toml --summary-onlyRust 测试与覆盖率摘要含 sparkshell 清单路径通过npm test未本地执行本 PR 专门移除全量套件冗余改用定向测试未运行npm run coverage:team-critical:compiled未本地执行门禁在 CI 中语义不变未运行omx doctor未执行setup/config 行为未变不需要这份矩阵本身就是可审查性的体现哪些命令必须本地跑、哪些可以依赖 CI、为什么可以依赖都被显式记录。对贡献者的实操建议是常规改动按 CONTRIBUTING.md 的本地预部署顺序执行——npm ci→npm run lint→npm run check:no-unused→npx tsc --noEmit涉及 team/state 的改动再追加npm run coverage:team-critical。八、Reviewer 关注点与未来维护红线原文档的 Reviewer notes 给出了三条维护红线与源码证据一一对应保留 Node 22 smoke lane跨运行时信号只能被聚焦不能被清除对应 .github/workflows/ci.yml 与测试断言 src/verification/tests/ci-rust-gates.test.tsCI 中优先使用编译后覆盖率命令coverage-team-critical等 lane 在下载 artifact 之后应调用*:compiled变体如coverage:team-critical:compiled源码级覆盖率脚本如coverage:team-critical前段的npm run build留给本地贡献者按需使用npm ci移除需谨慎若未来从消费 artifact 的 job 中移除npm ci必须确认所需 CLI/dev 依赖均已由 artifact 或显式 setup 步骤提供否则下载的dist将缺少运行时依赖。测试 src/verification/tests/ci-rust-gates.test.ts 当前仍要求每个消费 job 保留npm ci与 npm 缓存且不使用actions/cachev4直接缓存node_modules——这是干净依赖 预构建产物复用两条原则的并存结构。九、小结本次 CI 精简以信号不丢、重复必除为纲dist只构建一次并由所有编译后 lane 复用类型检查收敛到单一 Node 20 运行时Node 22 以 smoke lane 形式保留跨运行时信心覆盖率从每次必出报告收敛为必需门禁 按需本地报告Rust 侧则以--summary-only摘要取代重型 artifact 并显式覆盖crates/omx-sparkshell清单路径。整套拓扑由changes的 lane 分类与ci-status的 fail-closed 聚合共同守护并配有 src/verification/tests/ci-rust-gates.test.ts 中的契约测试锁定行为。如果你正在维护一个多语言、多 lane 的仓库并苦于 CI 时长与重复构建这套单产物复用 聚焦门禁 fail-closed 兜底的组合可以直接借鉴先列出每个信号的消费方与必需性再决定哪一层负责构建、哪一层负责验证最后用契约测试把精简后的拓扑固化下来。【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表