--- 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 这个 skill 是 Baizhi GitOps 平台的接入入口与执行摘要。 执行不应依赖用户重复解释平台规则;按本 skill 与当前仓库约定直接推进即可。 目标是让 agent 能独立完成以下工作: - 为应用仓库补齐或恢复 `.gitlab-ci.yml` - 生成或修复 `deploy/helm//` 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` - 共享镜像拉取 Secret:`registry-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 仓库中的 `Application`、`AppProject` 或其他发布侧清单 - 对 GitOps 的唯一动作,是在应用仓库 CI 中推送当前应用自己的 release 结果或版本引用 ## 交付模型 平台采用两个仓库协同交付: - 应用仓库负责源码、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//Chart.yaml` - `deploy/helm//values.yaml` - `deploy/helm//templates/*` - `deploy/release/metadata.yaml` - `deploy/release/values.yaml` - `deploy/release/secret.yaml` 如果应用还有不适合放进 Chart 的静态清单,可以在后续发布结果中导出到当前 GitOps 仓库的 `releases//manifests/`。 ## GitLab CI 规则 runner 约束: - 只要某个 job 需要使用 Docker、DinD 或 `docker buildx`,就必须显式带上 GitLab runner tags:`docker`、`network` ### 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//:` 如果仓库已经使用 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` - 只同步当前应用自己的 release 结果或版本引用 - 提交并推送到 `main` 通常需要更新: - `releases//values.yaml` - `releases//metadata.yaml` - `releases//manifests/` 下由当前应用导出的发布结果 不要在这个 job 中加入集群部署逻辑。 ## Helm Chart 规则 Chart 必须反映应用的真实运行架构。 推荐结构: ```text deploy/helm// ├── Chart.yaml ├── values.yaml └── templates/ ├── _helpers.tpl ├── deployment-.yaml ├── service-.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`,直接使用 - 如果没有提供,先完成所有非阻塞工作,最后只问用户一个最小必要问题来索取该端口 - 不要擅自写入示例端口或看起来顺手的默认值,例如 `30080`、`30081` - 如果用户暂时没有提供,就停在这一项等待补值,不要擅自填入 ## Release Bundle 规则 应用仓库中的 `deploy/release/` 是导出给当前 GitOps 仓库的标准模板。 ### `metadata.yaml` 至少应包含: - 应用名 - Kubernetes release 名 - namespace - chart 名 - chart 版本 - chart 仓库 - 镜像 tag - 源码仓库地址 ### `values.yaml` 必须是可用于部署的默认值,而不是示例值。 至少应满足: - 镜像地址指向 `registry.baizhi.cloud//...` - 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 只负责共享基础设施和通用运行时地址 - 平台共享基础设施包括 `PostgreSQL`、`Redis`、`Qdrant`、`MinIO` - 应用 Chart / release bundle 默认应引用这些 shared 组件的既有服务地址与 shared Secret,不要重复生成这些工作负载 - 这些 shared 组件的 host 应使用平台提供的实际地址或 FQDN,不要默认写成当前应用 namespace 下的裸服务名,例如 `postgres`、`redis`、`qdrant`、`minio` - 只有当用户明确要求该应用自带独立实例时,才为 `PostgreSQL`、`Redis`、`Qdrant`、`MinIO` 生成应用私有资源 - 平台共享基础设施不包含 `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_ENV` 与 `BAIZHIYUN_APP_ID` 决定运行环境与应用标识 - 当 `BAIZHIYUN_ENV=local` 时,opensdk 走 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_id`、`app.crt`、`app.key`、`ca.crt`、`public.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 - 仅使用 `deploy.baizhi.cloud` 与 `registry.baizhi.cloud` - 没有使用不安全的 HTTP registry 访问方式 - 如果存在用户未提供的必填私有配置,交互会话会继续停在当前必填项上索取补值 ## 最终输出要求 默认按下面结构汇报: 1. 修改了哪些文件 2. 关键设计决策 3. 最值得人工复核的 3 个点 ## 常见错误 以下都属于接入错误: - 把应用私有鉴权材料放进 `shared/` - 在 CI 里直接刷新 Argo - 重新引入已废弃的旧域名 - 使用 insecure registry 参数 - 生成的 Chart 与应用真实组件不匹配 - 在生产 release values 中写 `registry.example.com` 这类示例地址 - 应用没有这个设计却擅自发明新的公网 host - 在用户没有提供必填私有值时,仍然伪造占位内容并假装可以直接部署