# G14 CI/CD 性能分析 本文是 HWLAB G14 CI/CD 性能优化的长期参考,覆盖 `G14` source branch、Tekton PipelineRun、per-service BuildKit 镜像发布、`G14-gitops` promotion、Argo CD sync 和 DEV runtime health。D601 legacy CI/CD、Code Queue runner 和 host 侧临时构建路径不属于本文范围。 ## 性能模型 G14 CI/CD 耗时必须按阶段测量,不能只看一个 PipelineRun 总时长: 1. Source trigger:`G14` source commit 被 `hwlab-g14-branch-poller` 发现。 2. Source preparation:`prepare-source` clone source、checkout 精确 revision、导入最新 GitOps artifact catalog,并安装必要 npm 依赖。 3. Primitive validation:`repo-reports-guard`、`g14-contract-check`、`codex-api-forwarder-check` 从准备好的 workspace 并行运行。 4. Artifact planning:`plan-artifacts` 根据 component input hash 和上一轮 catalog 判断 affected/reused services。 5. Per-service fan-out:affected services 通过 BuildKit 发布镜像;reused services 复用 catalog identity,不能改变 workload pod template。 6. Artifact collection:`collect-artifacts` 汇总 per-service results 并验证 publish report。 7. GitOps promotion:`gitops-promote` 刷新 catalog、render desired state、commit 并 push `G14-gitops`。 8. Argo rollout:Argo CD 消费 `G14-gitops`,同步 runtime namespace,并让公网 health 对新 desired state 生效。 每次性能报告必须标注运行类型: - `reuse-only`:没有服务镜像需要重建。 - `single-component-build`:一个服务镜像重建,其余服务复用。 - `multi-component-build`:多个但不是全部服务镜像重建。 - `full-rebuild`:共享输入或 build-system 输入变化导致全部服务镜像重建。 ## Timing 输出合同 G14 Tekton 日志中的分段耗时统一使用 JSON 行事件:`event="g14-cicd-timing"`、`schemaVersion="v1"`、`stage`、`status`、`durationMs`,并尽量携带 `pipelineRun`、`taskRun`、`task`、`revision` 和 `serviceId`。后续性能对比只消费这些稳定字段,不从自然语言日志里反推耗时。 当前稳定 stage 名称:`source-clone`、`catalog-fetch`、`npm-ci`、`buildkit-context-transfer`、`dependency-install`、`cache-import`、`cache-export`、`gitops-render`、`gitops-clone`、`gitops-commit`、`gitops-push`、`argo-refresh`、`workload-ready`。 `argo-refresh` 以 `hwlab-dev` workload 的 `hwlab.pikastech.local/source-commit` 元数据收敛作为观测点,不要求 Tekton 跨 namespace patch Argo Application。`workload-ready` 以 `hwlab-dev` 的 Deployment/StatefulSet observed generation、ready replicas 和 updated replicas 为准;权限不足或超时必须用 `status` 明确输出,不得静默吞掉。 ## 当前基线 当前 G14 pipeline 已具备关键架构优化:一分钟 source polling、组件级 lazy build、per-service fan-out、G14 本地 registry、本地 base image、BuildKit-only publish、GitOps/Argo 分离。剩余耗时主要集中在固定开销和镜像构建机制上。 当前滚动基线量级: | 阶段 | 典型范围 | 说明 | | --- | --- | --- | | Source trigger | 0-60s | poller 每分钟运行一次;平均等待应接近 30s。 | | `prepare-source` | 75-175s | 主要由 fresh clone、GitOps catalog fetch 和 `npm ci` 组成;这是很多单组件运行里的最大固定成本。 | | Primitive validation | 每项 5-10s | source 准备后并行运行,目前不是主要瓶颈。 | | `plan-artifacts` | 6-10s | 当前可接受,重点是保持只读和确定性。 | | Reused service TaskRun | 每项 8-12s | fan-out wall time 接近最慢复用 task,但 unchanged services 仍会启动 build-shaped pod。 | | Fast affected service build | 25-35s | 小型 Node 服务且 cache 命中时的常见范围。 | | Heavy affected service build | 120-220s | 依赖面宽或重建 Codex 相关层的服务可能达到该范围。 | | `collect-artifacts` | 8-10s | 当前可接受,主要是校验和 report assembly。 | | `gitops-promote` | 50-105s | 主要由 render/check、GitOps clone/checkout、tree copy、commit、push 构成。 | | Argo sync 到 DEV Healthy | 10-220s | 受 repository refresh timing 和 workload 是否真实滚动影响较大。 | 当前端到端预期范围: | 运行类型 | PipelineRun | source commit 后到 DEV Healthy | | --- | --- | --- | | `reuse-only` | 3-4.5m | 3.5-6m | | `single-component-build` | 3.2-5.5m | 4-7.5m | | `full-rebuild` | 6-7m | 6.5-9m | 这些值是性能基线,不是发布 SLO。任何 CI/CD 优化变更都应按同一种运行类型做 before/after 对比。 ## 根本原因 ### Source Preparation 冷启动 `prepare-source` 每次 PipelineRun 都执行 fresh source clone、精确 checkout、GitOps catalog lookup 和 `npm ci`。当前 tools image 已避免运行时安装系统包,但没有消除每轮 npm install 成本。npm 或 GitHub 延迟上升时,后续 validation 和 build task 都会被这个共享 workspace 阻塞。 根因:source preparation 被当成无状态冷启动处理,但实际工作负载反复使用同一个小型依赖图和同一个私有仓库。 ### Build Context 过宽且重复处理 Runtime 依赖 服务镜像由 `scripts/artifact-publish.mjs` 生成 Dockerfile。该 Dockerfile 安装 production npm dependencies,然后复制 `internal`、`cmd`、`scripts`、`web`、`tools`、`skills`、`deploy` 等大范围目录。per-service Tekton task 还会先把 prepared source repo 复制到 service work directory,再调用 BuildKit。 根因:BuildKit 接收到 monorepo-shaped context,并重复执行本应预烘或按服务裁剪的 dependency-layer 工作。 ### Reuse 路径仍启动 Build-Shaped Pod 组件级 lazy build 已能正确把 unchanged services 标成 reused,但每个服务仍有一个带 BuildKit sidecar wiring 的 `build-*` TaskRun。reused services 会很快写出 Tekton results 并退出,但 Kubernetes 仍要承担 pod scheduling、sidecar setup、entrypoint setup 和 result collection 开销。 根因:Tekton result wiring 绑定在 service task 上,reuse 被实现为 build-shaped task 内部的快速分支,而不是更轻量的 catalog-result 路径。 ### GitOps Promotion 做了完整 Workspace 工作 `gitops-promote` 做 source freshness check、artifact catalog refresh、desired state render、render check、GitOps branch clone、generated state copy、commit 和 push。这保证了 release truth 清晰,但当前 repository 和文件树操作比必要量更重。 根因:GitOps promotion 语义正确,但没有针对 shallow/sparse branch operation 或 incremental generated-state update 做优化。 ### Argo Repository Discovery 带来变量延迟 `gitops-promote` push `G14-gitops` 后,Argo CD 不一定立刻发现新 revision。对于 reused-image 或小镜像变更,workload rollout 本身可能很快,repository discovery 反而变成端到端耗时里的显著部分。 根因:CI push 和 Argo refresh 是松耦合的;GitOps 仍是真相,但运行态观察会滞后于 push。 ### Retention Cleanup 对排障噪声覆盖不足 retention cleaner 会删除超过保留窗口的 completed PipelineRuns,但近期 failed PipelineRuns、failed TaskRuns 和 orphan Error pods 仍可能堆在 `hwlab-ci`。这通常不会给 pipeline 增加分钟级耗时,但会拖慢诊断并制造 API/list 噪声。 根因:retention policy 更偏向长期清理,不是针对已知 bad-run burst 后的近期失败对象治理。 ## 改进建议 | 优先级 | 建议 | 预期效果 | | --- | --- | --- | | P0 | 增加稳定的分段 timing 输出,覆盖 source clone、catalog fetch、`npm ci`、BuildKit context transfer、dependency install、cache import/export、GitOps clone、render、commit、push、Argo refresh、workload ready。 | 直接加速很小,但能让后续优化具备可比数据,避免把网络、npm、BuildKit、Argo 延迟混为一谈。 | | P0 | 给 `prepare-source` 使用 npm dependency cache,或在 CI tools image 里预装 repo dependencies,同时保留对 `package-lock.json` 精确性的校验。 | 将 `prepare-source` 从 75-175s 降到约 35-70s。单轮 PipelineRun 预计节省 40-100s。 | | P0 | 构建并使用包含 production `node_modules`、Codex package 和平台专用 Codex binary 的 runtime base image。 | 减少服务镜像重复依赖工作。fast build 维持约 20-35s;heavy build 从 120-220s 降到约 45-90s;full rebuild 预计节省 1-3m。 | | P0 | 为服务镜像增加生成式 `.dockerignore` 或 pruned BuildKit context,排除 `.git`、prepared `node_modules`、无关 generated files 和可排除的无关 service directories。 | 降低 context transfer 和 cache invalidation。小型 build 预计节省 10-40s,heavy build 预计节省 30-90s,同时降低磁盘压力。 | | P1 | 将 unchanged services 从 BuildKit-shaped tasks 拆出。可让 `plan-artifacts` 直接输出 catalog-backed service results,或给 reused service 使用无 sidecar 的轻量 task,changed services 保持 BuildKit。 | reuse-only 和 single-component fan-out 预计节省 10-30s,并显著减少 sidecar/pod 噪声;主要收益是稳定性和可观测性。 | | P1 | 优化 `gitops-promote`:对 `G14-gitops` 使用 shallow/sparse checkout,复用已 render 的输出做 check,避免复制或提交未变化的 generated paths。 | 将 `gitops-promote` 从 50-105s 降到约 20-45s。每轮 promotion 预计节省 30-60s。 | | P1 | GitOps push 成功后触发 Argo hard refresh,再用短轮询观察 sync。 | 当 workload 本身健康时,CI succeeded 到 DEV Healthy 从 10-220s 降到约 10-60s。 | | P1 | 扩展 failed-run retention:给 failed PipelineRuns 和 orphan Error pods 设置明确的短保留窗口,同时禁止删除 active PipelineRuns 和 runtime namespaces。 | 对 pipeline 直接加速有限,但能显著降低 bad-run burst 后的诊断噪声和 API/list 噪声。 | | P2 | 保持一分钟 polling,除非 source-trigger wait 成为主瓶颈;在固定开销降低前不要优先引入 GitHub webhook 复杂度。 | 理论平均最多节省约 30s;当前收益低于 `prepare-source`、BuildKit 和 GitOps promotion。 | | P2 | 在 context 和 base image 优化落地后,再调 BuildKit CPU/memory requests 与 cache export mode。 | 可能额外提升 build 10-20%,但在 build context 和 dependency layer 仍过宽时过早调资源不可靠。 | ## 高优先级改进后的预期效果 高优先级改进指 P0 项,加上 P1 的 GitOps promotion 优化和 Argo refresh coupling。它不要求改变当前 Tekton/GitOps/Argo truth model,也不需要回退到 shell runner。 预期高优先级优化后范围: | 运行类型 | PipelineRun | source commit 后到 DEV Healthy | | --- | --- | --- | | `reuse-only` | 1.8-2.6m | 2.2-3.5m | | `single-component-build` | 2.0-3.2m | 2.5-4m | | `full-rebuild` | 3.8-5.2m | 4.3-6m | 这是第一阶段务实目标:保持当前发布真相模型,优先消除普通 PR rollout 中占比最高的固定成本。 ## 全部建议落地后的预期效果 全部建议包括高优先级项、reuse task 拆分、failed-run retention 改进,以及后续 BuildKit resource tuning。 预期全部优化后范围: | 运行类型 | PipelineRun | source commit 后到 DEV Healthy | | --- | --- | --- | | `reuse-only` | 1.2-1.8m | 1.5-2.5m | | `single-component-build` | 1.6-2.6m | 2-3.2m | | `full-rebuild` | 3-4.5m | 3.5-5m | 剩余下限是真实工作:私有 source 访问、validation、immutable image publication、GitOps truth update、Argo sync 和 live runtime health。不要为了追求亚分钟 full CI/CD 而折叠这些边界。 ## 实施顺序 1. 增加低噪声 timing instrumentation。 2. 为 `prepare-source` 增加 npm/prepared-dependency cache。 3. 构建包含依赖和 Codex binary 的 production runtime base。 4. 裁剪 BuildKit context,并增加生成式 `.dockerignore` 保护。 5. 优化 `gitops-promote` clone/render/copy/push 机制。 6. GitOps push 后触发 Argo refresh,并测量 CI-success 到 DEV-health 耗时。 7. 将 reuse path 从 BuildKit-shaped service tasks 中拆出。 8. 扩展 failed-run retention cleanup。 9. 在 build graph 变小后再调 BuildKit resources。 ## 验收标准 任何优化变更只有在给出同运行类型 before/after 数据,并保持以下不变量时,才算可交付: - Source commit 仍是唯一 artifact identity。 - 镜像仍使用 commit tag 和 digest 作为发布身份。 - `G14-gitops` 仍是 Argo CD 消费的 desired-state truth。 - Unchanged services 不会因为全局 source commit 变化而滚动。 - Failed/stale PipelineRun cleanup 不触碰 `hwlab-dev`、`hwlab-prod`、Argo runtime state、registry storage 或 active PipelineRuns。 - Runtime success 仍由 Argo Application revision、workload readiness 和必要公网 health 证明。