refactor: make v0.3 runtime node-scoped

This commit is contained in:
Codex Agent
2026-06-08 22:19:30 +08:00
parent e8ab452b10
commit 187fb80a5d
38 changed files with 549 additions and 450 deletions
+1 -1
View File
@@ -291,5 +291,5 @@ blockers/failures`viewport`、`selector`、`failureType`、summary 和 artifa
chat 同源 readiness 和 provider credential blocker 边界。
- [spec-v02-services.md](spec-v02-services.md): Cloud Web runtime wrapper and browser-side TypeScript migration boundary.
- [pikasTech/HWLAB#532](https://github.com/pikasTech/HWLAB/issues/532): archived historical `docs/cloud-web-workbench.md` content.
- [g14-gitops-cicd.md](g14-gitops-cicd.md): Cloud Web rollout through G14 Tekton, GitOps and Argo CD
- [node-gitops-cicd.md](node-gitops-cicd.md): Cloud Web rollout through node-scoped Tekton, GitOps and Argo CD
path.
+4 -4
View File
@@ -19,12 +19,12 @@ The current G14 DEV route is:
```text
master hwlab-frps-dev :17666/:17667
-> G14 hwlab-g14-frpc in namespace hwlab-dev
-> G14 hwlab-node-frpc in namespace hwlab-dev
-> hwlab-cloud-web on internal :8080 for browser traffic
-> hwlab-edge-proxy / hwlab-cloud-api on internal :6667 for API and health
master hwlab-frps-dev :18666/:18667
-> G14 hwlab-g14-prod-frpc in namespace hwlab-prod
-> G14 hwlab-node-prod-frpc in namespace hwlab-prod
-> hwlab-cloud-web on internal :8080 for browser traffic
-> hwlab-edge-proxy / hwlab-cloud-api on internal :6667 for API and health
@@ -34,7 +34,7 @@ master hwlab-frps-dev :19666/:19667
-> hwlab-edge-proxy / hwlab-cloud-api on internal :6667 for API and health
```
G14 PROD is rendered by GitOps as namespace `hwlab-prod` and Argo CD application `hwlab-g14-prod`; it uses the `:18666/:18667` public endpoints when enabled. G14 desired state is generated into `deploy/gitops/g14/runtime-dev` and `deploy/gitops/g14/runtime-prod` and promoted through the `G14-gitops` branch.
G14 PROD is rendered by GitOps as namespace `hwlab-prod` and Argo CD application `hwlab-node-prod`; it uses the `:18666/:18667` public endpoints when enabled. G14 desired state is generated into `deploy/gitops/node/runtime-dev` and `deploy/gitops/node/runtime-prod` and promoted through the `G14-gitops` branch.
G14 `v0.2` is an additive lane, not a replacement for DEV or PROD. It uses source branch `v0.2`, fixed development workspace `G14:/root/hwlab-v02`, dedicated CI/CD source repo `G14:/root/hwlab-v02-cicd.git`, namespace `hwlab-v02`, and public ports `19666/19667`. The `v0.2` GitOps branch, runtime path and Argo Application must be distinct from DEV/PROD before any automated rollout is enabled.
@@ -44,7 +44,7 @@ G14 native k3s is the HWLAB DEV/PROD runtime source of truth. Commands that obse
```sh
tran G14:k3s kubectl -n hwlab-dev get deploy,svc,pod -o wide
tran G14:k3s kubectl -n argocd get application hwlab-g14-dev hwlab-g14-prod
tran G14:k3s kubectl -n argocd get application hwlab-node-dev hwlab-node-prod
tran G14:k3s kubectl -n hwlab-v02 get deploy,svc,pod -o wide
```
+1 -1
View File
@@ -22,7 +22,7 @@ tran G14:k3s kubectl get nodes -o wide
tran G14:k3s kubectl get ns hwlab-dev hwlab-prod
```
结果必须显示 G14 原生 k3s 中存在 `hwlab-dev`;需要验证 PROD 发布面时也必须显示 `hwlab-prod`。出现 D601 kubeconfig、Docker Desktop Kubernetes、`desktop-control-plane``127.0.0.1:11700` 或第二套 `hwlab-dev` 控制面时,停止 hotfix、回滚和验收判断。此边界与 [dev-runtime-boundary.md](dev-runtime-boundary.md) 和 [g14-gitops-cicd.md](g14-gitops-cicd.md) 保持一致。
结果必须显示 G14 原生 k3s 中存在 `hwlab-dev`;需要验证 PROD 发布面时也必须显示 `hwlab-prod`。出现 D601 kubeconfig、Docker Desktop Kubernetes、`desktop-control-plane``127.0.0.1:11700` 或第二套 `hwlab-dev` 控制面时,停止 hotfix、回滚和验收判断。此边界与 [dev-runtime-boundary.md](dev-runtime-boundary.md) 和 [node-gitops-cicd.md](node-gitops-cicd.md) 保持一致。
## kubectl 热修命令形状
@@ -6,9 +6,9 @@
G14 CI/CD 耗时必须按阶段测量,不能只看一个 PipelineRun 总时长:
1. Source trigger`G14` source commit 被 `hwlab-g14-branch-poller` 发现。
1. Source trigger`G14` source commit 被 `hwlab-node-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 并行运行。
3. Primitive validation`repo-reports-guard``node-contract-check``codex-api-forwarder-check` 从准备好的 workspace 并行运行。
4. Artifact planning`plan-artifacts` 根据 component input hash 和上一轮 catalog 判断 affected/reused services。
5. Per-service fan-outaffected services 通过 BuildKit 发布镜像;reused services 复用 catalog identity,不能改变 workload pod template。
6. Artifact collection`collect-artifacts` 汇总 per-service results 并验证 publish report。
@@ -24,7 +24,7 @@ G14 CI/CD 耗时必须按阶段测量,不能只看一个 PipelineRun 总时长
## Timing 输出合同
G14 Tekton 日志中的分段耗时统一使用 JSON 行事件:`event="g14-cicd-timing"``schemaVersion="v1"``stage``status``durationMs`,并尽量携带 `pipelineRun``taskRun``task``revision``serviceId`。后续性能对比只消费这些稳定字段,不从自然语言日志里反推耗时。
G14 Tekton 日志中的分段耗时统一使用 JSON 行事件:`event="node-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`
@@ -5,12 +5,12 @@ G14 是 HWLAB 当前 DEV/PROD 原生 k8s 与 GitOps 运行面目标。G14 CI/CD
## 目标模型
- Source of truth:业务版本以 Git source commit 为唯一身份;镜像 tag、OCI labels、runtime annotation 和 Argo CD desired state 都必须记录同一个 source commit。
- CITekton 在 G14 k3s 内运行 `hwlab-g14-ci-image-publish` Pipeline,由 `scripts/g14-gitops-render.mjs` 直接生成原生 task;最小校验固定为 `repo-reports-guard``g14-contract-check``codex-api-forwarder-check`,随后按 component plan 做 per-service BuildKit publish 与 GitOps promote;没有 `CI.json` runner、DIND 单任务发布或 Docker fallback。
- CITekton 在 G14 k3s 内运行 `hwlab-node-ci-image-publish` Pipeline,由 `scripts/gitops-render.mjs` 直接生成原生 task;最小校验固定为 `repo-reports-guard``node-contract-check``codex-api-forwarder-check`,随后按 component plan 做 per-service BuildKit publish 与 GitOps promote;没有 `CI.json` runner、DIND 单任务发布或 Docker fallback。
- Artifact:镜像使用 commit tag,例如 `127.0.0.1:5000/hwlab/hwlab-cloud-api:<shortCommit>`digest 由 registry 返回,CI report 只作为审计证据,不作为 CD 真相。发布态 artifact catalog 由 Tekton 写入 `G14-gitops:deploy/artifact-catalog.dev.json`
- Branch split`G14` 是源码监控分支,只保存人写源码、声明和 seed contract`G14-gitops` 是 Tekton promotion 写入的生成分支,保存 `deploy/artifact-catalog.dev.json``deploy/gitops/g14/**` desired state。CI/CD 不再把 catalog promotion commit 写回 `G14`
- Branch split`G14` 是源码监控分支,只保存人写源码、声明和 seed contract`G14-gitops` 是 Tekton promotion 写入的生成分支,保存 `deploy/artifact-catalog.dev.json``deploy/gitops/node/**` desired state。CI/CD 不再把 catalog promotion commit 写回 `G14`
- v0.2 扩容线:`v0.2` 必须从当前 `G14` fork 出来,并以 `G14:/root/hwlab-v02` 作为固定开发 workspace、`G14:/root/hwlab-v02-cicd.git` 作为固定 CI/CD source repo、`hwlab-v02` 作为固定 runtime namespace。`v0.2` CI/CD 只能作为新增 lane 接入现有 G14 Tekton/Argo 体系,不得改写、删除、暂停或重定向现有 `G14` poller、`G14-gitops` DEV/PROD desired state、`hwlab-dev``hwlab-prod`;详细规格见 [spec-v02-cicd.md](spec-v02-cicd.md)。
- CDArgo CD 只消费 `G14-gitops:deploy/gitops/g14/runtime-dev``deploy/gitops/g14/runtime-prod` 的 Git desired state,不重新构建镜像,不读取 D601 状态,不获取 legacy DEV CD Lease。
- FRPG14 DEV 通过 `hwlab-dev/hwlab-g14-frpc` 暴露 `17666/17667`G14 PROD 通过 `hwlab-prod/hwlab-g14-prod-frpc` 暴露 `18666/18667``v0.2` 规划通过 `hwlab-v02` 内独立 frpc 暴露 `19666/19667`。master frps 的 `deploy/frp/frps.dev.toml` 与实际 `/etc/frp/frps.toml` 必须放行对应端口,但 `v0.2` 放行只能新增 19xxx 入口,不能复用或覆盖 DEV/PROD 入口。
- CDArgo CD 只消费 `G14-gitops:deploy/gitops/node/runtime-dev``deploy/gitops/node/runtime-prod` 的 Git desired state,不重新构建镜像,不读取 D601 状态,不获取 legacy DEV CD Lease。
- FRPG14 DEV 通过 `hwlab-dev/hwlab-node-frpc` 暴露 `17666/17667`G14 PROD 通过 `hwlab-prod/hwlab-node-prod-frpc` 暴露 `18666/18667``v0.2` 规划通过 `hwlab-v02` 内独立 frpc 暴露 `19666/19667`。master frps 的 `deploy/frp/frps.dev.toml` 与实际 `/etc/frp/frps.toml` 必须放行对应端口,但 `v0.2` 放行只能新增 19xxx 入口,不能复用或覆盖 DEV/PROD 入口。
- 并行性:不同 source commit 的 CI build 不共享发布锁;并行安全由 immutable commit tag/digest 和 Git desired state 保证。最终运行版本由 Argo CD 当前同步的 Git revision 决定。
## 门禁最小化与扩容治理
@@ -19,38 +19,38 @@ G14 是 HWLAB 当前 DEV/PROD 原生 k8s 与 GitOps 运行面目标。G14 CI/CD
旧 DEV/D601/main 门禁如果阻碍当前 G14 或 `v0.2` 路径,默认处理是从当前调用链删除,而不是做兼容性迁移、fallback、legacy mode、双路径绕行或在旧门禁上叠加例外。新增门禁只能覆盖明确高价值风险,且必须最小、低噪声、容易删除;资源配额、RBAC 命名、清理策略、回滚顺序、人工同步策略等默认是设计约定或 runbook,不是 CI/CD 通过条件。
`v0.2` 的硬边界只包括:source branch 必须是 `v0.2`CI/CD source repo 必须是 `/root/hwlab-v02-cicd.git`GitOps branch 必须是 `v0.2-gitops`Git mirror/relay 必须来自 `devops-infra`runtime namespace 必须是 `hwlab-v02`runtime path 必须是 `deploy/gitops/g14/runtime-v02`Argo Application 必须指向 `v0.2` GitOps lane,公网入口只能是 `19666/19667``v0.2` source branch 不跟踪生成物,旧 DEV/D601/main 门禁不进入 `v0.2` 调用链。其他事项先写成决策表或 runbook;只有被证明无法靠上述边界和标准入口自然收敛时,才允许新增最小检查。
`v0.2` 的硬边界只包括:source branch 必须是 `v0.2`CI/CD source repo 必须是 `/root/hwlab-v02-cicd.git`GitOps branch 必须是 `v0.2-gitops`Git mirror/relay 必须来自 `devops-infra`runtime namespace 必须是 `hwlab-v02`runtime path 必须是 `deploy/gitops/node/runtime-v02`Argo Application 必须指向 `v0.2` GitOps lane,公网入口只能是 `19666/19667``v0.2` source branch 不跟踪生成物,旧 DEV/D601/main 门禁不进入 `v0.2` 调用链。其他事项先写成决策表或 runbook;只有被证明无法靠上述边界和标准入口自然收敛时,才允许新增最小检查。
## 生成入口
`scripts/g14-gitops-render.mjs` 是 G14 专用转换器:
`scripts/gitops-render.mjs` 是 G14 专用转换器:
- 架构迁移时,过时的自检、预检、guard、gate 优先删除,不在旧门禁上叠加例外或复杂度;新门禁只允许覆盖明确高价值风险,必须保持最小、低噪声、易迁移。
- 直接声明 Tekton Pipeline、最小原语校验 task 和 PipelineRun 样板;不再读取 `CI.json` 或生成 `ci-json` step。
- 读取 `deploy/deploy.yaml``deploy/k8s/*`,生成 Argo CD 可消费的 G14 runtime Kustomize path。
- G14 Tekton 的镜像构建发布入口必须是 `scripts/g14-artifact-publish.mjs`;它只是集群内 Task 的 build/push helper,不做 rollout、不写 D601、不获取 legacy DEV CD Lease。旧 `scripts/dev-artifact-publish.mjs` 入口已删除;`dev-cd-apply``ci-publish` 和旧 `main` JS CD 入口禁止出现在 G14 Pipeline 生成脚本和 G14 验收证据中。
- `g14-contract-check` 在 fresh source clone 内取当前 `HEAD`,把 GitOps 产物渲染到 `mktemp -d` 临时目录,并立刻用同一个 `--source-revision` 执行 `--check`;它校验 render 代码、原生 Tekton 产物生成合同和 forbidden-fragment 护栏,不依赖 source branch 预先存在 `deploy/gitops/g14/source.json`。面向已发布 runtime 的 `source.json` 只存在于 `G14-gitops` 生成分支,作为 promotion evidence。
- 生成 `hwlab-g14-branch-poller` CronJob:它使用 G14 集群内的 Git SSH Secret 轮询 `G14` 分支,按 source commit 创建确定命名的 Tekton PipelineRun。
- 生成 `hwlab-g14-control-plane-reconciler` CronJob:它使用同一个 Git SSH Secret 轮询 `G14`,运行 repo 内 `scripts/g14-gitops-render.mjs`,并 server-side apply 生成的 Tekton RBAC、Pipeline、Poller 和 Reconciler manifests;因此 CI 控制面变化应自动进入 G14 k3s,不需要人工长期执行 render/apply。
- 默认输出到 `deploy/gitops/g14/`
- 默认 GitOps 生成分支是 `G14-gitops`Pipeline 成功后把本次 source commit 对应的 `deploy/artifact-catalog.dev.json``deploy/gitops/g14/**` 推送到该分支,避免把生成提交继续写回 `G14`
- `v0.2` GitOps lane 必须使用独立生成身份,例如 `v0.2-gitops``deploy/artifact-catalog.v02.json``deploy/gitops/g14/runtime-v02`,并由独立 Argo CD Application 指向 `hwlab-v02`。若后续实现选择复用某个脚本入口,也必须通过显式参数区分 source branch、catalog、runtime path、Application 和 namespace,不能靠修改默认值让 `G14` DEV/PROD 行为漂移。
- G14 Tekton 的镜像构建发布入口必须是 `scripts/artifact-publish.mjs`;它只是集群内 Task 的 build/push helper,不做 rollout、不写 D601、不获取 legacy DEV CD Lease。旧 `scripts/dev-artifact-publish.mjs` 入口已删除;`dev-cd-apply``ci-publish` 和旧 `main` JS CD 入口禁止出现在 G14 Pipeline 生成脚本和 G14 验收证据中。
- `node-contract-check` 在 fresh source clone 内取当前 `HEAD`,把 GitOps 产物渲染到 `mktemp -d` 临时目录,并立刻用同一个 `--source-revision` 执行 `--check`;它校验 render 代码、原生 Tekton 产物生成合同和 forbidden-fragment 护栏,不依赖 source branch 预先存在 `deploy/gitops/node/source.json`。面向已发布 runtime 的 `source.json` 只存在于 `G14-gitops` 生成分支,作为 promotion evidence。
- 生成 `hwlab-node-branch-poller` CronJob:它使用 G14 集群内的 Git SSH Secret 轮询 `G14` 分支,按 source commit 创建确定命名的 Tekton PipelineRun。
- 生成 `hwlab-node-control-plane-reconciler` CronJob:它使用同一个 Git SSH Secret 轮询 `G14`,运行 repo 内 `scripts/gitops-render.mjs`,并 server-side apply 生成的 Tekton RBAC、Pipeline、Poller 和 Reconciler manifests;因此 CI 控制面变化应自动进入 G14 k3s,不需要人工长期执行 render/apply。
- 默认输出到 `deploy/gitops/node/`
- 默认 GitOps 生成分支是 `G14-gitops`Pipeline 成功后把本次 source commit 对应的 `deploy/artifact-catalog.dev.json``deploy/gitops/node/**` 推送到该分支,避免把生成提交继续写回 `G14`
- `v0.2` GitOps lane 必须使用独立生成身份,例如 `v0.2-gitops``deploy/artifact-catalog.v02.json``deploy/gitops/node/runtime-v02`,并由独立 Argo CD Application 指向 `hwlab-v02`。若后续实现选择复用某个脚本入口,也必须通过显式参数区分 source branch、catalog、runtime path、Application 和 namespace,不能靠修改默认值让 `G14` DEV/PROD 行为漂移。
- 默认 registry prefix 是 `127.0.0.1:5000/hwlab`,用于 G14 单节点 k3s 的 node-local registry。
- 默认 CI/CD proxy 是 G14 本机 `http://127.0.0.1:10808` / `socks5h://127.0.0.1:10808`。Tekton CI step、BuildKit sidecar 和 publish step 都注入 proxy/no_proxy;服务镜像构建只允许通过 Pod 内 BuildKit Unix socket 直接 push 到 G14 本地 registry,不能回退到 Docker daemon、DIND 或 host Docker。
- `prepare-source` 和最小原语校验 task 不允许每次运行时重新 `apk add``apt-get install` 或临时下载 browser/runtime 依赖。当前固定工具镜像是 `127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1`,包含 Node 22、npm、Bun、Git、OpenSSH、curl、Python3 和 Docker CLI。镜像内容由 `deploy/ci/hwlab-ci-node-tools.Dockerfile` 声明;脚本启动时必须输出工具与 proxy preflight 结构化日志。缺少工具时应先在 G14 构建并推送新的工具镜像,再修改 `HWLAB_G14_CI_TOOLS_IMAGE`/render 默认值,不能回退到 runtime 安装。
- `prepare-source` 和最小原语校验 task 不允许每次运行时重新 `apk add``apt-get install` 或临时下载 browser/runtime 依赖。当前固定工具镜像是 `127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1`,包含 Node 22、npm、Bun、Git、OpenSSH、curl、Python3 和 Docker CLI。镜像内容由 `deploy/ci/hwlab-ci-node-tools.Dockerfile` 声明;脚本启动时必须输出工具与 proxy preflight 结构化日志。缺少工具时应先在 G14 构建并推送新的工具镜像,再修改 `HWLAB_NODE_CI_TOOLS_IMAGE`/render 默认值,不能回退到 runtime 安装。
- G14 host 只用于 source workspace、GitOps render、k3s 控制和轻量语法/静态合同检查;不要把 host 当成浏览器执行面。低频 browser smoke 已不再属于默认 primitive CI。若确实需要一次性布局、移动端或交互验证,必须显式在 G14 k3s/Tekton 的专用 Playwright 镜像内运行,不能回退成 host 上强装 browser 的长期方案。
- Poller、control-plane reconciler、image publish 和 GitOps promote step 都不允许每次运行时 `apk add` / `apt-get install`。当前 G14 registry 固定工具镜像是 `127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1`,包含 Node 22、npm、Bun、Git、OpenSSH、curl、Python3 和 Docker CLI;生成的脚本只做 proxy preflight 与工具存在性检查。若需要升级工具,先在 G14 构建/推送新的工具镜像,再修改 `HWLAB_G14_CI_TOOLS_IMAGE`/render 默认值并由 reconciler apply。
- 服务镜像构建的默认 parent/base image 不得从 Docker Hub 反复拉取。当前 `node:20-bookworm-slim` 已镜像到 G14 registry 的 allowlist 名称:`127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim`render 默认 `base-image` 和 poller `BASE_IMAGE` 都指向这个本地镜像。需要升级 parent image 时,先通过 G14 proxy 拉取并推送到 G14 registry,再修改 `HWLAB_G14_DEV_BASE_IMAGE`/render 默认值;image publish step 只允许从本地 registry pull base image,且 tag 必须符合 publish gate 的 `hwlab-node20-base`/`hwlab-dev-base`/`hwlab-node-runtime-base` allowlist。
- Poller、control-plane reconciler、image publish 和 GitOps promote step 都不允许每次运行时 `apk add` / `apt-get install`。当前 G14 registry 固定工具镜像是 `127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1`,包含 Node 22、npm、Bun、Git、OpenSSH、curl、Python3 和 Docker CLI;生成的脚本只做 proxy preflight 与工具存在性检查。若需要升级工具,先在 G14 构建/推送新的工具镜像,再修改 `HWLAB_NODE_CI_TOOLS_IMAGE`/render 默认值并由 reconciler apply。
- 服务镜像构建的默认 parent/base image 不得从 Docker Hub 反复拉取。当前 `node:20-bookworm-slim` 已镜像到 G14 registry 的 allowlist 名称:`127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim`render 默认 `base-image` 和 poller `BASE_IMAGE` 都指向这个本地镜像。需要升级 parent image 时,先通过 G14 proxy 拉取并推送到 G14 registry,再修改 `HWLAB_NODE_DEV_BASE_IMAGE`/render 默认值;image publish step 只允许从本地 registry pull base image,且 tag 必须符合 publish gate 的 `hwlab-node20-base`/`hwlab-dev-base`/`hwlab-node-runtime-base` allowlist。
- 任何依赖下载阶段都必须有可观测诊断。生成的 Tekton 脚本在 npm、BuildKit base image/local registry probe 和 GitOps promote 之前输出结构化 `dependency-proxy-probe``dependency-curl-probe``dependency-download-*` 日志,至少包含 phase、目标 URL/镜像、脱敏 proxy、首包耗时、总耗时、下载字节数和速度。CI/CD 卡在下载时,先用这些日志判断是 proxy 不可达、目标源慢、DNS/首包慢还是下载吞吐低,再决定是否切换 G14 代理节点或预热镜像;不能只凭 PipelineRun Running 时长判断业务测试失败。
常用命令:
```sh
npm run g14:gitops:render -- --source-revision <sourceCommit>
npm run gitops:render -- --source-revision <sourceCommit>
```
人工 source workspace 不再对 `deploy/gitops/g14/**` 做生成物对比;这些文件在 source 分支下是忽略的生成物,旧文件和 `source.json` 不是真相。需要看渲染计划时使用 `npm run g14:gitops:render -- --no-write`;正式发布态只看 `G14-gitops`、Argo Application 和 live runtime。
人工 source workspace 不再对 `deploy/gitops/node/**` 做生成物对比;这些文件在 source 分支下是忽略的生成物,旧文件和 `source.json` 不是真相。需要看渲染计划时使用 `npm run gitops:render -- --no-write`;正式发布态只看 `G14-gitops`、Argo Application 和 live runtime。
## 原生 k8s Tekton + Argo 配置面 vs 已废弃的 CI.json runner
@@ -76,14 +76,14 @@ npm run g14:gitops:render -- --source-revision <sourceCommit>
HWLAB 是 monorepoG14 CI/CD 加速必须按组件输入判断构建和滚动;v0.2 env-reuse 的组件边界与环境配方直接来自 `deploy/deploy.yaml`,运行态镜像身份来自 per-service artifact catalog`CI.json` 已删除,不再作为任何 planner 输入。
- `deploy/deploy.yaml` 是当前 v0.2 人写 deploy/runtime 配置单一出处;`deploy/deploy.json` 不得作为 v0.2 兼容源恢复。配置读写由 `scripts/src/structured-config.mjs``scripts/src/deploy-config.mjs` 统一承载,只有该格式无关层直接处理 YAML/JSON 解析;planner、renderer、smoke、artifact helper 和 CLI 只调用读写 helper。
- `scripts/g14-ci-plan.mjs` 是只读 planner,默认读取当前 workspace 的 `deploy/deploy.yaml``deploy/artifact-catalog.dev.json`,以及 `deploy/deploy.yaml` 内的 lane service declarations/env recipe,输出 `affectedServices``reusedServices``componentCommitId``componentInputHash``dockerfileHash``baseImageDigest``buildArgsHash` 和原因;它不得修改 deploy、catalog 或 GitOps 文件。Tekton `prepare-source` 会先从 `G14-gitops` 注入上一轮发布态 catalogsource 分支里的 catalog 只作为 seed contract。
- `scripts/ci-plan.mjs` 是只读 planner,默认读取当前 workspace 的 `deploy/deploy.yaml``deploy/artifact-catalog.dev.json`,以及 `deploy/deploy.yaml` 内的 lane service declarations/env recipe,输出 `affectedServices``reusedServices``componentCommitId``componentInputHash``dockerfileHash``baseImageDigest``buildArgsHash` 和原因;它不得修改 deploy、catalog 或 GitOps 文件。Tekton `prepare-source` 会先从 `G14-gitops` 注入上一轮发布态 catalogsource 分支里的 catalog 只作为 seed contract。
- v0.2 服务清单来自显式 `--services``deploy.lanes.v02.envReuseServices`;旧 `deploy.services[]``deploy.k3s.serviceMappings[]``internal/protocol.SERVICE_IDS` 推导路径不再作为 planner 输入。
- v0.2 env-reuse 组件边界和环境镜像配方以 `deploy/deploy.yaml``lanes.v02.serviceDeclarations``lanes.v02.envRecipe``lanes.v02.bootConfig` 为单一配置点;新增服务或调整 `componentPaths``runtimeKind``entrypoint`、Bun 版本、系统包、launcher 路径和 HWPOD alias 时先改 deploy 配置与 schema/测试,不再把这些属性硬编码进 planner 或 artifact publish helper。
- `hwpod` 是 runner 内的稳定 HWPOD task 入口,由 `tools/hwpod-cli.ts``tools/hwpod-compiler-cli.ts``tools/hwpod-ctl.ts``tools/hwpod-node.ts``skills/hwpod-cli/``skills/hwpod-ctl/` 组成。修改这些路径时,G14/v0.2 CI 必须至少触发携带 `/usr/local/bin/hwpod` 的 runtime skills/env-reuse 重新装配或 rollout,不能全量复用旧 artifact 后只报告 PipelineRun 成功。
- `scripts/g14-artifact-publish.mjs` 默认启用组件级 lazy build:先运行 planner,再只构建/推送 `affectedServices``reusedServices``deploy/artifact-catalog.dev.json` 或 lane catalog 复用已有 sha256 digest。非 env-reuse 服务复用前必须满足 artifact provenance 自证:catalog 有可验证 digest、catalog 的 `sourceCommitId` 在当前 repo 可解析、用该 `sourceCommitId` 的 source tree 重新计算出的 `componentInputHash` 等于 catalog 记录、该 hash 再等于本轮 planner 计算值,且 `dockerfileHash`/`buildArgsHash` 没有不一致。catalog 缺 digest、缺 provenance、source tree 无法解析、catalog hash 与 catalog source tree 不一致、或 catalog hash 与本轮 input 不一致时,planner 必须把该服务列为 affected 并重新发布,不能用旧 guard 阻塞,也不能退回 Docker 或 legacy full-build 路线。
- `scripts/artifact-publish.mjs` 默认启用组件级 lazy build:先运行 planner,再只构建/推送 `affectedServices``reusedServices``deploy/artifact-catalog.dev.json` 或 lane catalog 复用已有 sha256 digest。非 env-reuse 服务复用前必须满足 artifact provenance 自证:catalog 有可验证 digest、catalog 的 `sourceCommitId` 在当前 repo 可解析、用该 `sourceCommitId` 的 source tree 重新计算出的 `componentInputHash` 等于 catalog 记录、该 hash 再等于本轮 planner 计算值,且 `dockerfileHash`/`buildArgsHash` 没有不一致。catalog 缺 digest、缺 provenance、source tree 无法解析、catalog hash 与 catalog source tree 不一致、或 catalog hash 与本轮 input 不一致时,planner 必须把该服务列为 affected 并重新发布,不能用旧 guard 阻塞,也不能退回 Docker 或 legacy full-build 路线。
- Artifact catalog 的 per-service provenance 是镜像 digest 的身份证明,不是本轮 planner 状态缓存。reuse 路径只能保留旧 artifact 自身的 `sourceCommitId``componentCommitId``componentInputHash``dockerfileHash``baseImage*``buildArgsHash`;禁止把当前 planner 的 component/build 元数据写入复用的旧 digest,否则下一轮 planner 会把旧镜像误判成已包含新输入,造成 CI/CD false-green。
- `scripts/g14-artifact-publish.mjs` 的 publish report 必须携带 planner 的 per-service 元数据;`scripts/refresh-artifact-catalog.mjs` 默认只预览,只有 G14 Tekton promotion 显式传 `--write` 时,才把生成的 `commitId``image``imageTag``digest``publishState` 和 component provenance 字段写进当前 workspace 的 `deploy/artifact-catalog.dev.json`,随后只提交到 `G14-gitops``deploy/deploy.yaml` 是人写的 runtime config 真相源,不得被 promotion、refresh 脚本或人工发布流程回写镜像身份字段。
- `scripts/g14-gitops-render.mjs` 只支持混合 desired stateworkload 的 container image、`HWLAB_IMAGE``HWLAB_IMAGE_TAG` 和 pod template `source-commit` 来自 `deploy/artifact-catalog.dev.json` 的 per-service artifact identity;普通 env、replica、healthPath、profile 等配置来自 `deploy/deploy.yaml`。全局 GitOps metadata 仍记录本次 source commit。`--legacy-source-images``HWLAB_G14_USE_DEPLOY_IMAGES=0` 已废弃,不得把所有 workload image 回退渲染为同一个 source commit tag。
- `scripts/artifact-publish.mjs` 的 publish report 必须携带 planner 的 per-service 元数据;`scripts/refresh-artifact-catalog.mjs` 默认只预览,只有 G14 Tekton promotion 显式传 `--write` 时,才把生成的 `commitId``image``imageTag``digest``publishState` 和 component provenance 字段写进当前 workspace 的 `deploy/artifact-catalog.dev.json`,随后只提交到 `G14-gitops``deploy/deploy.yaml` 是人写的 runtime config 真相源,不得被 promotion、refresh 脚本或人工发布流程回写镜像身份字段。
- `scripts/gitops-render.mjs` 只支持混合 desired stateworkload 的 container image、`HWLAB_IMAGE``HWLAB_IMAGE_TAG` 和 pod template `source-commit` 来自 `deploy/artifact-catalog.dev.json` 的 per-service artifact identity;普通 env、replica、healthPath、profile 等配置来自 `deploy/deploy.yaml`。全局 GitOps metadata 仍记录本次 source commit。`--legacy-source-images``HWLAB_NODE_USE_DEPLOY_IMAGES=0` 已废弃,不得把所有 workload image 回退渲染为同一个 source commit tag。
- G14 Tekton promotion 在推送 `G14-gitops` 前,必须用 publish report 显式 `--write` 刷新 workspace 内的 `deploy/artifact-catalog.dev.json`,然后把刷新后的 catalog 和 rendered GitOps desired state 一起提交到 `G14-gitops`。promotion 不得自动修改或推送 `G14` source branch,也不得自动修改 `deploy/deploy.yaml``deploy/k8s/base/workloads.yaml`,这样人写配置不会和 CI 生成身份反复冲突。
- Tekton 并发化只能以 planner 输出作为输入;每个 service 都有独立 TaskRunchanged service 启动 BuildKitunchanged service 只写 reuse result 并复用 catalog digest,且不能改 pod template,避免无意义 rollout。没有完整 per-service desired state 证据时,必须修复 planner/catalog 证据,不能使用 `--full-build``--legacy-source-images`、DIND 或 Docker fallback 回退。
@@ -91,7 +91,7 @@ HWLAB 是 monorepoG14 CI/CD 加速必须按组件输入判断构建和滚动
G14 CI/CD 加速的第一判定标准不是 PipelineRun 总耗时单点变短,而是 monorepo 组件粒度的“少构建、少滚动、可并发”是否成立。
- 触发延迟:`hwlab-g14-branch-poller` 固定每 1 分钟轮询 `G14`。相对 5 分钟轮询,平均触发等待应从约 2.5 分钟降到约 0.5 分钟,最坏等待从 5 分钟降到 1 分钟。发现 `kubectl -n hwlab-ci get cronjob hwlab-g14-branch-poller -o jsonpath='{.spec.schedule}'` 不是 `* * * * *` 时,应先修 poller/reconciler,而不是手工长期创建 PipelineRun。
- 触发延迟:`hwlab-node-branch-poller` 固定每 1 分钟轮询 `G14`。相对 5 分钟轮询,平均触发等待应从约 2.5 分钟降到约 0.5 分钟,最坏等待从 5 分钟降到 1 分钟。发现 `kubectl -n hwlab-ci get cronjob hwlab-node-branch-poller -o jsonpath='{.spec.schedule}'` 不是 `* * * * *` 时,应先修 poller/reconciler,而不是手工长期创建 PipelineRun。
- 组件懒构建:docs-only、GitOps-only、poller/reconciler manifest-only 等不影响服务输入的变更,planner 应输出 `affectedServices=[]``buildSkippedCount=<全部服务数>`,各 service TaskRun 应写出 `status=reused``build-backend=reused-catalog`。这类变更不应重新构建任何服务镜像,也不应把 workload image 改成当前 source commit tag。
- 并发 fan-outper-service TaskRun 应由 Tekton/k8s scheduler 同时调度,多个 service 的 build/reuse 窗口应接近“最慢单个服务任务耗时”,而不是所有服务串行相加。reuse-only 场景的 fan-out 窗口当前基线约为十几秒;真实组件构建场景仍需按 changed service 单独记录 BuildKit 耗时和 cache hit 情况。
- CD rolloutunchanged service 必须复用 `deploy/artifact-catalog.dev.json` 的 image/digestpod template 不应因全局 source commit 改变而无意义滚动。手写 manifest(例如 `deepseek-proxy`、device-agent 类辅助 workload)只要复用某个已发布服务镜像,也必须走同一个 catalog image 选择逻辑,不能直接用当前 source commit tag。
@@ -100,14 +100,14 @@ G14 CI/CD 加速的第一判定标准不是 PipelineRun 总耗时单点变短,
当前仍然慢的主要位置:
- `prepare-source` 与最小原语校验 task 仍是前段主要开销。它们包含 Git clone、checkout、必要的 `npm ci``repo-reports-guard``g14-contract-check``codex-api-forwarder-check`。继续加速应优先减少 workspace cold start 与依赖安装成本,而不是重新塞回一条 shell runner。
- `prepare-source` 与最小原语校验 task 仍是前段主要开销。它们包含 Git clone、checkout、必要的 `npm ci``repo-reports-guard``node-contract-check``codex-api-forwarder-check`。继续加速应优先减少 workspace cold start 与依赖安装成本,而不是重新塞回一条 shell runner。
- `gitops-promote` 仍是大头,当前量级约 100 秒。它包含 source branch freshness check、artifact catalog refresh、render、clone `G14-gitops`、复制 catalog 与 generated desired state、commit 和 push。继续加速应优先减少 git clone/push 成本,例如使用浅 clone、持久 workspace、server-side patch 或把 GitOps repo 操作单独缓存。
- per-service TaskRun 数量增加后会有 k8s 调度和 sidecar 生命周期开销。reuse-only 任务很快,但如果每个 unchanged service 都启动完整 buildkit sidecar,调度开销会抵消部分收益;长期目标是让 unchanged service 走更轻量的 reuse Taskchanged service 才启动 BuildKit。
- per-service BuildKit 必须使用 Pod 内 Unix socket 或其他 Pod-scoped 端点,禁止在 hostNetwork 下绑定固定 TCP 端口。多个 service TaskRun 并发时,如果 sidecar 统一监听 `0.0.0.0:1234`,会抢同一个宿主端口,导致主 step 结果成功但 Pod phase 显示 Failed,严重污染 CI 观测。
- Argo sync/health 不是 instant。`Sync=Synced` 后 health 仍可能因为 replicas=0 的模板 Deployment、未排除 health 的模板 Job 或 StatefulSet 旧 revision 显示 `Suspended`/`Progressing`。这时应先看实际长驻 workload ready 与具体 unhealthy resource,不要只看 Application 总 health;如果 suspended Job 只是模板资源,应修 render 注解而不是把 DEV rollout 判成失败。
- StatefulSet 旧 ordinal pod 可能长期卡在历史缺失镜像上,即使 StatefulSet 当前 template 已经修正。DEV 可按运行面热修流程删除旧 Pending pod 让 StatefulSet 按当前 template 重建;PROD namespace 需要明确 maintenance 授权后再做同类删除。
每次优化 CI/CD 都必须保留可比测量:记录 PipelineRun 总耗时、`prepare-source``repo-reports-guard``g14-contract-check``codex-api-forwarder-check``plan-artifacts`、per-service fan-out 起止窗口、`collect-artifacts``gitops-promote`、Argo sync 到 workload ready 的时间,并标明本轮是 reuse-only、单组件 build 还是多组件 build。没有这些分段数据,不要只用“感觉变快/变慢”判断优化成败。
每次优化 CI/CD 都必须保留可比测量:记录 PipelineRun 总耗时、`prepare-source``repo-reports-guard``node-contract-check``codex-api-forwarder-check``plan-artifacts`、per-service fan-out 起止窗口、`collect-artifacts``gitops-promote`、Argo sync 到 workload ready 的时间,并标明本轮是 reuse-only、单组件 build 还是多组件 build。没有这些分段数据,不要只用“感觉变快/变慢”判断优化成败。
## Code Agent Provider Profiles
@@ -126,15 +126,15 @@ DeepSeek proxy manifest 是 GitOps desired state 的一部分,DEV/PROD 分别
## Polling 触发
G14 不要求 GitHub webhook 或 GitHub Actions 配置。`hwlab-ci/hwlab-g14-branch-poller` CronJob 每 1 分钟通过 Git SSH 拉取 `G14` HEAD,并用 source commit 的前 12 位生成 PipelineRun 名称 `hwlab-g14-ci-poll-<short12>`
G14 不要求 GitHub webhook 或 GitHub Actions 配置。`hwlab-ci/hwlab-node-branch-poller` CronJob 每 1 分钟通过 Git SSH 拉取 `G14` HEAD,并用 source commit 的前 12 位生成 PipelineRun 名称 `hwlab-node-ci-poll-<short12>`
`v0.2` 接入不再新增 HWLAB 发布触发 CronJob;标准入口是 UniDesk CLI `bun scripts/cli.ts hwlab g14 control-plane trigger-current --lane v02 --confirm`,由该入口自动 fetch `/root/hwlab-v02-cicd.git`、解析当前 `origin/v0.2` HEAD,并直接创建可区分的 commit-pinned PipelineRun,例如 `hwlab-v02-ci-poll-<short12>`。该 lane 的 GitOps promotion 只允许写入 `v0.2` 专属 catalog、runtime path 和 GitOps branch;不得向 `G14` 或现有 DEV/PROD runtime path 写入生成物,也不得从 `/root/hwlab-v02` 工作树状态选择待发布 commit。
G14 lane 中如果同名 PipelineRun 已存在,poller 直接跳过;如果不存在,则创建新的 PipelineRun。这样可以用 Kubernetes 原生 CronJob、ServiceAccount、RBAC 和 Tekton API 实现无 GitHub webhook 的分支监控,同时避免同一个 commit 被反复派单。历史上的 `chore: promote G14 GitOps source ...` source 分支生成提交已经废弃;G14 poller 只应该看到人写 source commit。
Pipeline 的标准路径是:`G14` source commit -> Tekton 原语校验 task -> commit-tagged image push 到 G14 registry -> refresh artifact catalog -> render `deploy/gitops/g14/**` -> push catalog 与 GitOps desired state 到 `G14-gitops` -> Argo CD 同步 runtime。CD 只消费已经构建好的镜像和 Git desired state,不在 Argo CD 内构建镜像。
Pipeline 的标准路径是:`G14` source commit -> Tekton 原语校验 task -> commit-tagged image push 到 G14 registry -> refresh artifact catalog -> render `deploy/gitops/node/**` -> push catalog 与 GitOps desired state 到 `G14-gitops` -> Argo CD 同步 runtime。CD 只消费已经构建好的镜像和 Git desired state,不在 Argo CD 内构建镜像。
GitOps promotion 成功只证明 `G14-gitops` 分支已经写入新 desired state;如果 render 改变了 Argo Application、AppProject、runtime path 或 DEV/PROD 拆分目录,必须同步检查并应用 `deploy/gitops/g14/argocd/project.yaml``application-dev.yaml``application-prod.yaml``hwlab-g14-dev` 必须指向 `deploy/gitops/g14/runtime-dev``hwlab-g14-prod` 必须指向 `deploy/gitops/g14/runtime-prod`;如果集群里 Application 仍指向旧 `deploy/gitops/g14/runtime`Argo 会停在旧 revision,即使 CI/publish/promote 全部成功也不会滚动新镜像。
GitOps promotion 成功只证明 `G14-gitops` 分支已经写入新 desired state;如果 render 改变了 Argo Application、AppProject、runtime path 或 DEV/PROD 拆分目录,必须同步检查并应用 `deploy/gitops/node/argocd/project.yaml``application-dev.yaml``application-prod.yaml``hwlab-node-dev` 必须指向 `deploy/gitops/node/runtime-dev``hwlab-node-prod` 必须指向 `deploy/gitops/node/runtime-prod`;如果集群里 Application 仍指向旧 `deploy/gitops/node/runtime`Argo 会停在旧 revision,即使 CI/publish/promote 全部成功也不会滚动新镜像。
观察 PipelineRun、Argo 和 rollout 时使用短连接轮询:一次 `kubectl get` 或有限 `logs --tail` 后返回,由指挥侧间隔重试。不要用长时间 `kubectl wait --timeout=900s` 占住 `tran G14:k3s` 透传锁;如果误用长 wait,只能杀掉本地等待客户端并清理 stale tran lock,不能把这个等待过程当成 CD 失败。
@@ -147,17 +147,17 @@ KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl -n hwlab-ci logs pod/<pipelinerun-t
如果 probe 显示 `proxy-env-missing``proxy-connect-failed``timeout` 或速度长期接近 0,应先按 `/root/docs/vpn-proxy-ops.md` 检查 v2rayN/Hysteria,再重跑 polling。若 probe 正常但后续校验失败,按对应 Tekton task 日志和业务检查排障。
手动 render/apply 只允许作为 bootstrap 或 reconciler 故障抢修;正常路径必须由 `hwlab-g14-control-plane-reconciler` 自动完成 CI 控制面 manifest 更新。
手动 render/apply 只允许作为 bootstrap 或 reconciler 故障抢修;正常路径必须由 `hwlab-node-control-plane-reconciler` 自动完成 CI 控制面 manifest 更新。
修改 `scripts/g14-gitops-render.mjs`、Tekton Pipeline、RBAC、poller 或 reconciler 这类 CI 控制面后,不能立刻用旧集群 PipelineRun 作为新模板验证。必须先确认 `hwlab-g14-control-plane-reconciler` 已完成并且集群内 Pipeline manifest 包含新字段,再触发手动 poller 或等待下一轮 source commit;否则 PipelineRun 会在旧 Pipeline 下创建,容易把已经修复的 sidecar、proxy 或 TaskRun 行为误判为仍然失败。
修改 `scripts/gitops-render.mjs`、Tekton Pipeline、RBAC、poller 或 reconciler 这类 CI 控制面后,不能立刻用旧集群 PipelineRun 作为新模板验证。必须先确认 `hwlab-node-control-plane-reconciler` 已完成并且集群内 Pipeline manifest 包含新字段,再触发手动 poller 或等待下一轮 source commit;否则 PipelineRun 会在旧 Pipeline 下创建,容易把已经修复的 sidecar、proxy 或 TaskRun 行为误判为仍然失败。
## 集群资源
- `hwlab-ci`registry、Tekton runner RBAC、Polling CronJob、Pipeline/PipelineRun 所在 namespace。
- `hwlab-ci/hwlab-g14-control-plane-reconciler`:自动 render/apply G14 CI 控制面 manifest 的 CronJob。
- `argocd`Argo CD 控制面和 `hwlab-g14-dev` / `hwlab-g14-prod` Application 所在 namespace。
- `hwlab-dev`HWLAB DEV runtime namespace,由 Argo CD 应用 `deploy/gitops/g14/runtime-dev`
- `hwlab-prod`HWLAB PROD runtime namespace,由 Argo CD 应用 `deploy/gitops/g14/runtime-prod`;通过 `hwlab-g14-prod-frpc` 映射到 `18666/18667`,正式验收必须同时检查 Argo sync、Deployment ready、FRP public health 与 source commit。
- `hwlab-ci/hwlab-node-control-plane-reconciler`:自动 render/apply G14 CI 控制面 manifest 的 CronJob。
- `argocd`Argo CD 控制面和 `hwlab-node-dev` / `hwlab-node-prod` Application 所在 namespace。
- `hwlab-dev`HWLAB DEV runtime namespace,由 Argo CD 应用 `deploy/gitops/node/runtime-dev`
- `hwlab-prod`HWLAB PROD runtime namespace,由 Argo CD 应用 `deploy/gitops/node/runtime-prod`;通过 `hwlab-node-prod-frpc` 映射到 `18666/18667`,正式验收必须同时检查 Argo sync、Deployment ready、FRP public health 与 source commit。
- `hwlab-v02`HWLAB `v0.2` runtime namespace,只能由 `v0.2` 专属 Argo CD Application 和 GitOps runtime path 管理;规划通过独立 frpc 映射到 `19666/19667`。创建 `hwlab-v02` 不得删除、重命名或改写 `hwlab-dev`/`hwlab-prod`
G14 registry 由 Kubernetes Deployment `hwlab-ci/hwlab-registry` 承载,使用 host network 暴露 `127.0.0.1:5000` 给 k3s/containerd 和 host-network Tekton build pod。旧 host Docker registry 不能与该 Deployment 同时占用 5000 端口。
@@ -181,9 +181,9 @@ G14 GitOps manifests 不包含 D601 kubeconfig、D601 node guard、D601 FRP 公
G14 PR、CI、CD 的判断应按以下顺序收敛真相,越靠前越接近最终运行面:
1. live runtime:目标 namespace 的 Deployment/StatefulSet template、Pod ready、`describe`、容器日志和公网 health。
2. Argo desired state`hwlab-g14-dev` / `hwlab-g14-prod` 的 Application revision、sync、health 和实际 runtime path`v0.2` 接入后还要看 `hwlab-g14-v02` 或等价专属 Application 是否指向 `v0.2` GitOps lane 和 `hwlab-v02`
2. Argo desired state`hwlab-node-dev` / `hwlab-node-prod` 的 Application revision、sync、health 和实际 runtime path`v0.2` 接入后还要看 `hwlab-node-v02` 或等价专属 Application 是否指向 `v0.2` GitOps lane 和 `hwlab-v02`
3. Tekton 执行证据:branch-poller 日志、PipelineRun、TaskRun results、`gitops-promote` 终态。
4. 干净 source workspace`origin/G14` 当前内容,以及 `npm run g14:gitops:render -- --no-write` 和 planner 输出。
4. 干净 source workspace`origin/G14` 当前内容,以及 `npm run gitops:render -- --no-write` 和 planner 输出。
5. 对照线索:旧 commit 记忆、坏 worktree、D601 legacy 路径、脚本旧默认值,只能当线索,不能当真相。
常见误判与纠正:
@@ -214,8 +214,8 @@ bun scripts/cli.ts ssh G14:/root/hwlab shell 'git status --short --branch && git
2. Source / PR 预检
```sh
npm run g14:gitops:render -- --no-write
node scripts/g14-ci-plan.mjs --base-ref origin/G14 --target-ref HEAD --pretty
npm run gitops:render -- --no-write
node scripts/ci-plan.mjs --base-ref origin/G14 --target-ref HEAD --pretty
```
- 先看当前内容和长期参考,不按旧 commit 记忆判断“功能是否已合入”。
@@ -230,12 +230,12 @@ node scripts/g14-ci-plan.mjs --base-ref origin/G14 --target-ref HEAD --pretty
4. 确认 CI 已接单
- 先看最新 branch-poller job 或日志,确认它是否识别到新的 `G14` HEAD。
- 再看 `hwlab-ci` 里的 PipelineRun 是否出现 `hwlab-g14-ci-poll-<short12>`。poller 还没创建 PipelineRun 时,不要先把问题归类为 Tekton 故障。
- 如果本轮改的是 poller、Pipeline、RBAC、reconciler 或 render 模板,先确认 `hwlab-g14-control-plane-reconciler` 已经把新控制面 apply 进去,再用新 commit 验证。
- 再看 `hwlab-ci` 里的 PipelineRun 是否出现 `hwlab-node-ci-poll-<short12>`。poller 还没创建 PipelineRun 时,不要先把问题归类为 Tekton 故障。
- 如果本轮改的是 poller、Pipeline、RBAC、reconciler 或 render 模板,先确认 `hwlab-node-control-plane-reconciler` 已经把新控制面 apply 进去,再用新 commit 验证。
5. 确认 CI 真实通过
- 最低通过条件是:`prepare-source``repo-reports-guard``g14-contract-check``codex-api-forwarder-check``plan-artifacts`、per-service fan-out、`collect-artifacts``gitops-promote` 全部成功。
- 最低通过条件是:`prepare-source``repo-reports-guard``node-contract-check``codex-api-forwarder-check``plan-artifacts`、per-service fan-out、`collect-artifacts``gitops-promote` 全部成功。
- `build-*` fan-out 要按 result 判断 reused 还是 rebuilt;不要只看 TaskRun 名称。
- reuse-only 变更的目标是 `affectedServices=[]`、全部 service `status=reused`,且不触发无意义 rollout。
+10 -10
View File
@@ -1,6 +1,6 @@
# HWLAB 平行 Runtime Lane 扩容规格
本文是 HWLAB `v0.x` 平行 runtime lane 的长期扩容规格。`v0.3` 之后的 `v0.4``v0.5``v0.6` 等扩容必须沿用同一模式:人工只维护 `deploy/deploy.yaml` 中的 lane 声明,然后通过 repo-owned CLI 生成或应用扩容动作;不得再为每个新 lane 复制多处代码、手写 GitOps YAML、手动拼 namespace/Secret/FRP/Tekton/Argo 对象,或恢复 D601/G14 旧兼容路径。
本文是 HWLAB `v0.x` 平行 runtime lane 的长期扩容规格。`v0.3` 之后的 `v0.4``v0.5``v0.6` 等扩容必须沿用同一模式:人工只维护 `deploy/deploy.yaml` 中的 lane 声明,然后通过 repo-owned CLI 生成或应用扩容动作;不得再为每个新 lane 复制多处代码、手写 GitOps YAML、手动拼 namespace/Secret/FRP/Tekton/Argo 对象,或恢复 D601/旧节点兼容路径。
## 标准入口
@@ -17,9 +17,9 @@ node scripts/hwlab-lane-expand.mjs configure --lane v03 --from v02 --write
| `v03` | source branch `v0.3` |
| `v03` | GitOps branch `v0.3-gitops` |
| `v03` | namespace `hwlab-v03` |
| `v03` | runtime path `deploy/gitops/g14/runtime-v03` |
| `v03` | runtime path `deploy/gitops/node/runtime-v03` |
| `v03` | artifact catalog `deploy/artifact-catalog.v03.json` |
| `v03` | Argo Application `hwlab-g14-v03` |
| `v03` | Argo Application `hwlab-node-v03` |
| `v03` | Tekton Pipeline `hwlab-v03-ci-image-publish` |
| `v03` | default legacy FRP ports `19766/19767` |
@@ -37,32 +37,32 @@ node scripts/hwlab-lane-expand.mjs configure --lane v03 --from v02 --write
## GitOps 模块化与严格 TS
`v0.3` 起,GitOps 扩容逻辑不得继续堆进单个 `scripts/g14-gitops-render.mjs`。该文件只保留历史入口兼容、参数解析和高层编排;新增或抽出的 GitOps 逻辑必须进入 `scripts/src/` 下的领域模块,并优先使用 `.ts`
`v0.3` 起,GitOps 扩容逻辑不得继续堆进单个 `scripts/gitops-render.mjs`。该文件只保留历史入口兼容、参数解析和高层编排;新增或抽出的 GitOps 逻辑必须进入 `scripts/src/` 下的领域模块,并优先使用 `.ts`
第一批严格 TS 模块是 `scripts/src/g14-gitops-lane.ts`,负责 runtime lane 的命名、端口、endpoint、branch、catalog 和 `deploy.lanes.<lane>` 回填。该模块由 `tsconfig.gitops.json``strict``exactOptionalPropertyTypes``noUncheckedIndexedAccess` 等选项检查;验证入口是:
第一批严格 TS 模块是 `scripts/src/runtime-lane.ts`,负责 runtime lane 的命名、端口、endpoint、branch、catalog 和 `deploy.lanes.<lane>` 回填。该模块由 `tsconfig.gitops.json``strict``exactOptionalPropertyTypes``noUncheckedIndexedAccess` 等选项检查;验证入口是:
```bash
npm run gitops:ts:check
```
后续从 renderer、Tekton、Argo、FRP、Git mirror 或 artifact helper 继续拆出的模块,必须直接纳入该严格 TS 检查范围;不要先拆成 `.mjs` 再另开长期迁移债。`scripts/g14-gitops-render.mjs` 因为导入 TS 模块,实际执行必须走 Bun 入口:
后续从 renderer、Tekton、Argo、FRP、Git mirror 或 artifact helper 继续拆出的模块,必须直接纳入该严格 TS 检查范围;不要先拆成 `.mjs` 再另开长期迁移债。`scripts/gitops-render.mjs` 因为导入 TS 模块,实际执行必须走 Bun 入口:
```bash
npm run g14:gitops:render -- --lane v03
npm run gitops:render -- --lane v03
```
生成的 Tekton 任务和 control-plane reconciler 也必须使用 `node scripts/run-bun.mjs scripts/g14-gitops-render.mjs ...`,不得再用裸 `node scripts/g14-gitops-render.mjs ...`
生成的 Tekton 任务和 control-plane reconciler 也必须使用 `node scripts/run-bun.mjs scripts/gitops-render.mjs ...`,不得再用裸 `node scripts/gitops-render.mjs ...`
## 废弃路径
`G14` 和 D601 旧分支/runtime 只保留归档或事故对照价值,不再是新 HWLAB runtime lane 的 CI/CD 支持对象。`G14`归档分支名是 `v0.1`CI/CD 不再为了 `v0.1` 保持 namespace、Pipeline、GitOps branch、poller、reconciler 或 FRP 兼容。若旧对象仍存在,应通过受控 CLI 分阶段退役,不能作为 v0.3+ 发布证据。
旧节点和 D601 旧分支/runtime 只保留归档或事故对照价值,不再是新 HWLAB runtime lane 的 CI/CD 支持对象。旧节点归档分支名是 `v0.1`CI/CD 不再为了 `v0.1` 保持 namespace、Pipeline、GitOps branch、poller、reconciler 或 FRP 兼容。若旧对象仍存在,应通过受控 CLI 分阶段退役,不能作为 v0.3+ 发布证据。
## 验收边界
一个新 lane 只有同时满足以下条件才算扩容完成:
- 远端 source branch 和 GitOps branch 存在,并与 `deploy.lanes.<lane>` 声明一致。
- G14 k3s 中存在独立 namespace、Tekton Pipeline/RBAC、Argo AppProject/Application 和 runtime desired state。
- 目标 node k3s 中存在独立 namespace、Tekton Pipeline/RBAC、Argo AppProject/Application 和 runtime desired state。
- runtime namespace、SecretRef、PVC、ServiceAccount、FRP proxy、artifact catalog 和 observability 对象均使用 lane 独立命名。
- `control-plane trigger-current --lane <lane>` 能创建 commit-pinned PipelineRunpromotion 只写入对应 GitOps branch/path。
- 公网 Web/API health 命中该 lane 的 namespace 和 revision;不得用 DEV/PROD、D601 或 `v0.1` health 作为通过证据。
+33 -33
View File
@@ -20,11 +20,11 @@ CI/CD 内部由 UniDesk 受控触发入口、CI/CD 专用 source repo、devops-i
| 接口 | 说明 |
| --- | --- |
| `scripts/g14-gitops-render.mjs --lane v02` | v02 GitOps render 入口,负责 namespace、runtime path、catalog 和 endpoint 固定。 |
| `scripts/gitops-render.mjs --lane v02` | v02 GitOps render 入口,负责 namespace、runtime path、catalog 和 endpoint 固定。 |
| UniDesk v02 PR auto-CD monitor | 观察并合并 base=`v0.2` 的 ready PRmerge 后调用现有 `trigger-current`、定点 `status``git-mirror flush`。 |
| Tekton `hwlab-v02-ci-image-publish` | 构建 affected images、复用 unchanged digest,并 promotion 到 `v0.2-gitops`。 |
| `devops-infra` git mirror/relay | 读写 `v0.2` allowlist refsCI 读 source/catalog、写 `v0.2-gitops`,并通过手动 CLI flush 到 GitHub。 |
| Argo `argocd/hwlab-g14-v02` | 从 `devops-infra` 本地 mirror/relay 的 `v0.2-gitops:deploy/gitops/g14/runtime-v02` 同步到 `hwlab-v02`。 |
| Argo `argocd/hwlab-node-v02` | 从 `devops-infra` 本地 mirror/relay 的 `v0.2-gitops:deploy/gitops/node/runtime-v02` 同步到 `hwlab-v02`。 |
| `http://74.48.78.17:19666/` | v02 Cloud Web 公网入口。 |
| `http://74.48.78.17:19667/health/live` | v02 API/live 公网验收入口。 |
@@ -45,7 +45,7 @@ CI/CD 内部由 UniDesk 受控触发入口、CI/CD 专用 source repo、devops-i
| CI/CD source repo | `G14:/root/hwlab-v02-cicd.git` bare repo,由 UniDesk control-plane 自动 fetch `origin/v0.2`,再从 commit-pinned detached worktree render/apply 控制面 |
| GitOps branch | `v0.2-gitops` |
| Artifact catalog | `v0.2-gitops:deploy/artifact-catalog.v02.json` |
| Runtime path | `v0.2-gitops:deploy/gitops/g14/runtime-v02` |
| Runtime path | `v0.2-gitops:deploy/gitops/node/runtime-v02` |
| Runtime namespace | `hwlab-v02` |
| Tekton Pipeline | `hwlab-ci/hwlab-v02-ci-image-publish` |
| PR merge auto-CD | UniDesk CLI v02 PR monitor 合并 base=`v0.2` PR 后自动调用 `trigger-current`,并定点观察 merge head |
@@ -55,36 +55,36 @@ CI/CD 内部由 UniDesk 受控触发入口、CI/CD 专用 source repo、devops-i
| Tekton ServiceAccount | `hwlab-ci/hwlab-v02-tekton-runner` |
| PipelineRun prefix | `hwlab-v02-ci-poll-<short12>` |
| Argo CD AppProject | `argocd/hwlab-v02` |
| Argo CD Application | `argocd/hwlab-g14-v02` |
| Argo CD Application | `argocd/hwlab-node-v02` |
| FRP Deployment | `hwlab-v02/hwlab-v02-frpc` |
| Web entry | `http://74.48.78.17:19666/` |
| API/live entry | `http://74.48.78.17:19667/health/live` |
| Git mirror/relay | 独立 `devops-infra` 集群读写服务;不设 CronJob;读 source/catalog,写 `v0.2-gitops`,按需由 UniDesk CLI 手动 sync/flush |
| Registry | 维持当前 G14 `hwlab-ci/hwlab-registry` |
`scripts/g14-gitops-render.mjs --lane v02` 是当前 `v0.2` GitOps render 入口。该 lane 必须把默认 source branch 改为 `v0.2`、GitOps branch 改为 `v0.2-gitops`、catalog 改为 `deploy/artifact-catalog.v02.json`、runtime endpoint 改为 `19667`、web endpoint 改为 `19666`,并使用完整 source commit 作为 image tag。
`scripts/gitops-render.mjs --lane v02` 是当前 `v0.2` GitOps render 入口。该 lane 必须把默认 source branch 改为 `v0.2`、GitOps branch 改为 `v0.2-gitops`、catalog 改为 `deploy/artifact-catalog.v02.json`、runtime endpoint 改为 `19667`、web endpoint 改为 `19666`,并使用完整 source commit 作为 image tag。
## 真相源
`v0.2` 的发布真相按以下顺序判断:
1. live runtime`hwlab-v02` namespace 中 Deployment/StatefulSet template、Pod ready、事件、日志和 `19666/19667` 公网 health。
2. Argo desired state`argocd/hwlab-g14-v02` 的 revision、sync、health、source branch 和 runtime path。
2. Argo desired state`argocd/hwlab-node-v02` 的 revision、sync、health、source branch 和 runtime path。
3. CI/CD source refsUniDesk control-plane 专用 bare repo `refs/remotes/origin/v0.2`、devops-infra mirror/relay 的 `refs/heads/v0.2``refs/mirror-stage/heads/v0.2` 必须共同指向最新 source commit。
4. devops-infra mirror/relay 中的 GitOps branch`v0.2-gitops` 中的 `deploy/artifact-catalog.v02.json``deploy/gitops/g14/runtime-v02/**`
4. devops-infra mirror/relay 中的 GitOps branch`v0.2-gitops` 中的 `deploy/artifact-catalog.v02.json``deploy/gitops/node/runtime-v02/**`
5. Tekton 执行证据:UniDesk `trigger-current` 返回的 PipelineRun、TaskRun result、`gitops-promote` 终态。
6. GitHub 上游归档状态:mirror/relay flush 后的 `origin/v0.2-gitops``origin/v0.2`
7. 固定开发 workspace`/root/hwlab-v02``HEAD`、dirty 状态和 `origin/v0.2` 只作为人工开发对照线索;即使 workspace 脏或落后,也不得影响 CI/CD source commit 选择。
旧 commit 记忆、`G14`/`G14-gitops` DEV/PROD 产物、D601 legacy 路径、GitHub 上游尚未 flush 的短暂落后、source branch 中历史 generated 文件、固定开发 workspace 脏状态和临时 worktree 只能作为线索,不能作为 `v0.2` 发布通过证据。
source workspace 中被 `.gitignore` 忽略的 `deploy/gitops/g14/runtime-v02/**` 文件只可能是本地生成缓存。若这类文件与 `v0.2-gitops` 或 live runtime 不一致,应删除本地缓存并以 `v0.2-gitops`、Argo 和 live ConfigMap/Deployment 为准;不要在 source branch 修补 ignored generated 文件,也不要把它们的内容写入 issue closeout 作为发布证据。
source workspace 中被 `.gitignore` 忽略的 `deploy/gitops/node/runtime-v02/**` 文件只可能是本地生成缓存。若这类文件与 `v0.2-gitops` 或 live runtime 不一致,应删除本地缓存并以 `v0.2-gitops`、Argo 和 live ConfigMap/Deployment 为准;不要在 source branch 修补 ignored generated 文件,也不要把它们的内容写入 issue closeout 作为发布证据。
## Workspace 与 CI/CD 分离
`v0.2` 开发 workspace 和 CI/CD repo 必须分离。`/root/hwlab-v02` 是人工开发、短连接 `hwlab-cli` 和问题复现的固定 workspace;它允许出现并行任务产生的 untracked `.worktree/`、本地 dirty 文件或临时落后状态。CI/CD 不从该 checkout 的 `HEAD`、工作树 clean 状态或本地 branch 读取待发布 commit,也不得因为该 workspace 脏而跳过、误判或复用旧 PipelineRun。
UniDesk control-plane 必须使用独立 bare repo `/root/hwlab-v02-cicd.git` 作为 CI/CD source repo:每次 `status``apply``git-mirror apply``trigger-current` 先自动 fetch `origin/v0.2``refs/remotes/origin/v0.2`,再用目标 commit 创建 detached temp worktree 运行 `scripts/g14-gitops-render.mjs --lane v02`。该 repo 没有业务工作树,因此不会被人工开发 dirty 状态污染;如果它不可用,应以 `v02-head-unresolved` 或等价结构化错误失败,而不是回退到固定 workspace HEAD。
UniDesk control-plane 必须使用独立 bare repo `/root/hwlab-v02-cicd.git` 作为 CI/CD source repo:每次 `status``apply``git-mirror apply``trigger-current` 先自动 fetch `origin/v0.2``refs/remotes/origin/v0.2`,再用目标 commit 创建 detached temp worktree 运行 `scripts/gitops-render.mjs --lane v02`。该 repo 没有业务工作树,因此不会被人工开发 dirty 状态污染;如果它不可用,应以 `v02-head-unresolved` 或等价结构化错误失败,而不是回退到固定 workspace HEAD。
devops-infra git mirror 仍是 PipelineRun 和 Argo CD 的集群内读写源。`trigger-current --lane v02 --confirm` 在创建 PipelineRun 前必须比较 `expectedSourceHead` 与 mirror `localV02`,不一致时自动执行 bounded `git-mirror sync` Job。`git-mirror status` 必须分别暴露 `localV02``githubV02``localGitops``githubGitops``sourceInSync``gitopsInSync``pendingFlush``githubInSync` 不得再被理解为只代表 GitOps branch。
@@ -99,7 +99,7 @@ devops-infra git mirror 仍是 PipelineRun 和 Argo CD 的集群内读写源。`
`v0.2` source branch 不得跟踪:
- `deploy/artifact-catalog.v02.json`
- `deploy/gitops/g14/runtime-v02/**`
- `deploy/gitops/node/runtime-v02/**`
- Tekton/Argo 的 rendered runtime desired state。
- image digest、publish state、reuse evidence 或 CI 生成的 rollout metadata。
@@ -108,7 +108,7 @@ devops-infra git mirror 仍是 PipelineRun 和 Argo CD 的集群内读写源。`
`v0.2-gitops` branch 必须包含:
- `deploy/artifact-catalog.v02.json`,记录 image tag、digest、source commit、component identity、publish/reuse 状态。
- `deploy/gitops/g14/runtime-v02/**`,作为 Argo CD 实际消费的 desired state。
- `deploy/gitops/node/runtime-v02/**`,作为 Argo CD 实际消费的 desired state。
- 必要的 generated metadata,但不得包含 Secret 值。
首次初始化时,如果 `v0.2-gitops:deploy/artifact-catalog.v02.json` 尚不存在,只允许由 `v0.2` lane 的正式初始化步骤创建第一版 catalog。不得 fallback 到 `G14` source catalog、`G14-gitops` catalog、DEV runtime path 或 source branch 生成物。
@@ -131,8 +131,8 @@ devops-infra git mirror 仍是 PipelineRun 和 Argo CD 的集群内读写源。`
service source 或 boot script 的 code-only 变化只更新三变量和 GitOps desired state,不再重新构建业务镜像。
`hwlab-codex-api-forwarder` sidecar 和 `hwlab-deepseek-proxy``responses-bridge``hwlab-cloud-api` 的运行面关联容器,复用 `hwlab-cloud-api-env` 并通过各自 boot script 启动;它们不是独立 service matrix 成员,也不得增加第六个 env-reuse service。
CLI、CaseRun、HWPOD workspace 工具、文档、测试和其他非 service 资产不进入 env-reuse service 触发面。
8. promotion 刷新 `deploy/artifact-catalog.v02.json`render `deploy/gitops/g14/runtime-v02/**`,只在本 PipelineRun 的 source commit 仍是当前 `origin/v0.2` head 时推送到 `devops-infra` mirror/relay 的 `v0.2-gitops`;若 source branch 已推进,本轮输出 superseded/no-op,写出 `runtime-ready-required=false`,不得回写旧 GitOps revision。
9. `hwlab-g14-v02` 从本地 mirror/relay 的 `v0.2-gitops:deploy/gitops/g14/runtime-v02` 同步到 `hwlab-v02`
8. promotion 刷新 `deploy/artifact-catalog.v02.json`render `deploy/gitops/node/runtime-v02/**`,只在本 PipelineRun 的 source commit 仍是当前 `origin/v0.2` head 时推送到 `devops-infra` mirror/relay 的 `v0.2-gitops`;若 source branch 已推进,本轮输出 superseded/no-op,写出 `runtime-ready-required=false`,不得回写旧 GitOps revision。
9. `hwlab-node-v02` 从本地 mirror/relay 的 `v0.2-gitops:deploy/gitops/node/runtime-v02` 同步到 `hwlab-v02`
10. UniDesk CLI auto-CD 观察定点 `control-plane status --lane v02 --source-commit <merge-head>``--pipeline-run <name>`,确认 PipelineRun、Argo、runtime workload、public probes 和 planArtifacts build/reuse 摘要。历史 merge head 若因后续 `origin/v0.2` 推进而被 supersededPR 评论以 superseded 收口;最新 head 仍必须继续收敛到 runtime。
11. UniDesk CLI 或 mirror/relay flush 操作把本地 `v0.2-gitops` 推送到 GitHub canonical remoteflush 不在 CI runtime-ready 的关键路径内,但自动 CD 收口必须查询 pending、lastFlushed 和 failure,必要时执行 `git-mirror flush --confirm` 并等待 `pendingFlush=false`
12. 验收只观察 `hwlab-v02` runtime 和 `19666/19667`,并把 source commit、PipelineRun、GitOps revision、build/reuse 摘要、Argo/runtime/public probe 状态写回 PR 或关联 issue。
@@ -143,7 +143,7 @@ devops-infra git mirror 仍是 PipelineRun 和 Argo CD 的集群内读写源。`
GitOps promotion 成功后,本地 mirror/relay 的 `v0.2-gitops` 可立即被 Argo 消费;GitHub 上游 flush 是归档与跨节点同步步骤,不在 runtime-ready 关键路径内。`git-mirror status.pendingFlush=true` 时自动 CD 和人工收口都应运行 `git-mirror flush --confirm`,再用该 flush job 的 `job status``git-mirror status` 确认 `pendingFlush=false``localGitops=githubGitops`。不要把 pending flush 误判为 runtime 未发布,也不要在 flush job 仍运行时反复做全量 status。
`v0.2` 可以复用 G14 的 registry、proxy、BuildKit、工具镜像和脚本库;不得复用 `hwlab-g14-ci-image-publish``hwlab-g14-branch-poller``hwlab-g14-control-plane-reconciler``G14-gitops` runtime path 或 DEV/PROD Argo Application 作为 `v0.2` 发布入口。运行时不得为每个版本硬编码 namespace、catalog、runtime path 或健康判断;版本差异只通过 `deploy.yaml.lanes[profile]`、GitOps render 输入和实际 runtime 对象表达,新增版本不得新增运行时代码分支。
`v0.2` 可以复用 G14 的 registry、proxy、BuildKit、工具镜像和脚本库;不得复用 `hwlab-node-ci-image-publish``hwlab-node-branch-poller``hwlab-node-control-plane-reconciler``G14-gitops` runtime path 或 DEV/PROD Argo Application 作为 `v0.2` 发布入口。运行时不得为每个版本硬编码 namespace、catalog、runtime path 或健康判断;版本差异只通过 `deploy.yaml.lanes[profile]`、GitOps render 输入和实际 runtime 对象表达,新增版本不得新增运行时代码分支。
`v0.2` 不设 k8s 自动轮询发布。历史上若存在 `hwlab-v02-branch-poller``hwlab-v02-control-plane-reconciler` 或等价 CronJob,均视为迁移残留,应由 UniDesk control-plane apply 清理。PR 合并后的自动 CD 只能由 UniDesk CLI monitor 或一次性 reconcile job 驱动,并且必须复用 `trigger-current`、定点 `status``git-mirror flush`。暂停发布时停止 UniDesk monitor 或停止创建新的 PipelineRun;不要通过新增 CronJob 维持重试。
@@ -280,7 +280,7 @@ P1 no-op runtime skip 只跳过无实际 runtime 变化的等待。planner 输
Pipeline 内部的 no-op fast lane 必须形成完整证据链。
`prepare-source` 输出 `source-clone``catalog-fetch` timing。
`plan-artifacts` 输出 `g14-ci-plan`,其中 `buildServices=[]``rolloutServices=[]` 且 runtime service 全部 reuse。
`plan-artifacts` 输出 `ci-plan`,其中 `buildServices=[]``rolloutServices=[]` 且 runtime service 全部 reuse。
`gitops-promote` 输出 `skipped-runtime-unchanged``runtime-identity-only`,并把 `gitops-commit``gitops-push` 标为 `skipped`
PipelineRun 的 skipped tasks 中必须包含 `runtime-ready`
这条证据链缺一项时,不能只看总耗时通过,应先确认是日志缺失、planner 误判还是 GitOps runtime 比对退化。
@@ -340,7 +340,7 @@ for task in prepare-source plan-artifacts collect-artifacts gitops-promote runti
-o jsonpath="{.items[0].metadata.name}")
echo "--- $task $pod selected logs ---"
pattern="skipped-runtime-unchanged|runtime-ready-required|runtime-identity-only"
pattern="$pattern|g14-cicd-timing|git-operation|g14-ci-plan|artifact_reuse|buildSkippedCount"
pattern="$pattern|node-cicd-timing|git-operation|ci-plan|artifact_reuse|buildSkippedCount"
pattern="$pattern|gitops-commit|gitops-push|runtime-ready|progress|argo-refresh"
pattern="$pattern|argo-sync-health|workload-ready|observedCount"
kubectl logs -n "$ns" "$pod" --all-containers=true | \
@@ -356,7 +356,7 @@ done
| `prepare-source` 回到 20s 以上 | 日志是否出现 `npm ci`、npm registry probe、GitHub URL、SSH setup 或长时间 catalog fetch | 拆掉无效依赖安装和重复探针;读路径必须回到 mirror。 |
| `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。 |
| `buildSkippedCount` 偏低或突然变成 0 | `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 判定。 |
@@ -488,7 +488,7 @@ registry 与 git mirror/relay 分属不同基础设施边界。registry 保持
- `hwlab-v02` namespace 只能由 `v0.2` GitOps lane 管理。
- `argocd/hwlab-v02` AppProject destination 只能包含 `hwlab-v02`
- `argocd/hwlab-g14-v02` source 必须指向 `devops-infra` 本地 mirror/relay 中的 `v0.2-gitops:deploy/gitops/g14/runtime-v02`destination 必须是 `hwlab-v02`
- `argocd/hwlab-node-v02` source 必须指向 `devops-infra` 本地 mirror/relay 中的 `v0.2-gitops:deploy/gitops/node/runtime-v02`destination 必须是 `hwlab-v02`
- `hwlab-v02-frpc` 只能暴露 `19666/19667`,不能复用 `17666/17667``18666/18667`
- `v0.2` Secret、DB 凭据、PVC、ServiceAccount 和 runtime config 必须独立命名或独立 namespace scope;文档、issue、trace 和 report 只记录 SecretRef 名称与 key,不记录值。
- `v0.2` 初期不新增自动 registry GC;后续如启用清理,selector 必须带 lane/profile 标签,registry digest 保护集必须同时覆盖 `G14-gitops``v0.2-gitops`
@@ -502,11 +502,11 @@ registry 与 git mirror/relay 分属不同基础设施边界。registry 保持
- GitOps branch 必须是 `v0.2-gitops`
- runtime namespace 必须是 `hwlab-v02`
- artifact catalog 必须是 `deploy/artifact-catalog.v02.json`
- runtime path 必须是 `deploy/gitops/g14/runtime-v02`
- Argo Application 必须是 `hwlab-g14-v02`,且只能部署到 `hwlab-v02`
- source branch publish 后不得出现 `deploy/artifact-catalog.v02.json``deploy/gitops/g14/runtime-v02/**` 变更。
- source workspace 下若残留 ignored `deploy/gitops/g14/runtime-v02/**` 生成物,不能作为 source diff、PR 内容、回归证据或人工修补目标;发现和当前 `v0.2-gitops` 不一致时删除本地缓存。
- GitOps promotion 的 changed paths 只能落在 `deploy/artifact-catalog.v02.json``deploy/gitops/g14/runtime-v02/**` 及必要的 v02 Argo/GitOps 元数据。
- runtime path 必须是 `deploy/gitops/node/runtime-v02`
- Argo Application 必须是 `hwlab-node-v02`,且只能部署到 `hwlab-v02`
- source branch publish 后不得出现 `deploy/artifact-catalog.v02.json``deploy/gitops/node/runtime-v02/**` 变更。
- source workspace 下若残留 ignored `deploy/gitops/node/runtime-v02/**` 生成物,不能作为 source diff、PR 内容、回归证据或人工修补目标;发现和当前 `v0.2-gitops` 不一致时删除本地缓存。
- GitOps promotion 的 changed paths 只能落在 `deploy/artifact-catalog.v02.json``deploy/gitops/node/runtime-v02/**` 及必要的 v02 Argo/GitOps 元数据。
- 公网验收只能使用 `19666/19667`
- `v0.2` 不得创建或依赖 k8s CronJob`hwlab-v02-branch-poller``hwlab-v02-control-plane-reconciler` 或同类调度器出现时应清理,而不是接入发布链路。
- GitHub webhook 不是 v02 首期自动 CD 的必需入口;若未来接入,只能作为唤醒信号,不能直接决定发布 commit 或创建 PipelineRun。
@@ -527,11 +527,11 @@ registry 与 git mirror/relay 分属不同基础设施边界。registry 保持
- `G14` source branch 的 poller/reconciler 语义。
- `G14-gitops` DEV/PROD catalog 与 runtime desired state。
- `hwlab-dev``hwlab-prod` namespace。
- `hwlab-g14-dev``hwlab-g14-prod` Argo Application。
- `hwlab-node-dev``hwlab-node-prod` Argo Application。
- DEV `17666/17667` 与 PROD `18666/18667` FRP 入口。
- D601 legacy 回溯路径和旧运行面边界。
如果 `v0.2` 接入失败,回滚或暂停只能作用于 `hwlab-v02` lane:停止 UniDesk v02 monitor、停止手动触发新的 v02 PipelineRun、暂停或删除 `hwlab-g14-v02`、回滚 `v0.2-gitops` runtime path、关闭 `hwlab-v02-frpc` 或清理 `hwlab-v02` namespace 资源;不得通过新增 CronJob 维持重试,也不得重启、删除或回滚 DEV/PROD 运行面。
如果 `v0.2` 接入失败,回滚或暂停只能作用于 `hwlab-v02` lane:停止 UniDesk v02 monitor、停止手动触发新的 v02 PipelineRun、暂停或删除 `hwlab-node-v02`、回滚 `v0.2-gitops` runtime path、关闭 `hwlab-v02-frpc` 或清理 `hwlab-v02` namespace 资源;不得通过新增 CronJob 维持重试,也不得重启、删除或回滚 DEV/PROD 运行面。
## 验收标准
@@ -542,10 +542,10 @@ registry 与 git mirror/relay 分属不同基础设施边界。registry 保持
- 同一个 source commit 已有 PipelineRun 时不重复创建,也不删除重建;失败 run 的人工重试必须走后续显式 retry 策略,不恢复默认 delete/create。
- 自动 CD 在旧 run 运行期间遇到新 `origin/v0.2` head 时,新 head 可直接触发自己的 PipelineRun;旧 run 继续完成 CI,但 promotion 必须在写 GitOps 前发现 stale head 并 superseded/no-op,不能回写旧 `v0.2-gitops` 或回滚 runtime。
- 最新 `v0.2` source commit 对应的 PipelineRun 完成,且 promotion 写入 `v0.2-gitops`
- `v0.2-gitops` 中存在 `deploy/artifact-catalog.v02.json``deploy/gitops/g14/runtime-v02/**`
- `argocd/hwlab-g14-v02` 指向 `devops-infra` 本地 mirror/relay 的 `v0.2-gitops:deploy/gitops/g14/runtime-v02`sync revision 与目标 GitOps revision 对齐。
- `v0.2-gitops` 中存在 `deploy/artifact-catalog.v02.json``deploy/gitops/node/runtime-v02/**`
- `argocd/hwlab-node-v02` 指向 `devops-infra` 本地 mirror/relay 的 `v0.2-gitops:deploy/gitops/node/runtime-v02`sync revision 与目标 GitOps revision 对齐。
- `hwlab-v02` 中长驻 workload ready,没有把 DEV/PROD namespace 当成 `v0.2` 通过证据。
- `gitops-promote` 推送本地 mirror/relay 的 `v0.2-gitops` 后应触发 `argocd/hwlab-g14-v02` hard refresh,减少 GitOps push 与 Argo 仓库发现之间的漂移窗口;refresh 触发失败只作为低噪声事件输出,最终通过仍由 `runtime-ready` 判定。
- `gitops-promote` 推送本地 mirror/relay 的 `v0.2-gitops` 后应触发 `argocd/hwlab-node-v02` hard refresh,减少 GitOps push 与 Argo 仓库发现之间的漂移窗口;refresh 触发失败只作为低噪声事件输出,最终通过仍由 `runtime-ready` 判定。
- mirror/relay status 必须能显示本地 `v0.2-gitops` revision、GitHub 已 flush revision、pending flush revision 和最近一次 flush 错误;CI 通过不要求 GitHub flush 已完成,但 auto-CD 收口必须在 `pendingFlush=true` 时触发 flush 并最终观察到 `pendingFlush=false`
- `runtime-ready` 必须以 workload Pod template 的 source commit 判断 Argo 刷新,并在 Argo 刷新超时、observer RBAC 不足或 workload 未就绪时失败;不得把 CrashLoop、未刷新或公网不可用的 runtime 标成绿色。
- 启用 env 容器复用的 runtime service 必须在 catalog、Pod template annotation/env 和 `/health/live` 或等价 runtime identity 中同时暴露 env image digest 与 `HWLAB_BOOT_REPO`/`HWLAB_BOOT_COMMIT`/`HWLAB_BOOT_SH`;只暴露镜像 digest 不能证明 service code-only rollout 已生效。
@@ -557,7 +557,7 @@ registry 与 git mirror/relay 分属不同基础设施边界。registry 保持
- `trigger-current` 的异步 job 或 `--wait` 输出必须能显示 trigger 阶段进度;若 control-plane refresh、mirror pre-sync 或 delete/create PipelineRun 卡住,日志必须能定位阶段名和状态。
- 自动 CD 回写 PR 或关联 issue 的 rollout 评论必须包含 source commit、PipelineRun、GitOps revision、planArtifacts build/reuse 摘要、Argo/runtime/public probe 状态和耗时;该评论不能替代需要用户原入口验收的问题关闭证据。
- 自动 CD 过程中 source branch 的 `deploy/deploy.yaml` 不得出现 `commitId`、service `image``HWLAB_COMMIT_ID``HWLAB_IMAGE``HWLAB_IMAGE_TAG` 回写。
- no-op env-reuse fast lane 必须输出完整证据链:`g14-ci-plan` 全复用、`skipped-runtime-unchanged``gitops-commit`/`gitops-push` skipped、`runtime-ready` skipped。
- no-op env-reuse fast lane 必须输出完整证据链:`ci-plan` 全复用、`skipped-runtime-unchanged``gitops-commit`/`gitops-push` skipped、`runtime-ready` skipped。
不能只用 PipelineRun `Completed` 或总耗时证明没有退化。
- 真实 rollout 的 `runtime-ready` 必须输出 `started`、周期性 `progress` 和最终 `argo-refresh`/`argo-sync-health`/`workload-ready` 类事件;缺少这些事件时应按可见性回归处理。
- Bun 语法检查和测试入口必须分开:`bun --check <file.ts>` 只用于非测试 TypeScript 源文件语法/转译检查;`*.test.ts``*.test.mts` 或其他使用 `test(...)` 的文件必须用 `bun test <file>` 或 repo-owned package script 执行。不得再用 `bun --check` 直接跑 `.test.ts`,该命令会在测试运行器外求值并报 `Cannot use test outside of the test runner`,这不是业务回归证据。
@@ -568,11 +568,11 @@ GitOps branch 已更新、source branch render 通过、PipelineRun 名称存在
## T1
阅读 docs/reference/spec-v02-cicd.md,然后用 cli 手动测试以下内容:确认 `origin/v0.2` 最新 commit 对应的 PipelineRun 完成,promotion 只写入 `v0.2-gitops`,且 source branch 没有跟踪 `deploy/artifact-catalog.v02.json``deploy/gitops/g14/runtime-v02/**` 生成物。
阅读 docs/reference/spec-v02-cicd.md,然后用 cli 手动测试以下内容:确认 `origin/v0.2` 最新 commit 对应的 PipelineRun 完成,promotion 只写入 `v0.2-gitops`,且 source branch 没有跟踪 `deploy/artifact-catalog.v02.json``deploy/gitops/node/runtime-v02/**` 生成物。
## T2
阅读 docs/reference/spec-v02-cicd.md,然后用 cli 手动测试以下内容:查询 Argo `hwlab-g14-v02`,确认 source repo 为 `devops-infra` 本地 mirror/relaybranch/path 为 `v0.2-gitops:deploy/gitops/g14/runtime-v02`destination namespace 为 `hwlab-v02`sync revision 与目标 GitOps revision 对齐。
阅读 docs/reference/spec-v02-cicd.md,然后用 cli 手动测试以下内容:查询 Argo `hwlab-node-v02`,确认 source repo 为 `devops-infra` 本地 mirror/relaybranch/path 为 `v0.2-gitops:deploy/gitops/node/runtime-v02`destination namespace 为 `hwlab-v02`sync revision 与目标 GitOps revision 对齐。
## T3
@@ -615,7 +615,7 @@ GitOps branch 已更新、source branch render 通过、PipelineRun 名称存在
| PR merge 后自动 CD | 待迁移 | 目标见 #848UniDesk CLI v02 PR monitor 合并 base=`v0.2` PR 后复用 `trigger-current`、定点 `status``git-mirror flush`;首期不要求 GitHub webhook,也不创建 k8s CronJob。 |
| v02 runtime readiness fail-closed | 已实现 | `gitops-promote` 推送后触发 Argo hard refresh`runtime-ready` 读取 workload Pod template source committimeout、observer RBAC 不足或未就绪会让 PipelineRun 失败。 |
| v02 裁撤服务不进入发布面 | 已实现 | v02 Tekton build service set、artifact catalog 和 runtime render 只包含保留服务;v02 Argo 开启 prune 清理旧 live 对象;裁撤服务仍可保留在 DEV legacy 源码中。 |
| Argo v02 Application | 已实现 | `hwlab-g14-v02` 指向 v02 GitOps path 和 namespace。 |
| Argo v02 Application | 已实现 | `hwlab-node-v02` 指向 v02 GitOps path 和 namespace。 |
| FRP `19666/19667` 入口 | 已实现 | 由 `hwlab-v02-frpc` 与 master frps allowlist 共同提供。 |
| SecretRef 独立与 provider 验收 | 已实现/持续约束 | SecretRef 已独立;验收必须做真实短连接聊天。 |
| env 容器复用三变量启动 | 已实现/持续约束 | 五个 v0.2 runtime service 均启用 env-reuse fast lane,并由 CI/CD 自动推导 `HWLAB_BOOT_REPO``HWLAB_BOOT_COMMIT``HWLAB_BOOT_SH`service code-only rollout 复用 env image digest,只更新代码身份。 |
@@ -653,7 +653,7 @@ Code Agent 的 Secret 修复不是只改一个 Secret 对象就结束。`hwlab-c
### GitOps 与 runtime 收敛
GitOps promotion 成功不等于 runtime 已经运行新版本。验收必须等待 `argocd/hwlab-g14-v02` 的 sync revision 对齐最新 `v0.2-gitops` revision,并确认 `19667/health/live``environment``endpoint`、关键 SecretRef 和 service revision 与目标 lane 对齐。
GitOps promotion 成功不等于 runtime 已经运行新版本。验收必须等待 `argocd/hwlab-node-v02` 的 sync revision 对齐最新 `v0.2-gitops` revision,并确认 `19667/health/live``environment``endpoint`、关键 SecretRef 和 service revision 与目标 lane 对齐。
Argo `Synced/Healthy` 也不能单独替代公网验证。FRP server 侧 `allowPorts` 缺失时,`hwlab-v02-frpc` 会反复报告 `port not allowed`;这种问题应修 master 侧 `frps` allowlist 并只重启 `hwlab-frps-dev`,不要改 DEV/PROD GitOps、Service 或 v02 runtime path。修复后必须同时验证新增 `19666/19667` 和既有 DEV `17666/17667`
@@ -6,7 +6,7 @@
- G14 共享监控控制面运行在 `devops-infra` 平台基础设施 namespace,由 UniDesk/G14 基础设施规格管理。它承载 Prometheus Operator、Prometheus 实例、可选 Alertmanager/Grafana 以及跨 namespace scrape 选择策略。
- `hwlab-v02` 只承载 HWLAB 业务服务、`/metrics` endpoint、Service labels/ports、`ServiceMonitor` / `PodMonitor``PrometheusRule`。不得把 Prometheus Operator、Prometheus、Grafana 或 Alertmanager 部署进 `hwlab-v02`
- `hwlab-g14-v02` Argo Application 仍只同步 `deploy/gitops/g14/runtime-v02``hwlab-v02`。监控控制面不能挂到这个 Application;它只消费业务 namespace 中的监控声明。
- `hwlab-node-v02` Argo Application 仍只同步 `deploy/gitops/node/runtime-v02``hwlab-v02`。监控控制面不能挂到这个 Application;它只消费业务 namespace 中的监控声明。
- `hwlab-cli` 或 UniDesk 受控 CLI 可以作为查询入口,但必须通过 runtime namespace/lane 自动解析目标,不得手动暴露 Prometheus 公网地址。
## 内部架构
@@ -91,7 +91,7 @@ sidecar 必须至少暴露以下基础指标:
### `ServiceMonitor`
`deploy/gitops/g14/runtime-v02` 应生成或包含 v0.2 业务服务的 `ServiceMonitor`。Selector 必须同时约束:
`deploy/gitops/node/runtime-v02` 应生成或包含 v0.2 业务服务的 `ServiceMonitor`。Selector 必须同时约束:
- namespace 为 `hwlab-v02`
- `hwlab.pikastech.local/gitops-target=v02`
@@ -139,7 +139,7 @@ HWLAB v0.2 可声明 `PrometheusRule`,但规则只表达当前 v0.2 目标行
## T3
阅读本文,然后用 CLI 手动测试以下内容:读取 `deploy/gitops/g14/runtime-v02` 或 live `hwlab-v02` 对象,确认 `ServiceMonitor` selector 限定 `hwlab-v02``gitops-target=v02``monitoring=enabled` 和具体 service id;确认不存在把 Prometheus、Grafana 或 Alertmanager 部署到 `hwlab-v02` 的对象。
阅读本文,然后用 CLI 手动测试以下内容:读取 `deploy/gitops/node/runtime-v02` 或 live `hwlab-v02` 对象,确认 `ServiceMonitor` selector 限定 `hwlab-v02``gitops-target=v02``monitoring=enabled` 和具体 service id;确认不存在把 Prometheus、Grafana 或 Alertmanager 部署到 `hwlab-v02` 的对象。
## T4
+2 -2
View File
@@ -96,7 +96,7 @@ origin/v0.2
| `frpc` / `frps` | 外部稳定服务 | 保留 | [spec-v02-frpc.md](spec-v02-frpc.md) |
| Postgres | 外部稳定服务 | 保留 | [spec-v02-postgres.md](spec-v02-postgres.md) |
| OpenFGA | 外部稳定服务 / 内部授权 PDP | 新增并保留,ClusterIP-only | [spec-v02-openfga-authorization.md](spec-v02-openfga-authorization.md) |
| Argo CD / Tekton / BuildKit / registry | 外部稳定服务 | 保留 | [spec-v02-cicd.md](spec-v02-cicd.md)、[g14-gitops-cicd.md](g14-gitops-cicd.md) |
| Argo CD / Tekton / BuildKit / registry | 外部稳定服务 | 保留 | [spec-v02-cicd.md](spec-v02-cicd.md)、[node-gitops-cicd.md](node-gitops-cicd.md) |
| Codex CLI | 外部工具/runtime | 保留 | [code-agent-chat-readiness.md](code-agent-chat-readiness.md) |
| Keil / pyOCD / UART 工具 | 外部或主机侧工具 | 由 HWPOD spec 和 node-ops 绑定使用 | [spec-hwpod-harness.md](spec-hwpod-harness.md) |
@@ -121,7 +121,7 @@ hwlab-agent-worker
## T1
阅读 docs/reference/spec-v02-services.md,然后用 CLI 手动测试以下内容:列出 `deploy/deploy.yaml``deploy/deploy.schema.json``deploy/artifact-catalog.dev.json``deploy/gitops/g14/runtime-v02`,确认 runtime service set 只包含 `hwlab-cloud-api``hwlab-cloud-web``hwlab-gateway``hwlab-edge-proxy``hwlab-agent-skills`
阅读 docs/reference/spec-v02-services.md,然后用 CLI 手动测试以下内容:列出 `deploy/deploy.yaml``deploy/deploy.schema.json``deploy/artifact-catalog.dev.json``deploy/gitops/node/runtime-v02`,确认 runtime service set 只包含 `hwlab-cloud-api``hwlab-cloud-web``hwlab-gateway``hwlab-edge-proxy``hwlab-agent-skills`
## T2