232 lines
17 KiB
Markdown
232 lines
17 KiB
Markdown
# v0.2 CI/CD 规格
|
||
|
||
本文是 HWLAB `v0.2` 在 G14 上接入 CI/CD 的长期规格。目标是把 `v0.2` 作为独立加法 lane 接入现有 G14 k3s、Tekton、GitOps 和 Argo CD 体系,同时保持 `G14` DEV/PROD 发布面稳定。
|
||
|
||
实施跟踪见 [pikasTech/HWLAB#530](https://github.com/pikasTech/HWLAB/issues/530),阶段计划见 [../plan/hwlab-v02-namespace-cicd.md](../plan/hwlab-v02-namespace-cicd.md)。本文只记录稳定规格、边界和判定标准;不要把一次性执行记录、排障流水账或临时证据写入本文。
|
||
|
||
## 在系统中的职责划分
|
||
|
||
`v0.2` CI/CD 是 G14 上的加法 lane:source branch、GitOps branch、runtime namespace、artifact catalog、Argo Application、Tekton Pipeline 和 FRP 入口均独立于 DEV/PROD。它共享 G14 k3s、Tekton controller、Argo CD controller、本地 registry 和构建工具,但不能复用 DEV/PROD runtime path、namespace、Application 或公网端口作为 v02 发布证据。
|
||
|
||
## 内部架构
|
||
|
||
CI/CD 内部由 branch poller、PipelineRun、component planner、BuildKit publish、GitOps promotion、Argo sync 和公网验收构成。source branch 只保存源码和人写配置;`v0.2-gitops` branch 保存 catalog 和 rendered runtime desired state;live runtime 是最终通过证据。
|
||
|
||
## API 接口说明
|
||
|
||
| 接口 | 说明 |
|
||
| --- | --- |
|
||
| `scripts/g14-gitops-render.mjs --lane v02` | v02 GitOps render 入口,负责 namespace、runtime path、catalog 和 endpoint 固定。 |
|
||
| Tekton `hwlab-v02-ci-image-publish` | 构建 affected images、复用 unchanged digest,并 promotion 到 `v0.2-gitops`。 |
|
||
| Argo `argocd/hwlab-g14-v02` | 从 `v0.2-gitops:deploy/gitops/g14/runtime-v02` 同步到 `hwlab-v02`。 |
|
||
| `http://74.48.78.17:19666/` | v02 Cloud Web 公网入口。 |
|
||
| `http://74.48.78.17:19667/health/live` | v02 API/live 公网验收入口。 |
|
||
|
||
## 规格目标
|
||
|
||
- `v0.2` 固定作为 G14 上的新增 CI/CD lane,不改写现有 `G14` DEV/PROD lane。
|
||
- `v0.2` source branch 只保存源码、人写配置、模板、脚本和文档;CI/CD 生成物只进入 `v0.2-gitops`。
|
||
- `hwlab-v02` 是唯一 runtime namespace;`74.48.78.17:19666/19667` 是唯一公网验收入口。
|
||
- 共享 G14 k3s、Tekton controller、Argo CD controller、本地 registry、工具镜像和脚本库;隔离分支、catalog、runtime path、Application、Pipeline、CronJob、ServiceAccount、SecretRef、PVC 和 FRP 入口。
|
||
- 旧 DEV/D601/main 门禁不得进入 `v0.2` 发布调用链;新增检查只覆盖固定 branch、namespace、catalog、runtime path、GitOps branch、Argo destination 和公网入口这些硬边界。
|
||
|
||
## 固定命名
|
||
|
||
| 对象 | v0.2 规格 |
|
||
| --- | --- |
|
||
| Source branch | `v0.2` |
|
||
| Source workspace | `G14:/root/hwlab-v02` |
|
||
| 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 namespace | `hwlab-v02` |
|
||
| Tekton Pipeline | `hwlab-ci/hwlab-v02-ci-image-publish` |
|
||
| Branch poller | `hwlab-ci/hwlab-v02-branch-poller` |
|
||
| Control-plane reconciler | `hwlab-ci/hwlab-v02-control-plane-reconciler` |
|
||
| 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` |
|
||
| 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` |
|
||
|
||
`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。
|
||
|
||
## 真相源
|
||
|
||
`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。
|
||
3. GitOps branch:`v0.2-gitops` 中的 `deploy/artifact-catalog.v02.json` 与 `deploy/gitops/g14/runtime-v02/**`。
|
||
4. Tekton 执行证据:`hwlab-v02-branch-poller`、PipelineRun、TaskRun result、`gitops-promote` 终态。
|
||
5. 干净 source workspace:`origin/v0.2`、`deploy/deploy.json`、模板、render 脚本和 `--no-write` 输出。
|
||
|
||
旧 commit 记忆、`G14`/`G14-gitops` DEV/PROD 产物、D601 legacy 路径、source branch 中历史 generated 文件和临时 worktree 只能作为线索,不能作为 `v0.2` 发布通过证据。
|
||
|
||
## Source 与 GitOps 分层
|
||
|
||
`v0.2` source branch 可以包含:
|
||
|
||
- 源码、测试、文档和人写计划。
|
||
- `deploy/deploy.json` 或等价 lane 配置。
|
||
- k8s 模板、render 脚本、CI/CD helper 和 catalog schema。
|
||
|
||
`v0.2` source branch 不得跟踪:
|
||
|
||
- `deploy/artifact-catalog.v02.json`。
|
||
- `deploy/gitops/g14/runtime-v02/**`。
|
||
- Tekton/Argo 的 rendered runtime desired state。
|
||
- image digest、publish state、reuse evidence 或 CI 生成的 rollout metadata。
|
||
|
||
`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。
|
||
- 必要的 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 生成物。
|
||
|
||
## CI/CD 链路
|
||
|
||
标准链路如下:
|
||
|
||
1. `hwlab-v02-branch-poller` 轮询 `origin/v0.2`,按 source commit 创建 `hwlab-v02-ci-poll-<short12>` PipelineRun。
|
||
2. `prepare-source` checkout `v0.2` source,并从 `v0.2-gitops` 读取上一版 `deploy/artifact-catalog.v02.json`。
|
||
3. 原语校验 task 只覆盖 repo 报告护栏、GitOps render 合同和必要的代码语法/单元检查;旧 DEV/D601/main gate 不进入 lane。
|
||
4. planner 根据 component input 判断 affected/reused services。
|
||
5. affected service 通过 BuildKit 发布到 G14 本地 registry;reused service 复用 catalog digest。
|
||
6. promotion 刷新 `deploy/artifact-catalog.v02.json`,render `deploy/gitops/g14/runtime-v02/**`,只推送到 `v0.2-gitops`。
|
||
7. `hwlab-g14-v02` 从 `v0.2-gitops:deploy/gitops/g14/runtime-v02` 同步到 `hwlab-v02`。
|
||
8. 验收只观察 `hwlab-v02` runtime 和 `19666/19667`。
|
||
|
||
`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` 发布入口。
|
||
|
||
## Artifact 与镜像身份
|
||
|
||
- `v0.2` 镜像 tag 使用完整 40 位 source commitId。
|
||
- runtime manifest 必须使用 digest pin 作为部署身份。
|
||
- catalog 必须记录 lane/profile、source branch、GitOps branch、source commitId、serviceId、image tag、digest、component identity 和 publish/reuse 状态。
|
||
- 同一 source commit 对同一 service 应生成同一镜像;lane 差异放在 manifest、env、SecretRef、namespace、FRP 和 DB 配置中,不 bake 进镜像。
|
||
- `deploy/deploy.json` 只承载人写 runtime intent,不承载 digest、publish state 或 reuse evidence。
|
||
|
||
## Kubernetes 与 Argo 边界
|
||
|
||
- `hwlab-v02` namespace 只能由 `v0.2` GitOps lane 管理。
|
||
- `argocd/hwlab-v02` AppProject destination 只能包含 `hwlab-v02`。
|
||
- `argocd/hwlab-g14-v02` source 必须指向 `v0.2-gitops:deploy/gitops/g14/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`。
|
||
|
||
## 硬边界
|
||
|
||
以下边界是 `v0.2` CI/CD 的最小硬约束:
|
||
|
||
- source branch 必须是 `v0.2`。
|
||
- 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/**` 变更。
|
||
- GitOps promotion 的 changed paths 只能落在 `deploy/artifact-catalog.v02.json` 与 `deploy/gitops/g14/runtime-v02/**` 及必要的 v02 Argo/GitOps 元数据。
|
||
- 公网验收只能使用 `19666/19667`。
|
||
- 旧 DEV/D601/main gate、fallback、legacy mode 和双路径兼容不得进入 `v0.2` 调用链。
|
||
|
||
这些硬边界优先在自然写入点做最小内联断言:render 断言 namespace/runtime path,promotion 断言 GitOps branch/changed paths,Argo spec 断言 destination,验收断言端口和 runtime identity。不要为每条设计约定再新增独立 preflight、guard、gate 或报告生成器。
|
||
|
||
## G14 DEV/PROD 不变边界
|
||
|
||
接入 `v0.2` 不得改变以下对象:
|
||
|
||
- `G14` source branch 的 poller 语义。
|
||
- `G14-gitops` DEV/PROD catalog 与 runtime desired state。
|
||
- `hwlab-dev` 与 `hwlab-prod` namespace。
|
||
- `hwlab-g14-dev` 与 `hwlab-g14-prod` Argo Application。
|
||
- DEV `17666/17667` 与 PROD `18666/18667` FRP 入口。
|
||
- D601 legacy 回溯路径和旧运行面边界。
|
||
|
||
如果 `v0.2` 接入失败,回滚或暂停只能作用于 `hwlab-v02` lane:停止 `hwlab-v02-branch-poller`、暂停或删除 `hwlab-g14-v02`、回滚 `v0.2-gitops` runtime path、关闭 `hwlab-v02-frpc` 或清理 `hwlab-v02` namespace 资源;不得重启、删除或回滚 DEV/PROD 运行面。
|
||
|
||
## 验收标准
|
||
|
||
`v0.2` CI/CD 通过必须同时满足:
|
||
|
||
- `hwlab-ci` 中存在 `hwlab-v02-ci-image-publish`、`hwlab-v02-branch-poller`、`hwlab-v02-control-plane-reconciler` 和 `hwlab-v02-tekton-runner`。
|
||
- 最新 `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` 指向 `v0.2-gitops:deploy/gitops/g14/runtime-v02`,sync revision 与目标 GitOps revision 对齐。
|
||
- `hwlab-v02` 中长驻 workload ready,没有把 DEV/PROD namespace 当成 `v0.2` 通过证据。
|
||
- `http://74.48.78.17:19666/` 返回 `v0.2` Cloud Web。
|
||
- `http://74.48.78.17:19667/health/live` 返回 `v0.2` runtime health,payload 中的 namespace、revision 或 runtime identity 能与 `hwlab-v02`/`v0.2` 对齐。
|
||
|
||
GitOps branch 已更新、source branch render 通过、PipelineRun 名称存在或 `G14` DEV/PROD health 正常,都不能单独代表 `v0.2` CI/CD 通过。
|
||
|
||
## 测试规格
|
||
|
||
## 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/**` 生成物。
|
||
|
||
## T2
|
||
|
||
阅读 docs/reference/spec-v02-cicd.md,然后用 cli 手动测试以下内容:查询 Argo `hwlab-g14-v02`,确认 source branch/path 为 `v0.2-gitops:deploy/gitops/g14/runtime-v02`,destination namespace 为 `hwlab-v02`,sync revision 与目标 GitOps revision 对齐。
|
||
|
||
## T3
|
||
|
||
阅读 docs/reference/spec-v02-cicd.md,然后用 cli 手动测试以下内容:访问 `http://74.48.78.17:19666/` 和 `http://74.48.78.17:19667/health/live`,确认公网入口、payload environment、revision 和 runtime identity 都指向 v02,不把 DEV/PROD health 当作 v02 证据。
|
||
|
||
## T4
|
||
|
||
阅读 docs/reference/spec-v02-cicd.md,然后用 cli 手动测试以下内容:涉及 Code Agent 时使用短连接 submit/result/trace 轮询,确认 `status=completed` 且 assistant reply 非空;不得只用 `/health/live` 中 `codeAgent=ready` 证明 provider 鉴权通过。
|
||
|
||
## 规格的实现情况
|
||
|
||
| 规格项 | 状态 | 说明 |
|
||
| --- | --- | --- |
|
||
| v02 独立 source/GitOps/runtime lane | 已实现 | `v0.2`、`v0.2-gitops`、`hwlab-v02` 和 `runtime-v02` 已固定。 |
|
||
| Tekton poller/pipeline/promotion | 已实现 | 通过 `hwlab-v02-*` 对象和 GitOps promotion 管理。 |
|
||
| Argo v02 Application | 已实现 | `hwlab-g14-v02` 指向 v02 GitOps path 和 namespace。 |
|
||
| FRP `19666/19667` 入口 | 已实现 | 由 `hwlab-v02-frpc` 与 master frps allowlist 共同提供。 |
|
||
| SecretRef 独立与 provider 验收 | 已实现/持续约束 | SecretRef 已独立;验收必须做真实短连接聊天。 |
|
||
| 自动 registry GC | 未实现 | 初期不启用自动 GC,后续需 lane/profile 保护集。 |
|
||
|
||
## 平行 lane 运维边界
|
||
|
||
后续新增 `v0.x` 或其他平行 runtime lane 时,优先复用本节的判定顺序和排障边界,避免把一次性补丁沉淀成新的宽泛门禁。本节只保留可复用的运维边界;具体执行记录、排障流水和一次性证据应放在 issue、PR 或 `docs/plan/` 中。
|
||
|
||
### Secret 导入与重启边界
|
||
|
||
平行 lane 的 Secret 必须独立命名,不能在 runtime 里直接引用 DEV Secret。允许把 DEV 当前值一次性导入到目标 lane 的独立 Secret 名,但验证只能输出 Secret 对象、key、字节数和哈希指纹,不能打印 Secret value、token 片段、完整 DB URL 或 `auth.json` 内容。
|
||
|
||
`v0.2` 至少需要独立维护以下 SecretRef:
|
||
|
||
- `hwlab-v02-postgres/POSTGRES_PASSWORD`。
|
||
- `hwlab-cloud-api-v02-db/database-url`。
|
||
- `hwlab-v02-code-agent-provider/openai-api-key`。
|
||
- `hwlab-v02-code-agent-codex-auth/auth.json`。
|
||
|
||
Code Agent 的 Secret 修复不是只改一个 Secret 对象就结束。`hwlab-cloud-api` 通过 env 读取 `OPENAI_API_KEY`,Secret 更新后必须滚动 `hwlab-v02/hwlab-cloud-api`。DeepSeek profile 还通过 `hwlab-deepseek-proxy` 的 initContainer 把 `DEEPSEEK_API_KEY` 渲染进 Moon Bridge 配置,Secret 更新后也必须滚动 `hwlab-v02/hwlab-deepseek-proxy`,否则 proxy 仍会使用旧配置并返回上游鉴权失败。
|
||
|
||
### Code Agent 验收
|
||
|
||
`/health/live` 中 `codeAgent=ready`、`codexStdio=ready` 只能证明运行时结构、二进制、workspace、token boundary 和会话 supervisor 就绪;它不证明真实 provider 鉴权可用。涉及 Code Agent 的扩容验收必须追加一次真实短连接聊天闭环:用 `Prefer: respond-async` 和 `X-HWLAB-Short-Connection: 1` 提交 `/v1/agent/chat`,再轮询 `/v1/agent/chat/result/<traceId>`,只有 `status=completed` 且 assistant reply 非空才算通过。
|
||
|
||
如果 trace 里出现 `Authentication Fails`、`upstream stream error` 或 `codex_stdio_provider_retry`,先按 profile 分层判断:`deepseek` profile 走 `hwlab-deepseek-proxy.<namespace>.svc.cluster.local:4000/v1/responses` 和 Moon Bridge;`codex-api` profile 走 Pod-local loopback forwarder。不要用 `codex-api` readiness 掩盖 DeepSeek 专用凭证或 Moon Bridge 配置问题。
|
||
|
||
长耗时 smoke 不应通过 UniDesk SSH 长连接等待完整 Codex turn。Codex 首 token 可能超过短查询窗口,验证应使用短连接 submit/result/trace 轮询,避免把控制通道超时误判成 provider 失败。
|
||
|
||
### GitOps 与 runtime 收敛
|
||
|
||
GitOps promotion 成功不等于 runtime 已经运行新版本。验收必须等待 `argocd/hwlab-g14-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`。
|
||
|
||
### 后续扩容建议
|
||
|
||
下一条平行 lane 建议先列一张最小资源映射表,再落地 CI/CD:source branch、GitOps branch、runtime namespace、runtime path、Argo Application、FRP ports、artifact catalog、Postgres Secret、Cloud API DB Secret、Code Agent provider Secret、Codex auth Secret、DeepSeek proxy restart 对象和公网验收 URL。映射表是执行清单,不是新 gate;只有 branch、namespace、runtime path、GitOps branch、Argo destination、SecretRef 名称和公网端口这些硬边界需要内联断言。
|
||
|
||
Secret、FRP 和 Argo 问题都应先在目标运行面做最小真实闭环,再进入完整 CI/CD 复跑。不要用完整 PipelineRun 反复探索 Secret 值、FRP allowlist 或 provider 鉴权;CI/CD 只负责固化已经在目标 namespace 证明可行的配置和源码。
|