agent-skills/gitops-app-onboarding/SKILL.md
2026-05-09 19:37:10 +08:00

547 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: gitops-app-onboarding
description: 面向当前 Baizhi GitOps 平台的项目接入工作流,只适用于 `deploy.baizhi.cloud`、`registry.baizhi.cloud`、GitLab + Argo CD 这套固定交付模型。只要用户提到“给当前平台接入新项目”“恢复 .gitlab-ci.yml / deploy 目录”“补齐当前平台的 Helm chart / release bundle”“修当前平台的发版链路”“让应用仓库在发版时推送自己的 release 结果”,就应优先使用这个 skill如果只是通用 CI、通用 Helm 或通用 GitOps 任务而未指向当前平台,不应触发。
---
# GitOps 项目接入 Skill
## 目标
让 agent 能独立完成下面四件事:
- 生成或修复 `.gitlab-ci.yml`
- 生成或修复 `deploy/helm/<app>/`
- 生成或修复 `deploy/release/`
- 让发版链路把当前应用的发布结果同步到固定 GitOps 仓库
## 平台固定常量
除非用户明确要求修改,否则固定使用:
- GitOps 主机:`deploy.baizhi.cloud`
- Registry 主机:`registry.baizhi.cloud`
- Helm OCI 仓库:`oci://registry.baizhi.cloud/helm`
- GitOps 仓库地址:`https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
- Registry 用户名:`registry-ci`
- 共享 pull secret`registry-pull-secret`
- GitOps 控制器Argo CD
- 代码托管GitLab
GitLab CI 默认依赖这些变量:
- `GITEA_USER`
- `GITEA_TOKEN`
- `REGISTRY_PASSWORD`
## 开始前先做什么
先按这个顺序读仓库:
1. `README.md`
2. Dockerfile、包管理文件、构建脚本、已有 deploy 文件
3. 用户提供的额外设计文档
在动手前先确定:
- 组件列表
- 每个组件的构建上下文与入口
- 对外暴露方式
- 运行时配置结构
- 平台共享依赖与应用私有依赖
- 是否检测到私有 Git 依赖(例如 `git.in.chaitin.net/ai/baizhiyun/opensdk`
应用仓库自己的 `README.md` 是应用运行架构的真相来源;本 skill 只定义平台接入规则。
## 边界
- 只处理应用仓库侧接入
- 不修改与当前应用无关的 GitOps 清单
- 对 GitOps 的唯一动作,是在应用仓库 CI 中同步当前应用自己的 release 结果与版本引用
- 如果当前应用的 `Application` 已存在,只允许更新 `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`
- 不修改 `AppProject`、bootstrap、其他应用的 `Application`
## 应用仓库必须产出哪些文件
### CI
- `.gitlab-ci.yml`
### Chart
- `deploy/helm/<app>/Chart.yaml`
- `deploy/helm/<app>/values.yaml`
- `deploy/helm/<app>/templates/*`
### release 作者源
- `deploy/release/metadata.yaml`
- `deploy/release/values.yaml`
- `deploy/release/secret.yaml`
## GitOps 仓库里最终应该有哪些文件
CI 导出结果固定为:
- `deploy/release/metadata.yaml` -> `releases/<app>/metadata.yaml`
- `deploy/release/values.yaml` -> `releases/<app>/values.yaml`
- `deploy/release/secret.yaml` -> `releases/<app>/manifests/secret.yaml`
- `apps/<app>/application.yaml` -> 只更新 chart source 的 `targetRevision`
固定规则:
- 不导出 `releases/<app>/secret.yaml`
- 不生成或覆盖 `db-secret.yaml``kustomization.yaml` 这类 GitOps 仓库里已有的文件
## GitLab CI 规则
### 私有 Git 依赖判定口径
下文中的“检测到私有 Git 依赖”统一指:仓库在 `go.mod`、`go.sum`、源码 import、构建脚本或 Dockerfile 构建流程中,实际引用了需要认证访问的私有 Git 仓库(例如 `git.in.chaitin.net/ai/baizhiyun/opensdk`)。
只有在检测到这类依赖时,才启用 `.netrc`、私有仓库认证,以及 `GOPRIVATE`、`GONOSUMDB`、`GONOPROXY`、`GOINSECURE`、`GIT_SSL_NO_VERIFY` 这一组私有 Go 变量;否则不要添加这些配置。
### stages
固定使用:
- `test`
- `build`
- `release`
### runner tags
只要 job 使用 Docker、DinD 或 `docker buildx`,就必须带:
- `docker`
- `network`
### test job
用途:只做测试,不改 GitOps不推镜像。
要求:
- 运行在分支和 MR 上
- 安装当前语言栈的最小依赖
- 只有检测到私有 Git 依赖时才补齐认证;否则不要引入 `.netrc`
- 使用项目原生测试入口
Go 项目默认变量写在 `.gitlab-ci.yml``variables:`
- `GOPROXY=https://goproxy.cn,direct`
- `GOSUMDB=sum.golang.google.cn`
只有检测到私有 Git 依赖时,才额外设置这些变量:
- `GOPRIVATE=git.in.chaitin.net`
- `GONOSUMDB=git.in.chaitin.net`
- `GONOPROXY=git.in.chaitin.net`
- `GOINSECURE=git.in.chaitin.net`
- `GIT_SSL_NO_VERIFY="true"`
### release 触发条件
只在 `vX.Y.Z` tag 上触发发布链路。
### image build jobs
输入源码、Dockerfile、单组件构建上下文。
输出:分别推送到 `registry.baizhi.cloud/<app>/<component>:<version>` 的运行时镜像。
设计原则:不同服务的镜像必须独立构建,避免一个组件改动或失败拖慢所有组件发布。
要求:
- 不要生成一个串行构建所有镜像的单体 `build-images` job每个需要构建镜像的服务使用独立 job例如 `build-backend-image`、`build-frontend-image`、`build-nginx-image`
- 如果多个组件构建脚本完全一致,可以使用 `parallel:matrix`,但矩阵中的每个组件仍必须是 GitLab 可独立调度、独立失败、独立重试的构建单元
- 每个镜像构建 job 只负责一个组件的 Dockerfile、构建上下文、tag 与 push
- release 链路必须等待所有应用自建镜像构建成功;优先用 `needs:` 精确声明,而不是只依赖 stage 顺序
- 登录 `registry.baizhi.cloud`
- 优先使用 `docker buildx`
- 只有检测到私有 Git 依赖时,才通过 `.netrc` 和 build secret 传入;否则不要生成 `.netrc` 相关步骤
- 如需额外 CA也通过 build secret 传入
- 如果 Dockerfile 中使用 Docker Hub 源作为 `FROM` 基础镜像或其他拉取来源,需改写为 `registry-mirrors.dev.in.chaitin.net` 对应镜像源;不要保留对 Docker Hub 的直接拉取
- 如果 Dockerfile 中使用 `apk`,需要将 apk 软件源切换为中科大源后再安装依赖
- 如果 Dockerfile 内会执行 `go mod download`、`go build` 等 Go 构建命令,必须通过 `--build-arg` 透传 Go 构建变量,不要只写在 `.gitlab-ci.yml``variables:`
- 无论是否检测到私有 Git 依赖,至少透传:`GOPROXY`、`GOSUMDB`
- 只有检测到私有 Git 依赖时,才额外透传:`GOPRIVATE`、`GONOSUMDB`、`GONOPROXY`、`GOINSECURE`
- Dockerfile 中对应变量必须有 `ARG`,并让构建命令实际使用传入值,而不是退回默认值
禁止:
- `http://registry...`
- `--plain-http`
- `--insecure-skip-tls-verify`
- 不要假设 `.gitlab-ci.yml` 中的环境变量会自动进入 `docker build` / `docker buildx build`
### GitLab CI YAML 与脚本合法性
生成或修复 `.gitlab-ci.yml` 时要优先保证 GitLab CI 配置本身可解析、可执行、可维护。
要求:
- 不要在 CI 脚本里用 Python 临时解析或改写 YAML优先使用 `yq`、`helm`、`git`、`install`、`mkdir`、`cp`、`rsync` 这类明确的 CLI
- 修改 `Chart.yaml``version` / `appVersion` 使用 `yq -i`,不要用 Python heredoc 或内联脚本
- 修改 Argo CD `Application``targetRevision` 使用 `yq -i` 定位字段,避免用脆弱的 `sed` 跨行替换
- 对 CI 文件做合法性自检时,至少能用 `yq e '.' .gitlab-ci.yml` 验证 YAML 语法;如果环境有 GitLab CI lint 工具或 API再补充 GitLab 语义校验
- `.gitlab-ci.yml` 中的多行 shell 逻辑保持最小化;复杂到需要编程语言脚本时,优先把脚本提交到仓库中的可审查文件,而不是在 CI YAML 里塞内联程序
禁止:
-`.gitlab-ci.yml` 中嵌入 `python - <<'PY'`、`python -c` 或临时 Python 脚本来改 YAML
- 用字符串替换方式盲改 `application.yaml` 中所有 `targetRevision`
### package-chart job
输入:`deploy/helm/<app>/Chart.yaml`、`deploy/helm/<app>/values.yaml`、`deploy/helm/<app>/templates/*`
输出:推送到 `oci://registry.baizhi.cloud/helm` 的 Chart 包。
要求:
- `helm registry login registry.baizhi.cloud`
- 在临时目录复制 `deploy/helm/<app>/`
-`yq -i` 把复制品中的 `version``appVersion` 改成 tag 版本
- 业务镜像的默认 tag 必须跟随 `appVersion`,不要依赖 release values 覆盖业务镜像 tag
- `helm package`
- `helm push`
- 如果应用包含自建镜像,`package-chart` 必须通过 `needs:` 等待所有镜像构建 job 成功
### update-gitops-repo job
输入:`deploy/release/*`、当前 tag 版本、GitOps 仓库中的 `apps/<app>/application.yaml`
输出:
- `releases/<app>/metadata.yaml`
- `releases/<app>/values.yaml`
- `releases/<app>/manifests/` 下的发布结果
- `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`
依赖关系:
- `update-gitops-repo` 必须显式依赖 `package-chart` 成功,优先写 `needs: ["package-chart"]`
- 不要让 `update-gitops-repo``package-chart` 仅靠同 stage 顺序或隐式执行顺序关联
- 如果 release stage 中还有其他准备 job也必须保证 GitOps 仓库更新发生在 Chart 包成功推送之后
处理顺序固定为:
1. 克隆 `https://${GITEA_USER}:${GITEA_TOKEN}@deploy.baizhi.cloud/gitops-admin/argodeploy.git`
2. 确保 `releases/<app>/``releases/<app>/manifests/` 存在,不要整体清空目录
3. 将应用仓库中的 `deploy/release/metadata.yaml``deploy/release/values.yaml` 复制到 GitOps 仓库的 `releases/<app>/metadata.yaml``releases/<app>/values.yaml`,覆盖已有内容
4. 保留已有的 `releases/<app>/manifests/kustomization.yaml``releases/<app>/manifests/db-secret.yaml`
5.`deploy/release/secret.yaml` 物化为 `releases/<app>/manifests/secret.yaml`
6. 替换 `releases/<app>/metadata.yaml` 中的 `__VERSION__`;只有第三方镜像、非业务版本字段或明确需要的环境配置才允许替换 `releases/<app>/values.yaml` 中的 `__VERSION__`
7.`yq -i` 更新 `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`,只改当前应用的 chart source
8. 只有存在 diff 时才提交并推送 `main`
禁止:
- 在 CI 中调用 `kubectl`
- 在 CI 中调用 `argocd app sync`
- 把 hard refresh 当常规发布步骤
- 在 Chart 包推送成功前更新 GitOps 仓库
## Helm Chart 规则
Chart 必须反映应用的真实运行架构。
固定要求:
- 按职责拆文件,不堆一个大模板
- 模板中不硬编码生产 tag
- 所有镜像名从 values 读取
- 应用自己构建的业务镜像 tag 默认必须来自 `.Chart.AppVersion`values 中的 tag 只能作为显式覆盖项
- Deployment 模板必须使用类似 `{{ default .Chart.AppVersion .Values.<component>.image.tag }}` 的逻辑渲染业务镜像 tag
- `deploy/helm/<app>/values.yaml` 中业务镜像 `tag` 默认写空字符串或不写,不要写生产版本号
- 所有 Service 暴露方式从 values 读取
- nginx 对外 Service 固定使用 `NodePort`
- 后端 Service 只做集群内访问
- 不生成 Ingress 模板,也不保留 Ingress values
- `NodePort` 必须来自用户或平台已分配值,不能猜
- 设置 `enableServiceLinks: false`
- 支持 `imagePullSecrets`
- 如果应用包含需要持久化数据的服务PVC / `volumeClaimTemplates` 必须显式使用 `storageClassName: longhorn`
- 环境变量注入保持可读
- 如果镜像内带 nginx / 反向代理配置upstream service 名必须与 Chart 渲染出的 Service 名一致
- 生成 chart 时要确认应用是否包含需要经 nginx 转发的静态文件;如果有,必须明确静态资源目录、挂载方式和 nginx 路由,不要只配后端 upstream
- 不要依赖 Kubernetes 不支持的 `$(OTHER_ENV)` 展开
- 对 Neo4j 这类镜像,不要注入不存在的 `NEO4J_*` 配置名,例如 `NEO4J_PASSWORD`
### Argo CD sync-wave
当 Chart 或 release manifests 中存在资源依赖顺序时,使用 Argo CD sync wave 明确表达顺序,避免依赖文件名、模板渲染顺序或 Kubernetes 最终一致性碰运气。
固定规则:
- annotation 键必须写成 `argocd.argoproj.io/sync-wave`,不要写成 `rgocd.argoproj.io/sync-wave` 或其他拼写
- wave 值使用字符串,例如 `"-20"`、`"0"`、`"10"`
- 低 wave 先同步,高 wave 后同步;不要把依赖方和被依赖方放在同一个 wave
- `releases/<app>/manifests/` 下的资源也必须参与 wave 设计;不要只给 Helm Chart 模板里的资源排序
- 被 Job、Deployment、StatefulSet 或 Pod 通过 `envFrom`、`secretKeyRef`、`configMapKeyRef`、volume、`imagePullSecrets` 消费的 Secret / ConfigMapwave 必须早于消费它们的 workload
- `registry-pull-secret`、`platform-shared-secrets` 等平台托管共享资源的 wave 已固定为 `"-1"`;不要修改它们,应用资源应围绕这个锚点排序
- `manifests/db-secret.yaml` 如果存在,必须早于所有读取 `databaseSecret` / `<app>-db` 的 migrate Job 和业务 workload推荐使用 `"0"`
- 应用私有 Secret、应用私有 ConfigMap 必须早于所有会消费它们的 workload推荐使用 `"0"`
- 只有确实存在跨资源启动顺序要求时才加 sync-wave不要给所有资源机械添加 annotation
推荐顺序:
- `-1`:平台托管共享资源,例如 `registry-pull-secret`、`platform-shared-secrets`、平台共享 ConfigMap
- `0`:应用自有前置资源,例如 ServiceAccount、RBAC、`manifests/db-secret.yaml`、应用私有 Secret、应用私有 ConfigMap、PVC / `volumeClaimTemplates` 所依赖的存储前置资源
- `10`migrate Job、应用自带的私有基础设施例如 Neo4j、向量库、内部依赖服务的 StatefulSet / Deployment
- `15`:内部依赖的 Service尤其是会被后续 nginx upstream 或应用启动配置引用的服务名
- `20`后端、worker、API 等核心业务 Deployment / StatefulSet
- `25`:核心业务 Service
- `30`nginx / frontend 入口 Deployment以及对外 `NodePort` Service
如果 nginx 配置在容器启动时解析 upstream必须保证 upstream 对应 Service 的 wave 早于 nginx Deployment如果应用启动依赖 Secret / ConfigMap / PVC / imagePullSecret必须保证这些资源的 wave 早于消费它们的 workload。尤其注意平台共享资源已经在 `"-1"`,应用自有 secret/config 应从 `"0"` 开始migrate Job 这类消费者必须排在它们之后,例如 `"10"`,不能把消费者放到 `"-10"` 或同一个 wave 里。
生成或修复 release manifests 时,逐项核对:
- `releases/<app>/manifests/db-secret.yaml` 的 wave 早于 Chart 中所有引用该 secret 的 Job / Deployment / StatefulSet
- `releases/<app>/manifests/secret.yaml` 的 wave 早于 Chart 中所有引用该 secret 的 workload
- `registry-pull-secret` 在目标 namespace 存在,且 wave 早于所有使用私有镜像的 workload
- 共享 secret / config 如果由 release manifests 或 shared manifests 同步,也早于所有消费者
如果应用依赖平台 shared 之外的私有服务,必须明确表达依赖来源:
- 要么由 Chart 生成应用自带资源
- 要么明确引用用户提供的外部地址
不能只留一个指向不存在服务的 host。
如果应用自带依赖同时需要业务连接口令和依赖自身启动口令Secret key 要同时表达两种消费方式,例如:
- `neo4j_password`
- `neo4j_auth`
## 对外暴露模型
固定使用:
- nginx 作为统一入口
- 对外只暴露一个 nginx `NodePort`
- 后端服务只在集群内通信
- 不生成 Ingress
`NodePort` 处理规则:
- 用户或文档已提供时直接使用
- 没提供时,在生成到这一项时立即索取
- 不要写示例端口或默认端口
## Release Bundle 规则
### `metadata.yaml`
至少包含:
- 应用名
- release 名
- namespace
- chart 名
- chart 版本
- chart 仓库
- 镜像 tag
- 源码仓库地址
### `values.yaml`
必须是可部署默认值,不是示例值。
至少满足:
- 应用自建镜像使用 `registry.baizhi.cloud/<app>/...`
- 应用自建镜像不要在 release values 中写业务版本 tag业务镜像 tag 默认由 Chart `appVersion` 决定,以便 Argo CD UI 回滚 Chart 版本时镜像版本同步回滚
- 第三方镜像保持真实来源
- 第三方镜像 tag 必须继续显式写在 values 中,不要跟随 Chart `appVersion`
- Secret 名与 Chart 约定一致
- PostgreSQL 连接读取应用自己的 `databaseSecret`
- 私有镜像包含 `imagePullSecrets`
- 与 Chart schema 一致
- 不要包含 `backend.image.tag`、`server.image.tag`、`frontend.image.tag`、`nginx.image.tag` 等应用自建业务镜像版本覆盖,除非用户明确要求做一次性特殊覆盖
- nginx 对外入口使用 `NodePort`
- `NodePort` 值来自用户或平台分配结果
- 不包含 Ingress 配置项
### `manifests/db-secret.yaml`
这是 deploy 仓库注册应用阶段生成的数据库源secret 名称格式为 `<app>-db` 不是应用仓库侧要生成的文件。至少包含:
- `host`
- `port`
- `database`
- `username`
- `password`
固定规则:
- chart 如果依赖 Postgres 则必须消费这个 secret
### `secret.yaml`
只放应用私有 Secretkey 名必须与 Chart 读取的 key 对齐。
规则:
- 不伪造生产值
- 外部集成凭据在生成到对应配置时逐项索取
- 应用自带私有依赖的内部口令优先自动生成
- 组合型鉴权字段优先直接写成完整 key 值
- 缺值时停在当前项继续问,不要留看似可部署的假配置
## 平台共享配置契约
`shared/` 只放平台级共享配置。
共享资源:
- `platform-runtime-config`
- `platform-shared-secrets`
- `registry-pull-secret`
`platform-runtime-config` 提供:
- `LLM_BASE_URL`
- `EMBEDDER_BASE_URL`
- `OSS_BUCKET`
`platform-shared-secrets` 提供:
- `REDIS_PASSWORD`
- `QDRANT_API_KEY`
- `OSS_ACCESS_KEY`
- `OSS_SECRET_KEY`
平台共享基础设施固定为:
- `PostgreSQL`
- `Redis`
- `Qdrant`
- `OSS`
固定 FQDN 与对象存储约定:
- `redis.infra.svc.cluster.local`
- `qdrant.infra.svc.cluster.local`
固定规则:
- 不要写成当前应用 namespace 下的裸服务名
- 不默认为 `Redis`、`Qdrant`、`OSS` 生成应用私有实例
- 如果应用当前使用的是 `MinIO` / S3 兼容配置,优先沿用现有对象存储配置结构接入平台对象存储;但不要默认假设 `MinIO` 客户端可直接连接平台 `OSS`,需根据仓库实际使用的 SDK 与平台提供的协议兼容性确认
- `Neo4j` 不属于 shared如应用需要由应用自己部署
- 不要把应用私有鉴权材料放进 `shared/`
- 如果 Chart 依赖的运行时资源不是由 Chart 直接创建,就必须确保 `releases/<app>/manifests/` 仍会把这些资源 apply 到目标 namespace
## 百智云用户鉴权接入
只有在检测到私有 Git 依赖,且该依赖就是 `git.in.chaitin.net/ai/baizhiyun/opensdk` 时才需要接入。
识别规则:
- 先按上文“私有 Git 依赖判定口径”检查仓库,再确认私有依赖中是否实际包含 `git.in.chaitin.net/ai/baizhiyun/opensdk`
- 只有确认包含这个依赖或导入时,才进入本节并索取百智云相关材料
- 如果仓库里没有这个包,就跳过整段,不要要求接入百智云,也不要生成对应配置
固定规则:
- 不要把鉴权材料放进 `shared/`
- 不要伪造生产值
- 按固定顺序逐项索取:`app_id` -> `app.crt` -> `app.key` -> `ca.crt` -> `public.key`
- 缺少哪一项,就停在那一项继续问
挂载规则:
- 固定挂载目录:`/app/ssl`
- 固定文件路径:`/app/ssl/app.crt`、`/app/ssl/app.key`、`/app/ssl/ca.crt`
- 不要改成其他自定义目录
- `public.key` 如果保留,应明确其用途,不要混同为 mTLS 必需文件
## 提问方式
- 只问当前步骤真正阻塞的值
- 逐项问,不要一次性要一大串
- 对外部集成字段,在写到对应配置时就问
- 对应用自带私有依赖内部口令,优先自动生成
- 如果当前正在等补值,回复重点只放当前这一项
## 执行顺序
按下面顺序推进:
1. 读 README 与构建文件
2. 梳理组件、依赖、暴露模型
3. 生成或修复 `.gitlab-ci.yml`
4. 生成或修复 Chart
5. 缺少必填值时停在当前项索取
6. 生成或修复 `deploy/release/`
7. 自检并汇报风险点
## 自检
完成后尽量执行:
- `git status --short`
- `git diff --check`
- `yq e '.' .gitlab-ci.yml`
- `helm template`(前提是 Chart 与 values 已能渲染)
至少确认:
- 接入文件齐全
- `.gitlab-ci.yml` YAML 语法合法,不包含用于改 YAML 的内联 Python
- `.gitlab-ci.yml` 包含 test、组件级独立镜像构建、Chart 发布、GitOps 同步
- 多服务应用的业务镜像不是由一个串行 `build-images` job 统一构建;每个自建镜像可被 GitLab 独立调度和重试
- `package-chart` 通过 `needs:` 等待所有必要镜像构建成功
- `update-gitops-repo` 通过 `needs:` 依赖 `package-chart` 成功
- release values 指向 `registry.baizhi.cloud`
- release values 不覆盖应用自建业务镜像 tag业务镜像 tag 由 Chart `appVersion` 默认决定
- 第三方镜像没有被错误改写到平台 registry
- 第三方镜像仍显式固定 repository 和 tag且没有错误跟随 Chart `appVersion`
- 如果 Dockerfile 原本使用 Docker Hub 源,已切换到 `registry-mirrors.dev.in.chaitin.net`,且未误改其他非 Docker Hub 镜像源
- 如果 Dockerfile 中使用 `apk`,已切换到中科大源
- GitOps update job 指向 `https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
- GitOps update job 用 `yq` 精确更新当前应用 chart source 的 `targetRevision`
- CI 中没有直接调用 Argo
- 只使用 `deploy.baizhi.cloud``registry.baizhi.cloud`
- 没有使用不安全的 registry 访问方式
- 如果 `Application` 仍引用 `releases/<app>/manifests/`,该 path 在发布结果中实际存在
- 如果镜像内包含固定 upstream 配置upstream service 名与 Chart 渲染结果一致
- Neo4j 一类自带依赖的启动环境变量不依赖 `$(OTHER_ENV)` 展开
- 如果应用包含需要持久化数据的服务,对应 PVC / `volumeClaimTemplates` 已显式设置 `storageClassName: longhorn`
- 如果资源存在启动顺序依赖,`argocd.argoproj.io/sync-wave` 拼写正确wave 顺序符合依赖方向
- `releases/<app>/manifests/db-secret.yaml`、`secret.yaml`、pull secret、shared secret/config 的 wave 早于所有引用它们的 migrate Job 和业务 workload
- `registry-pull-secret`、`platform-shared-secrets` 等平台托管资源保持平台约定的 `"-1"`,应用自有前置资源围绕它排序,不要改平台资源 wave
- migrate Job 不要设置成负 wave它依赖的应用自有 Secret / ConfigMap / DB secret 通常在 `"0"`migrate Job 应排在更高 wave例如 `"10"`
- 如果检测到的私有 Git 依赖中包含 `git.in.chaitin.net/ai/baizhiyun/opensdk`,缺少必填百智云私有配置时交互停在当前项继续索取
## 最终输出
默认按这个顺序汇报:
1. 修改了哪些文件
2. 关键决定
3. 最值得人工复核的点
## 常见错误
- 把应用私有鉴权材料放进 `shared/`
- 在 CI 里直接刷新 Argo
- 重新引入旧域名
- 使用 insecure registry 参数
- Chart 与应用真实组件不匹配
- 在生产 release values 中写示例地址
- 在 release values 中写应用自建业务镜像 tag导致 Argo CD UI rollback 只回滚 Chart 但镜像仍被 `main` 上的 values 固定到新版本
- 擅自发明新的公网 host
- 在未检测到私有 Git 依赖中的 `git.in.chaitin.net/ai/baizhiyun/opensdk` 时仍强行接入百智云
- Dockerfile 明明使用了 Docker Hub / `apk` 默认源,却没有切到 `registry-mirrors.dev.in.chaitin.net` / 中科大源,或误改了原本不在 Docker Hub 的镜像源
- 用户未提供必填值时伪造占位内容
- 多个服务镜像塞进一个串行 build job导致无法并行构建、无法单独重试、失败定位困难
- `update-gitops-repo` 没有依赖 `package-chart`GitOps 仓库先于 Chart 推送被更新
-`.gitlab-ci.yml` 中用 Python heredoc 临时改 `Chart.yaml`、release values 或 `application.yaml`
- `argocd.argoproj.io/sync-wave` 拼错为 `rgocd.argoproj.io/sync-wave`,或把依赖方放在被依赖资源之前
- 只给 Chart 模板资源设计 wave却遗漏 `releases/<app>/manifests/db-secret.yaml`、`secret.yaml`、pull secret 等 release manifests导致 migrate Job 先于 Secret 执行
- 不顾平台约定把 `registry-pull-secret`、`platform-shared-secrets` 等平台托管资源改成其他 wave正确做法是保持它们在 `"-1"`,应用资源围绕 `"-1"` 排序