agent-skills/gitops-app-onboarding/SKILL.md
2026-04-15 18:35:55 +08:00

15 KiB
Raw Blame History

name description
gitops-app-onboarding 面向当前 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 secretregistry-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.yamlkustomization.yaml 这类 GitOps 仓库里已有的文件

GitLab CI 规则

私有 Git 依赖判定口径

下文中的“检测到私有 Git 依赖”统一指:仓库在 go.modgo.sum、源码 import、构建脚本或 Dockerfile 构建流程中,实际引用了需要认证访问的私有 Git 仓库(例如 git.in.chaitin.net/ai/baizhiyun/opensdk)。

只有在检测到这类依赖时,才启用 .netrc、私有仓库认证,以及 GOPRIVATEGONOSUMDBGONOPROXYGOINSECUREGIT_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.ymlvariables:

  • 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 上触发发布链路。

build-images job

输入源码、Dockerfile、多组件构建上下文。

输出:推送到 registry.baizhi.cloud/<app>/<component>:<version> 的运行时镜像。

要求:

  • 登录 registry.baizhi.cloud
  • 优先使用 docker buildx
  • 只有检测到私有 Git 依赖时,才通过 .netrc 和 build secret 传入;否则不要生成 .netrc 相关步骤
  • 如需额外 CA也通过 build secret 传入
  • 如果 Dockerfile 内会执行 go mod downloadgo build 等 Go 构建命令,必须通过 --build-arg 透传 Go 构建变量,不要只写在 .gitlab-ci.ymlvariables:
  • 无论是否检测到私有 Git 依赖,至少透传:GOPROXYGOSUMDB
  • 只有检测到私有 Git 依赖时,才额外透传:GOPRIVATEGONOSUMDBGONOPROXYGOINSECURE
  • Dockerfile 中对应变量必须有 ARG,并让构建命令实际使用传入值,而不是退回默认值

禁止:

  • http://registry...
  • --plain-http
  • --insecure-skip-tls-verify
  • 不要假设 .gitlab-ci.yml 中的环境变量会自动进入 docker build / docker buildx build

package-chart job

输入:deploy/helm/<app>/Chart.yamldeploy/helm/<app>/values.yamldeploy/helm/<app>/templates/*

输出:推送到 oci://registry.baizhi.cloud/helm 的 Chart 包。

要求:

  • helm registry login registry.baizhi.cloud
  • 在临时目录复制 deploy/helm/<app>/
  • 把复制品中的 versionappVersion 改成 tag 版本
  • helm package
  • helm push

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

处理顺序固定为:

  1. 克隆 https://${GITEA_USER}:${GITEA_TOKEN}@deploy.baizhi.cloud/gitops-admin/argodeploy.git
  2. 确保 releases/<app>/releases/<app>/manifests/ 存在,不要整体清空目录
  3. 将应用仓库中的 deploy/release/metadata.yamldeploy/release/values.yaml 复制到 GitOps 仓库的 releases/<app>/metadata.yamlreleases/<app>/values.yaml,覆盖已有内容
  4. 保留已有的 releases/<app>/manifests/kustomization.yamlreleases/<app>/manifests/db-secret.yaml
  5. deploy/release/secret.yaml 物化为 releases/<app>/manifests/secret.yaml
  6. 替换 releases/<app>/metadata.yamlreleases/<app>/values.yaml 中的 __VERSION__
  7. 更新 apps/<app>/application.yaml 中当前应用 chart source 的 targetRevision
  8. 只有存在 diff 时才提交并推送 main

禁止:

  • 在 CI 中调用 kubectl
  • 在 CI 中调用 argocd app sync
  • 把 hard refresh 当常规发布步骤

Helm Chart 规则

Chart 必须反映应用的真实运行架构。

固定要求:

  • 按职责拆文件,不堆一个大模板
  • 模板中不硬编码生产 tag
  • 所有镜像名从 values 读取
  • 所有 Service 暴露方式从 values 读取
  • nginx 对外 Service 固定使用 NodePort
  • 后端 Service 只做集群内访问
  • 不生成 Ingress 模板,也不保留 Ingress values
  • NodePort 必须来自用户或平台已分配值,不能猜
  • 设置 enableServiceLinks: false
  • 支持 imagePullSecrets
  • 环境变量注入保持可读
  • 如果镜像内带 nginx / 反向代理配置upstream service 名必须与 Chart 渲染出的 Service 名一致
  • 生成 chart 时要确认应用是否包含需要经 nginx 转发的静态文件;如果有,必须明确静态资源目录、挂载方式和 nginx 路由,不要只配后端 upstream
  • 不要依赖 Kubernetes 不支持的 $(OTHER_ENV) 展开
  • 对 Neo4j 这类镜像,不要注入不存在的 NEO4J_* 配置名,例如 NEO4J_PASSWORD

如果应用依赖平台 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>/...
  • 第三方镜像保持真实来源
  • Secret 名与 Chart 约定一致
  • PostgreSQL 连接读取应用自己的 databaseSecret
  • 私有镜像包含 imagePullSecrets
  • 与 Chart schema 一致
  • 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 下的裸服务名
  • 不默认为 RedisQdrantOSS 生成应用私有实例
  • 如果应用当前使用的是 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
  • helm template(前提是 Chart 与 values 已能渲染)

至少确认:

  • 接入文件齐全
  • .gitlab-ci.yml 包含 test、镜像构建、Chart 发布、GitOps 同步
  • release values 指向 registry.baizhi.cloud
  • 第三方镜像没有被错误改写到平台 registry
  • GitOps update job 指向 https://deploy.baizhi.cloud/gitops-admin/argodeploy.git
  • CI 中没有直接调用 Argo
  • 只使用 deploy.baizhi.cloudregistry.baizhi.cloud
  • 没有使用不安全的 registry 访问方式
  • 如果 Application 仍引用 releases/<app>/manifests/,该 path 在发布结果中实际存在
  • 如果镜像内包含固定 upstream 配置upstream service 名与 Chart 渲染结果一致
  • Neo4j 一类自带依赖的启动环境变量不依赖 $(OTHER_ENV) 展开
  • 如果检测到的私有 Git 依赖中包含 git.in.chaitin.net/ai/baizhiyun/opensdk,缺少必填百智云私有配置时交互停在当前项继续索取

最终输出

默认按这个顺序汇报:

  1. 修改了哪些文件
  2. 关键决定
  3. 最值得人工复核的点

常见错误

  • 把应用私有鉴权材料放进 shared/
  • 在 CI 里直接刷新 Argo
  • 重新引入旧域名
  • 使用 insecure registry 参数
  • Chart 与应用真实组件不匹配
  • 在生产 release values 中写示例地址
  • 擅自发明新的公网 host
  • 在未检测到私有 Git 依赖中的 git.in.chaitin.net/ai/baizhiyun/opensdk 时仍强行接入百智云
  • 用户未提供必填值时伪造占位内容