fix: parallelize v02 service builds

This commit is contained in:
Codex
2026-05-31 06:46:22 +08:00
parent 056ba60468
commit 6afbbca249
3 changed files with 20 additions and 4 deletions
+17
View File
@@ -103,6 +103,8 @@ CI/CD 内部由 UniDesk 手动触发入口、PipelineRun、component planner、B
3. CI/CD 校验只保留最小构建、语法、打包和冒烟检查;旧 DEV/D601/main gate、运行时内部证明型校验、健康诊断重断言和历史预检不进入 lane。
4. planner 根据 component input 判断 affected/reused services。
5. affected service 通过 BuildKit 发布到 G14 本地 registryreused service 复用 catalog digest。
所有 selected service 的 build TaskRun 都只依赖 `plan-artifacts`,不按 service 串行排队,也不设置 8 并发或其他 Pipeline 级限流。
实际并发由 Tekton controller、G14 节点资源、PVC I/O、BuildKit sidecar 和本地 registry 承载能力决定。
6. promotion 刷新 `deploy/artifact-catalog.v02.json`render `deploy/gitops/g14/runtime-v02/**`,只推送到 `devops-infra` mirror/relay 的 `v0.2-gitops`
7. `hwlab-g14-v02` 从本地 mirror/relay 的 `v0.2-gitops:deploy/gitops/g14/runtime-v02` 同步到 `hwlab-v02`
8. UniDesk CLI 或 mirror/relay flush 操作把本地 `v0.2-gitops` 推送到 GitHub canonical remoteflush 不在 CI runtime-ready 的关键路径内,但必须可查询 pending、lastFlushed 和 failure。
@@ -135,6 +137,13 @@ CI/CD 内部由 UniDesk 手动触发入口、PipelineRun、component planner、B
当前预算判定:source-only、所有 service 都复用 artifact、GitOps runtime 只发生 source identity 变化时,总耗时应接近 40s;超过 50s 需要先查是否误触发 `runtime-ready`、是否发生 GitHub 直连、是否恢复了 `npm ci` 或无效 preflight。真正需要 rollout 的 code-only 变更允许约 50s,因为 `runtime-ready` 必须等待 Argo 与 workload 收敛。涉及 BuildKit publish、env image rebuild、registry push 或真实 runtime 滚动时,不适用 40s 预算,应按 affected service 的 build 耗时单独测量。混合变更必须按 service 作用域裁剪:只改 `package.json``scripts`、旧门禁入口、短连接 CLI、CLI 测试、非 runtime 文档或 device-pod host asset 时,不得触发无关 runtime service 全量 build;若同一变更确实同时改了 `internal/cloud/**`、device-pod code 和 skill bundle,则只允许对应 service build/rollout,其他 service 必须复用 catalog digest。
真实 rebuild 场景必须按全并行 fan-out 判定性能。
`plan-artifacts` 之后所有 affected service build task 应同时进入 Tekton 调度队列,`collect-artifacts` 只做 fan-in 等待全部 build task 写入 service report。
不得为了稳定表面耗时在 Pipeline 拓扑上重新串行化,也不得引入固定 8 并发上限。
全量 rebuild 的关键路径应接近最慢 service build 耗时加上 source、planning、collect、promotion 和 runtime-ready 固定开销,而不是所有 service build 耗时求和。
若全并行导致节点 CPU、内存、PVC I/O、BuildKit sidecar 或 registry 竞争,先通过 TaskRun duration、Pod scheduling、node pressure、registry latency 和 BuildKit 日志定位容量瓶颈。
除非已经证明控制面无法承载,否则不要把容量问题回退成 service 串行依赖。
关键阶段预算如下:
| 阶段 | 正常预算 | 退化信号 |
@@ -155,6 +164,11 @@ Git 读写都走 `devops-infra` 本地 mirror/relay。读路径用 HTTP mirror c
env image 复用把系统依赖和业务代码身份分离。`environmentDigest` 表示可复用运行环境,`HWLAB_BOOT_REPO``HWLAB_BOOT_COMMIT``HWLAB_BOOT_SH` 表示本次代码启动身份。code-only 变更只更新 boot metadata 和 runtime identity,不发布新 env image;只有真实 env 输入变化或缺少可复用 env digest 时才进入 env rebuild。`package.json` 只按 dependency/runtime 字段参与 env/runtime hash`scripts` 只属于开发入口,不得因为清理旧门禁脚本而重建所有 service 或重建 env image。
BuildKit publish 采用 service 级全并行 fan-out。
每个 service build task 拥有独立 BuildKit sidecar、独立 service workdir 和独立 report 文件,均从同一 `plan-artifacts` 结果判断是否需要执行。
跳过的 task 由 Tekton `when` 表达式裁剪,执行的 task 并行写入 `/workspace/source/service-results/<serviceId>.json`
`collect-artifacts` 只从 report 目录收敛结果,不再通过 `tasks.build-*.results` 直接依赖某个前序 task 输出,因此全并行不会改变 artifact 身份语义。
planner 必须按 service component model 裁剪 build。`tools/` 下的短连接 CLI 源码不是 runtime service 输入;`skills/` 只有 agent runtime 或 skills bundle 真正消费的子目录才影响对应 runtimedevice-pod host CLI asset 属于 skills bundle 或 host 侧分发输入,不得让 cloud-api、agent-worker、gateway、edge-proxy 等服务重建。CI 读取 artifact catalog 时支持 repo 相对路径和绝对路径,便于用真实 catalog 做本地热探测;catalog 缺失才允许 fail closed 到 rebuild,不得把“诊断命令没读到 catalog”误判为生产路径必须全量构建。
P1 no-op runtime skip 只跳过无实际 runtime 变化的等待。planner 输出 `buildServices=[]``rolloutServices=[]` 后,`gitops-promote` 会在写入前对旧 `runtime-v02` 与新 render 结果做归一化比较:忽略 source commit、artifact source commit、boot commit 和等价 commit env/annotation 这类 identity-only 字段。如果归一化结果相同,promotion 输出 `skipped-runtime-unchanged`,把 Tekton result `runtime-ready-required=false` 写出,并跳过 GitOps commit、push、Argo hard refresh 和 `runtime-ready`。如果 workload spec、image digest、env image、SecretRef、Service、Ingress、FRP、ConfigMap 或 rollout service 有实际变化,必须保持 `runtime-ready-required=true` 并等待 runtime 收敛。
@@ -208,6 +222,8 @@ done
| `source-clone` 超过 5s | PipelineRun 参数 `git-read-url`、mirror service、PVC I/O、`git-mirror status` | 不要改回 GitHub 直连;先修 mirror/read service。 |
| catalog 缺失导致全量 build | `prepare-source` 是否从 `v0.2-gitops` 取到 `deploy/artifact-catalog.v02.json` | 先 `git-mirror sync --confirm`;必要时查 mirror refs/object closure。 |
| `buildSkippedCount` 偏低或突然变成 0 | `g14-ci-plan``affectedServices``buildServices``rolloutServices`、catalog 加载状态、`package.json` 字段 diff 和 service component path | 真实业务变更可以 build;脚本清理、CLI/测试/文档、host asset 或 code-only env-reuse 变更不应误触发全量 build。 |
| 多 service rebuild 仍串行执行 | `tekton-v02/pipeline.yaml` 中所有 `build-*` task 的 `runAfter`,以及 TaskRun startTime 是否都紧跟 `plan-artifacts` | build task 只能依赖 `plan-artifacts`;发现 `build-B` 依赖 `build-A` 时直接修 render 脚本和生成物,不保留串行兼容路径。 |
| 全并行 rebuild 变慢或不稳定 | TaskRun duration、Pod Pending/Unschedulable、node pressure、PVC I/O、BuildKit sidecar 日志、本地 registry push latency | 优先定位资源容量或 registry/BuildKit 瓶颈;不要先把 Pipeline 拓扑改回串行或固定 8 并发。 |
| no-op 仍执行 `runtime-ready` | `gitops-promote` 是否输出 `runtime-ready-required=false``skipped-runtime-unchanged` | 查 runtime 归一化比较;不要直接删除 `runtime-ready`,只修 no-op 判定。 |
| mirror `pendingFlush=true` 长期存在 | `bun scripts/cli.ts hwlab g14 git-mirror status` 和最近一次 flush 错误 | 手动 `git-mirror flush --confirm`flush 不影响已 rollout 本地 revision,但不能静默积压。 |
| Argo `Synced/Healthy` 但公网不通 | `hwlab-v02-frpc` 日志、master frps allowlist、`19666/19667` | 修 FRP allowlist 或 frpc;不要把 DEV/PROD 入口当作 v02 证据。 |
@@ -356,6 +372,7 @@ GitOps branch 已更新、source branch render 通过、PipelineRun 名称存在
| `devops-infra` git mirror/relay 加速 | 已实现/持续约束 | source/catalog/runtime checkout 读路径和 GitOps promotion 写路径均使用独立基础设施集群 mirror/relayArgo source 指向本地 mirrorGitHub flush 由 UniDesk CLI 手动触发,不设置 CronJob。runtime namespace 不持有 GitHub deploy keyregistry 保持 G14 `hwlab-ci/hwlab-registry`。 |
| `hwlab-cli` 不进 CI/CD service matrix | 已实现/持续约束 | CLI 是固定 repo 短连接 client,不发布镜像、不生成 artifact、不创建 `build-hwlab-cli` TaskRun;相关旧入口出现时直接删除。 |
| CI/CD fast lane 性能预算 | 已实现/持续约束 | env-reuse no-op 目标约 40s;真实 runtime rollout 目标约 50s;不得恢复 `prepare-source` 依赖安装、GitHub 关键路径写入或 no-op runtime 等待。 |
| Service build 全并行 fan-out | 已实现/持续约束 | selected services 的 build TaskRun 全部只依赖 `plan-artifacts`,不设置 8 并发或其他 Pipeline 级限流;`collect-artifacts` 通过 service report 目录 fan-in。 |
| 自动 registry GC | 未实现 | 初期不启用自动 GC,后续需 lane/profile 保护集。 |
## 平行 lane 运维边界