agent-skills/gitops-app-onboarding/SKILL.md
2026-03-31 14:02:05 +08:00

410 lines
13 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 目录”“修当前 GitOps 仓库里的 Application / AppProject / release 引用”“补齐当前平台的 Helm chart / release bundle / GitOps 交付链路”,就应优先使用这个 skill如果只是通用 CI、通用 Helm 或通用 GitOps 任务而未指向当前平台,不应触发。
---
# GitOps 项目接入 Skill
这个 skill 是 Baizhi GitOps 平台的接入入口与执行摘要。
执行不应依赖用户重复解释平台规则;按本 skill 与当前仓库约定直接推进即可。
目标是让 agent 能独立完成以下工作:
- 为应用仓库补齐或恢复 `.gitlab-ci.yml`
- 生成或修复 `deploy/helm/<app>/` Chart
- 生成或修复 `deploy/release/` release bundle
- 在需要时补当前 GitOps 仓库中的 `Application`、`AppProject` 与发布结果
## 平台固定常量
除非用户明确要求修改,否则默认使用以下常量:
- GitOps 仓库主机:`deploy.baizhi.cloud`
- OCI Registry 主机:`registry.baizhi.cloud`
- Helm OCI 仓库:`oci://registry.baizhi.cloud/helm`
- GitOps 仓库克隆地址:`https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
- Registry 用户名:`registry-ci`
- 共享镜像拉取 Secret`registry-pull-secret`
- GitOps 控制器Argo CD
- Chart 分发方式OCI Registry
- 源代码托管GitLab
应用仓库 CI 默认依赖以下 GitLab 变量:
- `GITEA_USER`
- `GITEA_TOKEN`
- `REGISTRY_PASSWORD`
通常直接把 `REGISTRY_USER` 写成 `registry-ci`
## 真相来源与读取顺序
开始改代码前,按下面顺序建立上下文:
1. 先读当前 GitOps 仓库 `README.md`
2. 再读目标应用仓库 `README.md`
3. 再读 Dockerfile、包管理文件、构建脚本、现有 deploy 文件
4. 如果用户给了额外设计文档,一并读取
判断规则:
- 目标应用仓库自己的 `README.md` 是应用运行架构的真相来源
- 当前 GitOps 仓库 `README.md` 说明平台目录职责和安装入口
- 本 skill 定义平台接入流程、约束和执行重点
- 如果应用 README 与平台约定冲突,优先识别是“应用设计差异”还是“平台硬约束”
- 如果冲突会直接改变最终实现且无法安全推断,再问用户;否则优先按已有代码和文档做最小偏差实现
在生成任何文件前,先推断出:
- 组件列表
- 每个组件的构建上下文
- 容器入口
- 对外暴露模型
- 运行时配置结构
- 哪些依赖属于平台共享,哪些是应用私有
不要假设每个项目都长得和现有项目一样。
## 先判断修改范围
先区分任务属于哪一种:
1. 只修应用仓库:仅修改应用仓库中的 CI、Chart、release 模板
2. 首次接入当前 GitOps 仓库:除应用仓库外,还要补当前 GitOps 仓库中的发布文件
3. 只修当前 GitOps 仓库:仅改 GitOps 侧引用与发布结果
如果用户只要求修应用仓库,不要擅自修改当前 GitOps 仓库。
## 交付模型
平台采用两个仓库协同交付:
- 应用仓库负责源码、Docker 构建、`.gitlab-ci.yml`、Helm Chart 源码、release bundle 模板
- 当前 GitOps 仓库负责 Argo CD `Application`、`AppProject`、平台 bootstrap、已发布 release bundle、共享配置
标准发布流程:
1. 分支或 MR 只跑测试
2.`vX.Y.Z` tag 后构建并推送镜像
3.`vX.Y.Z` tag 后打包并推送 Helm Chart
4.`vX.Y.Z` tag 后更新当前 GitOps 仓库中该应用的版本引用
5. 推送当前 GitOps 仓库提交
6. Argo CD 感知当前 GitOps 仓库变更后自动同步
关键约束:
- CI 不能直接调用 `kubectl`
- CI 不能调用 `argocd app sync`
- CI 不能把 hard refresh 当常规步骤
- 当前 GitOps 仓库的提交才是 Argo 的同步信号
如果线上故障需要 hard refresh那是运维例外不属于通用模板。
## 应用仓库通常需要生成什么
通常需要创建或修复:
- `.gitlab-ci.yml`
- `deploy/helm/<app-name>/Chart.yaml`
- `deploy/helm/<app-name>/values.yaml`
- `deploy/helm/<app-name>/templates/*`
- `deploy/release/metadata.yaml`
- `deploy/release/values.yaml`
- `deploy/release/secret.yaml`
如果应用还有不适合放进 Chart 的静态清单,可以在后续发布结果中导出到当前 GitOps 仓库的 `releases/<app>/manifests/`
## 当前 GitOps 仓库通常需要生成什么
只有在“首次接入当前 GitOps 仓库”或用户明确要求时,才生成或修复:
- `apps/<app-name>/application.yaml`
- `bootstrap/projects/<app-name>-project.yaml`
- `releases/<app-name>/metadata.yaml`
- `releases/<app-name>/values.yaml`
- `releases/<app-name>/manifests/secret.yaml`
- `releases/<app-name>/manifests/kustomization.yaml`
- 其他确有必要的静态发布清单
如需建新应用骨架,优先执行或仿照 `scripts/new-app.sh`,不要脱离现有目录结构重新发明。
当前 GitOps 仓库保存的是 Argo 可消费的发布结果,不保存应用 Chart 模板源码。
## GitLab CI 规则
### stages
使用这三个 stage
- `test`
- `build`
- `release`
### test job
test job 应运行在分支和 MR 上,并执行目标项目自己的标准测试命令。
要求:
- 安装该语言栈所需的最小依赖
- 如果依赖私有代码仓库,补齐认证
- 使用项目本身的标准测试入口,不要擅自发明新的测试命令
示例:
- Go`go mod download`、`go test ./...`
- Node`npm ci`、`npm test`
### release 触发条件
发布链路只应在 `vX.Y.Z` 这种语义化 tag 上触发。
### build-images job
这个 job 必须:
- 登录 `registry.baizhi.cloud`
- 构建项目所有需要发布的运行时镜像
- 将镜像推送到 `registry.baizhi.cloud/<app-name>/<component>:<version>`
如果仓库已经使用 BuildKit 或多构建上下文,优先使用 `docker buildx`
如果镜像构建依赖私有 Git 仓库:
- 用 CI 凭据生成 `.netrc`
- 通过 Docker build secret 传入
- 如需额外 CA 证书,也通过 build secret 传入
- 不要通过全局关闭 TLS 校验规避问题
不要使用:
- `http://registry...`
- `--plain-http`
- `--insecure-skip-tls-verify`
### package-chart job
这个 job 必须:
- 执行 `helm registry login registry.baizhi.cloud`
- 将 Chart 的 `version``appVersion` 更新为 tag 去掉前缀 `v` 后的版本号
- 执行 `helm package`
- 推送到 `oci://registry.baizhi.cloud/helm`
### update-gitops-repo job
这个 job 必须:
- 克隆 `https://${GITEA_USER}:${GITEA_TOKEN}@deploy.baizhi.cloud/gitops-admin/argodeploy.git`
- 只更新目标应用在当前 GitOps 仓库中的版本引用
- 提交并推送到 `main`
通常需要更新:
- `apps/<app-name>/application.yaml`
- `releases/<app-name>/values.yaml`
- `releases/<app-name>/metadata.yaml`
不要在这个 job 中加入集群部署逻辑。
## Helm Chart 规则
Chart 必须反映应用的真实运行架构。
推荐结构:
```text
deploy/helm/<app-name>/
├── Chart.yaml
├── values.yaml
└── templates/
├── _helpers.tpl
├── deployment-<component>.yaml
├── service-<component>.yaml 或 services.yaml
└── 按职责拆分的其他资源
```
规则:
- 按职责拆文件,不要堆成一个巨大模板
- 模板中不要硬编码生产镜像 tag
- 所有镜像名都从 values 读取
- 所有 Service 暴露方式都从 values 读取
- 设置 `enableServiceLinks: false`
- 支持 `imagePullSecrets`
- 环境变量注入保持可读
- 健康检查要符合真实应用行为
`_helpers.tpl` 一般至少提供:
- chart name
- fullname
- namespace
- labels
- selector labels
只有当项目本身确实有 path 推导的 URL 时,才增加 URL helper。
## 对外暴露模型
必须根据目标应用的 README、现有代码和当前网络结构推断。
例如:
- 如果项目是一个 frontend 对外,再由 frontend 反代内部 API 路径,就保持这个模型
- 如果项目明确使用 Ingress才生成 Ingress
- 如果项目明确已经移除 Ingress就不要重新引入
不要因为应用有多个内部服务,就擅自发明多个公网 host。
## Release Bundle 规则
应用仓库中的 `deploy/release/` 是导出给当前 GitOps 仓库的标准模板。
### `metadata.yaml`
至少应包含:
- 应用名
- Kubernetes release 名
- namespace
- chart 名
- chart 版本
- chart 仓库
- 镜像 tag
- 源码仓库地址
### `values.yaml`
必须是可用于部署的默认值,而不是示例值。
至少应满足:
- 镜像地址指向 `registry.baizhi.cloud/<app-name>/...`
- Secret 名符合平台约定
- 私有镜像拉取时包含 `imagePullSecrets`
- 与 Chart schema 保持一致
### `secret.yaml`
用于放应用私有 Secret 模板key 名必须与 Chart 读取的 key 对齐。
规则:
- 不要为了“看起来完整”而伪造假的生产值
- 如果这些值是接入该应用所必需的,应在完成所有非阻塞工作后向用户索取
- 如果用户暂时没有提供,不要造占位内容冒充可部署配置
- 可以只保留结构,或暂不生成具体 secret 内容,但必须在最终输出中明确警告缺失项与影响
## 平台共享配置契约
`shared/` 目录只放平台级共享配置。
共享资源:
- `platform-runtime-config`
- `platform-shared-secrets`
- `registry-pull-secret`
当前 `platform-runtime-config` 提供:
- `LLM_BASE_URL`
- `EMBEDDER_BASE_URL`
当前 `platform-shared-secrets` 提供:
- `POSTGRES_USER`
- `POSTGRES_PASSWORD`
- `REDIS_PASSWORD`
- `QDRANT_API_KEY`
- `NEO4J_USERNAME`
- `NEO4J_PASSWORD`
- `MINIO_ACCESS_KEY`
- `MINIO_SECRET_KEY`
shared 边界:
- shared 只负责共享基础设施和通用运行时地址
- 不要把某个厂商的客户端证书、私钥、应用专属 `app_id`、tenant id、client id、namespace id、应用独有 webhook 签名密钥放进 `shared/`
- 镜像拉取默认使用 `registry-pull-secret`,不要随便为每个应用再造一个 pull secret除非平台模型发生变化
## 可选的应用私有接入
有些应用支持可选的第三方鉴权、mTLS 或厂商专有接入。
处理规则:
- 不要把它们当成平台共享配置
- 不要擅自生成生产值
- 先完成所有非阻塞工作
- 如果 README 没明确说明是否启用,最后只问用户一个最小必要问题
- 如果需要,再向用户索取必要值,例如 `app_id`、`app.crt`、`app.key`、`ca.crt`、`public.key`
- 如果不需要,就跳过这部分 release values 和 secret 生成
- 如果用户需要但没有提供完整值,不要写伪造占位内容;在最终输出中明确警告缺失了哪些字段以及可能影响
提问方式要求:
- 只在真正阻塞最终可部署结果时才问
- 先做完不依赖这些值的工作
- 问题必须尽量小而具体,避免连续追问多个开放问题
## 执行流程
建议按下面顺序推进:
1. 读取应用 README 与构建文件,梳理组件和暴露模型
2. 判断任务范围是应用仓库、当前 GitOps 仓库,还是两者都要改
3. 生成或修复 `.gitlab-ci.yml`
4. 生成或修复 Chart 与 values
5. 生成或修复 release bundle
6. 如任务需要,再补当前 GitOps 仓库中的 `Application` 与发布结果
7. 完成非阻塞工作后,再处理可选私有接入提问
8. 自检并在最终输出中说明风险点
## 自检要求
完成后尽量执行:
- `git status --short`
- `git diff --check`
- `helm template`,前提是 Chart 与 values 已能渲染
至少确认:
- 应用仓库不再缺少接入文件
- `.gitlab-ci.yml` 包含 test、镜像构建、chart 发布、GitOps 仓库更新逻辑
- release values 指向 `registry.baizhi.cloud`
- GitOps 仓库更新 job 指向 `https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
- CI 中没有直接调用 Argo
- 没有继续使用旧域名
- 没有继续使用不安全的 HTTP registry 访问方式
- 如果存在用户未提供的必填私有配置,最终输出中已明确列出缺失项和潜在影响
## 最终输出要求
默认按下面结构汇报:
1. 修改了哪些文件
2. 关键设计决策
3. 最值得人工复核的 3 个点
如果存在用户未提供的必填私有配置,额外增加“缺失项警告”,明确列出:
- 缺少哪些字段
- 因此哪些配置尚未完成
- 不补齐会影响什么例如无法直接部署、某功能未启用、secret 仍为空
## 常见错误
以下都属于接入错误:
- 把应用私有鉴权材料放进 `shared/`
- 在 CI 里直接刷新 Argo
- 重新引入已废弃的旧域名
- 在 HTTPS 已恢复后仍使用 insecure registry 参数
- 生成的 Chart 与应用真实组件不匹配
- 在生产 release values 中写 `registry.example.com` 这类示例地址
- 应用没有这个设计却擅自发明新的公网 host
- 在用户没有提供必填私有值时,仍然伪造占位内容并假装可以直接部署