CI 测试与反馈性能

August 23, 2026 · View on GitHub

当前 PR workflow 是 .github/workflows/ci.ymlScope Detector 使用统一 NX_BASE / NX_HEAD 生成 versioned delivery-manifest-v1.json artifact;后续 child 只消费并校验同一份 manifest,不重新解释 affected 范围。 job 的执行条件也只消费 manifest 的 lane policy:docs-only PR 只保留 governance,ro../release-tools/full policy 则显式开启对应的完整 lane,避免 scope 输出与实际门禁分叉。

稳定 required Oracle 始终出现:Governance OracleValidate OracleBoundary OracleIntegration OracleWeb Flow OracleCoverage OraclePerformance Oracle。 最终的 Delivery Observation 也属于 required context;它校验 manifest、lane evidence 和 run summary 完整存在,避免所有 child 通过但观测证据缺失时仍然 false-green。

Oracle 使用 tools/test-system-v2/lib/oracle.mjs 的同一状态机:未受影响且 child skipped 是成功, 应执行但 skipped/cancelled/failed 是失败,detector failure 会 fail closed。GitHub ruleset 的 active required contexts 由 .github/rulesets/main.json 声明,并由 ruleset-check 校验名称一致性。

Validate children(static analysis、unit、typecheck、build)并行执行。Desktop IPC 和 main 在一个 prepared Boundary runner 内分别执行;integration、smoke 和每个 Web shard 使用独立数据库环境。 真实数据库、浏览器和性能 target 均关闭 Nx cache。

Web Flow 的 21 个核心 spec 由 apps/web/web-flow-specs.mjs 唯一列出。 tools/test-system-v2/web-spec-durations.json 保存最近一次完整 V2 run 的逐 spec 测量基线, generate-web-shards.mjs 据此生成 web-shards.jsonweb-shards.test.mjs 校验合集无遗漏、无重复。

tools/test-system-v2/run-command.mjs 输出结构化 timing/report,并使用 failure-classification.mjs 区分 assertion、infrastructure、process-crash、timeout 和 flaky;只有 明确 infrastructure 或 process crash 才自动重试一次。成功 run 不上传大体积浏览器证据,失败时保留 trace、video、screenshot 和 JSON report。

CI/CD Platform V2 现在把平台事实收敛到 tools/ci-cd-platform/lane-registry 声明每个 lane 的 capability、输入输出、隔离、cache、owner 和失败策略;create-lane-input.mjs 把同一份 delivery manifest 转换为可验证的 lane-input-v1。workspace action 先消费 manifest,再严格按 lane capability 决定是否安装可选工具链,并生成带 digest 和 setup timing 的 workspace-receipt-v1。Web lane 在 Mastra-native cutover 后只需要 Node/pnpm/Playwright/Postgres,不再为已退役的 Python runtime 安装 Python/uv。

每条命令输出唯一的 lane-result-v1publish-lane-evidence 生成 lane-summary-v1;CI 末尾的 Delivery Observation 递归聚合各 job 的证据为 run-summary-v1。这些对象都绑定 commit、manifest digest 和上游对象 digest,来源不一致或证据缺失时 fail closed;Observation 不再通过跳过聚合产生 false-green。API、API runtime dependency closure、Web、 Migrator、Database、Database Runtime 属于同一 production artifact closure;closure 由 API workspace dependencies 递归计算。Web shard 和 publish-images.yml 都会在使用前验证每个内容 digest、source manifest digest 以及 closure 目录集合。

PR coverage 由 Coverage Oracle 门禁;.github/workflows/coverage.yml 的 schedule/manual 车道继续 执行完整 configured project lists,作为 affected 图漏检的 nightly 兜底。PR test:perf 只执行固定 seed 的排序/service budget;真实 GC、memory 和长采样在 performance-experiment.yml nightly 车道, 并明确要求 --expose-gc

本地对应入口:

node tools/test-system-v2/inventory.mjs --check
node tools/test-system-v2/ruleset-check.mjs
node --test tools/test-system-v2/__tests__/*.test.mjs
node tools/ci-cd-platform/schema-check.mjs
node tools/ci-cd-platform/registry-check.mjs
node --test tools/ci-cd-platform/__tests__/*.test.mjs
node tools/ci-cd-platform/run-fault-injection.mjs
node --test tools/ci-cd-platform/__tests__/timing.test.mjs
pnpm nx run desktop:test:boundary

仓库只有一名维护者时,.github/rulesets/main.json 保留 active Oracle、Delivery Observation 和 required thread resolution, 但 required_approving_review_count、code-owner review 和 last-push approval 均为 0/false;门禁是 自动化 Oracle,不是给自己制造一个无法产生第二人的 review 阻塞。

2026-08-05 V2 验收测量

本节同时记录历史容量数据和当前 PR fresh-run;历史数据仅用于成本对照,当前分支证据见下方 PR #209 段落。

当前 PR #209 的最终 Actions run 31002955215 绑定 30bf0da88b6541c9e5fe0c08410c5fd51ff1275d,七个稳定 Oracle、四个 Web shard 和 Delivery Observation 全部通过。run-summary-v1 的 setup 为 368,804 ms,lane execution 为 1,965,337 ms,最长 lane 为 284,813 msmissingLanes: [];四个 Web shard 为约 5:56、5:42、5:51、5:46,证据 artifact 使用唯一 shard-0..3 suffix。该 run 是当前分支 fresh-run 证据,但仍不足以替代至少五次 comparable timing 的 P50/P95 与 runner-minute 统计。

Actions run 30968872885 的七个 required Oracle 全部通过。workflow 从 02:16:23Z02:24:46Z,墙钟约 8:23;所有 job 的 实际执行时间合计 2,981 秒,即 49.68 runner-minutes。该执行成本高于 42.3 分钟基线,因此不能视为 runner-minutes 目标已达成;公开仓库 billing API 返回的 0 billable milliseconds 是不同指标。

此前 run 的 Web shard 实际 job 时长为 6:48、7:29、5:53、7:11。由 JSON report 聚合的逐 spec baseline 重新分配后,四个 shard 估算测试时长为 253,478、254,607、257,794、254,664 毫秒,估算极差 4.32 秒,明显低于此前约 1:42 的观测极差。最终 run 的四个 shard 实际 job 时长为 6:44、7:03、 6:55、7:09,实际极差 25 秒。后续 run 应继续从 Actions artifact 记录墙钟、执行 runner-minutes、cache 命中和实际 shard 平衡,不把单次测量写成永久保证。

手动触发的完整 Coverage workflow run 30970172037 已验证 full configured project selection 不再 false-green;它实际执行 governed domain、store 和 use-case coverage,并在 schedule:test:coverage:use-cases 的 branch coverage 56.33% < 60% 时失败。该回归保持 原 threshold,证明 nightly audit 和 coverage regression gate 都会 fail closed。

覆盖 nightly-audit 修复后的最终 PR head c85759766Actions run 30971373609 验证,七个 Oracle 全部通过;该 run 的墙钟约 8:43,job execution 合计 3,045 秒(50.75 runner-minutes)。

随后移除 Web shard 的重复 API build,并缓存 Playwright 浏览器;run 30972424422 仍七个 Oracle 全部通过,但 execution 为 49.32 runner-minutes,未达到 42.3 基线。该实验保留在实现 中,因为它删除了真实重复工作,即使共享 runner 噪声使单次测量没有显著下降。

前一轮 main-based 重构 PR head c17b9c2d2run 30998745996 七个稳定 Oracle、四个 Web shard 和 Delivery Observation 全部通过。run-summary-v1 的 manifest digest 为 6765b888d8eaed32786f8584056c1efcc632581fcce79266cc5c762a0e953e16,summary digest 为 69f7af0590a5c6e99569cb46c336a34ae9b6470ac25bb52ebabff87b7af92484;setup 270,994 ms,lane execution 1,079,501 ms,最长 lane 283,413 msmissingLanes: []。四个 Web shard job 为 5:41、5:43、5:44、 6:02。该 run 是 fresh-run 验证,不替代至少五次 comparable run 的 P50/P95 统计;runner-minutes 仍需从 同范围 Actions run 的 job receipts 计算,不能用 billing API 的 0 值替代。

前一轮 CI/CD Platform V2 head 49775316frun 30995540184 再次通过全部稳定 Oracle、四个 Web shard 和 Delivery Observation。run summary 记录 setup 279,052 ms、 lane execution 1,116,601 ms、最长 lane 284,047 ms,manifest digest 615b3976e39aefb891d5f0f95083afd18497c91fa6d2b7cc1d64b83e1adce80c,无 failures、无 missing lanes。 四个 Web shard 的实际 job 时长为 5:52、5:58、6:08、6:16,极差 24 秒;这证明 shard 平衡和登录 helper 修复在该 head 上有效,但仍不足以替代至少五次 comparable timing 的 P50/P95 验收。