agent-skills/gitops-app-onboarding/SKILL.md
2026-03-31 17:01:17 +08:00

16 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

这个 skill 是 Baizhi GitOps 平台的接入入口与执行摘要。

执行不应依赖用户重复解释平台规则;按本 skill 与当前仓库约定直接推进即可。

目标是让 agent 能独立完成以下工作:

  • 为应用仓库补齐或恢复 .gitlab-ci.yml
  • 生成或修复 deploy/helm/<app>/ Chart
  • 生成或修复 deploy/release/ release bundle
  • 在发版链路中将当前应用自己的 release 结果推送到固定 GitOps 仓库

平台固定常量

除非用户明确要求修改,否则默认使用以下常量:

  • 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
  • 共享镜像拉取 Secretregistry-pull-secret
  • GitOps 控制器Argo CD
  • Chart 分发方式OCI Registry
  • 源代码托管GitLab

应用仓库 CI 默认依赖以下 GitLab 变量:

  • GITEA_USER
  • GITEA_TOKEN
  • REGISTRY_PASSWORD

通常直接把 REGISTRY_USER 写成 registry-ci

真相来源与读取顺序

开始改代码前,按下面顺序建立上下文:

  1. 先读目标应用仓库 README.md
  2. 再读 Dockerfile、包管理文件、构建脚本、现有 deploy 文件
  3. 如果用户给了额外设计文档,一并读取

判断规则:

  • 目标应用仓库自己的 README.md 是应用运行架构的真相来源
  • 本 skill 定义平台接入流程、约束和执行重点
  • 如果应用 README 与平台约定冲突,优先识别是“应用设计差异”还是“平台硬约束”
  • 如果冲突会直接改变最终实现且无法安全推断,再问用户;否则优先按已有代码和文档做最小偏差实现

在生成任何文件前,先推断出:

  • 组件列表
  • 每个组件的构建上下文
  • 容器入口
  • 对外暴露模型
  • 运行时配置结构
  • 哪些依赖属于平台共享,哪些是应用私有

不要假设每个项目都长得和现有项目一样。

先判断修改范围

先区分任务属于哪一种:

  1. 补齐或修复应用仓库中的 CI、Chart、release 模板
  2. 修复应用仓库中的发版链路,使其在发版时推送当前应用自己的 release 结果

边界约束:

  • 本 skill 只处理应用仓库侧接入
  • 不读取、不判断、不修改 GitOps 仓库中的 ApplicationAppProject 或其他发布侧清单
  • 对 GitOps 的唯一动作,是在应用仓库 CI 中推送当前应用自己的 release 结果或版本引用

交付模型

平台采用两个仓库协同交付:

  • 应用仓库负责源码、Docker 构建、.gitlab-ci.yml、Helm Chart 源码、release bundle 模板
  • 当前 GitOps 仓库负责 Argo CD ApplicationAppProject、平台 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/

GitLab CI 规则

runner 约束:

  • 只要某个 job 需要使用 Docker、DinD 或 docker buildx,就必须显式带上 GitLab runner tagsdockernetwork

stages

使用这三个 stage

  • test
  • build
  • release

test job

test job 应运行在分支和 MR 上,并执行目标项目自己的标准测试命令。

要求:

  • 安装该语言栈所需的最小依赖
  • 如果依赖私有代码仓库,补齐认证
  • 使用项目本身的标准测试入口,不要擅自发明新的测试命令

示例:

  • Gogo mod downloadgo test ./...
  • Nodenpm cinpm 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 的 versionappVersion 更新为 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
  • 只同步当前应用自己的 release 结果或版本引用
  • 提交并推送到 main

通常需要更新:

  • releases/<app-name>/values.yaml
  • releases/<app-name>/metadata.yaml
  • releases/<app-name>/manifests/ 下由当前应用导出的发布结果

不要在这个 job 中加入集群部署逻辑。

Helm Chart 规则

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

推荐结构:

deploy/helm/<app-name>/
├── Chart.yaml
├── values.yaml
└── templates/
    ├── _helpers.tpl
    ├── deployment-<component>.yaml
    ├── service-<component>.yaml 或 services.yaml
    └── 按职责拆分的其他资源

规则:

  • 按职责拆文件,不要堆成一个巨大模板
  • 模板中不要硬编码生产镜像 tag
  • 所有镜像名都从 values 读取
  • 所有 Service 暴露方式都从 values 读取
  • nginx 对外 Service 固定使用 NodePort
  • 后端 Service 默认使用集群内访问类型,不对外暴露 NodePort
  • 如果应用运行时依赖某个不属于平台 shared 的私有服务Chart / release bundle 必须把该依赖的来源表达清楚:要么生成应用自带资源,要么明确引用用户已提供的外部地址;不要只留下一个指向不存在服务的 host
  • NodePort 必须来自用户或平台已分配值agent 不得自行猜测或默认分配端口
  • 不要生成 Ingress 模板或 Ingress values
  • 设置 enableServiceLinks: false
  • 支持 imagePullSecrets
  • 环境变量注入保持可读
  • 健康检查要符合真实应用行为

_helpers.tpl 一般至少提供:

  • chart name
  • fullname
  • namespace
  • labels
  • selector labels

只有当项目本身确实有 path 推导的 URL 时,才增加 URL helper。

对外暴露模型

对外暴露模型使用固定方式,不再按项目自由选择。

  • 固定使用 nginx 作为统一入口,代理前端与后端路径
  • 对外只暴露 nginx 入口,并通过 NodePort 提供入口访问
  • 后端服务默认只在集群内通信
  • 每个应用对外只保留一个 nginx NodePort 入口
  • 不生成 Ingress 资源,也不要在 values 中保留 Ingress 开关
  • 不要因为应用有多个内部服务,就擅自发明多个公网 host

如果项目当前没有现成的前端代理层,也应按这个固定模型为对外入口预留 nginx 代理方案,而不是改成 Ingress。

NodePort 处理规则:

  • 如果用户或项目文档已经提供了分配好的 NodePort,直接使用
  • 如果没有提供,先完成所有非阻塞工作,最后只问用户一个最小必要问题来索取该端口
  • 不要擅自写入示例端口或看起来顺手的默认值,例如 3008030081
  • 如果用户暂时没有提供,最终输出中必须明确说明 nginx 对外 NodePort 尚未分配,因此外部访问配置未完成

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 保持一致
  • nginx 对外入口使用 NodePort
  • NodePort 值来自用户或平台已分配结果,而不是模板内置默认值
  • 不包含 Ingress 配置项

secret.yaml

用于放应用私有 Secret 模板key 名必须与 Chart 读取的 key 对齐。

规则:

  • 不要为了“看起来完整”而伪造假的生产值
  • 先区分“外部集成凭据”和“应用自带私有依赖的内部口令”
  • 如果是外部集成凭据,应在完成所有非阻塞工作后主动向用户索取,而不是只在最后留警告
  • 如果是应用自带私有依赖的内部口令,优先由生成流程一次性生成并写入 release secret而不是要求用户手填
  • 如果用户暂时没有提供,不要造占位内容冒充可部署配置
  • 对部署阻塞项,按最小必要粒度逐项提问,优先直接问“这一项应填什么”
  • 只有当用户明确暂不提供、或本轮对话结束时仍未补齐,才在最终输出中保留缺失项警告
  • 可以只保留结构,或暂不生成具体 secret 内容,但必须在最终输出中明确警告缺失项与影响

release bundle 只负责导出当前应用自己的发布结果,不负责维护 GitOps 仓库中的其他对象。

平台共享配置契约

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
  • MINIO_ACCESS_KEY
  • MINIO_SECRET_KEY

shared 边界:

  • shared 只负责共享基础设施和通用运行时地址
  • 平台共享基础设施包括 PostgreSQLRedisQdrantMinIO
  • 应用 Chart / release bundle 默认应引用这些 shared 组件的既有服务地址与 shared Secret不要重复生成这些工作负载
  • 只有当用户明确要求该应用自带独立实例时,才为 PostgreSQLRedisQdrantMinIO 生成应用私有资源
  • Neo4j 不再作为平台共享基础设施提供;如应用需要图数据库,应由应用自己部署和维护
  • 只要应用运行时配置仍引用某个应用私有依赖,就应在应用 Chart / release bundle 中把它一并表达出来,而不是只在 values 里保留连接参数
  • 不要把某个厂商的客户端证书、私钥、应用专属 app_id、tenant id、client id、namespace id、应用独有 webhook 签名密钥放进 shared/
  • 镜像拉取默认使用 registry-pull-secret,不要随便为每个应用再造一个 pull secret除非平台模型发生变化

百智云用户鉴权接入

平台接入要求百智云用户鉴权。

处理规则:

  • 不要把这类鉴权材料当成平台共享配置
  • 不要擅自生成生产值
  • 先完成所有非阻塞工作
  • env 与鉴权材料均为必填项
  • 鉴权材料按固定顺序向用户索取:app_id -> app.crt -> app.key -> ca.crt -> public.key
  • 如果用户还没提供完整值,不要写伪造占位内容;在最终输出中明确警告缺失了哪些字段以及可能影响

opensdk 读取与挂载规则:

  • 当前 opensdk 通过环境变量 BAIZHIYUN_ENVBAIZHIYUN_APP_ID 决定运行环境与应用标识
  • BAIZHIYUN_ENV=localopensdk 走 mock 分支,不读取证书文件
  • local 环境下opensdk 会从固定路径读取证书文件,而不是从环境变量读取路径
  • 固定文件路径是:/app/ssl/app.crt/app/ssl/app.key/app/ssl/ca.crt
  • 因此在 Chart / workload 中,应把百智云 Secret 以文件名不变的方式挂载到目录 /app/ssl
  • 不要把证书挂到其他自定义目录后期待 opensdk 自动发现,例如 /.tls/baizhi
  • public.key 不属于当前 opensdk 建立 mTLS 连接时的必读文件;如果平台或应用仍要求保留它,应明确说明它的用途,不要把它和 mTLS 必需挂载文件混为一谈

提问方式要求:

  • 只在真正阻塞最终可部署结果时才问
  • 先做完不依赖这些值的工作
  • 按必填项收集百智云配置
  • 先索取 env,再按固定顺序逐项索取 app_idapp.crtapp.keyca.crtpublic.key
  • 对外部集成字段,应在非阻塞工作完成后逐项索取,而不是直接跳到最终缺失项警告
  • 对应用自带私有依赖内部口令,优先自动生成;只有用户明确要求自定义时才向用户索取
  • 不要用“把需要的都给我”这种模糊问法
  • 缺少任一必填项时,要明确指出当前卡在哪一项

执行流程

建议按下面顺序推进:

  1. 读取应用 README 与构建文件,梳理组件和暴露模型
  2. 判断任务是补齐应用仓库接入,还是修复发版链路
  3. 生成或修复 .gitlab-ci.yml
  4. 生成或修复 Chart 与 values
  5. 生成或修复 release bundle
  6. 完成非阻塞工作后,再逐项补齐百智云必填字段
  7. 自检并在最终输出中说明风险点

自检要求

完成后尽量执行:

  • git status --short
  • git diff --check
  • helm template,前提是 Chart 与 values 已能渲染

至少确认:

  • 应用仓库不再缺少接入文件
  • .gitlab-ci.yml 包含 test、镜像构建、chart 发布、release 结果同步逻辑
  • 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
  • 在用户没有提供必填私有值时,仍然伪造占位内容并假装可以直接部署