Files
pikasTech-unidesk/.agents/skills/unidesk-cicd/references/gitea-pac.md
T
2026-07-21 17:18:48 +02:00

272 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.
# Gitea + Pipelines-as-Code
Gitea/Pipelines-as-Code 迁移后的 CI/CD 只有一条正式路径:
```text
GitHub PR merge -> GitHub webhook bridge -> Gitea controlled mirror and immutable snapshot refs -> CLI release plan -> CLI manual PaC webhook -> Tekton PipelineRun -> GitOps/Argo -> k8s runtime
```
GitHub 是唯一上游写入权威。目标 source branch 的 GitHub PR merge 只更新 Gitea source authority,不创建 PipelineRun。操作者必须先执行 `release plan`,审阅本次请求范围、累计有效范围、env reuse、镜像构建和 rollout;范围准确后再执行 `release trigger --confirm`,由 CLI 手动发送 PaC webhook。禁止恢复 Gitea 自动 hook、直接创建 PipelineRun 或用 apply、sync、flush 补跑。
发布链任一环节不通时,任务目标是修复该环节的 YAML、controller、planner 或源码,并重新执行 plan;范围准确后才允许手动 webhook 验收。禁止用 Gitea Actions、`act_runner`、branch-follower、host worktree、Pipeline 内直连 GitHub、直接 Gitea push、人工 mirror sync、裸建 PipelineRun、`trigger-current`、hook test 或自定义脚本补齐当前交付。`config/cicd-gitea-actions-poc.yaml` 只保留只读历史材料。
## Webhook bridge 自举保护
- Argo `selfHeal` 的边界:
- 只能把 GitOps branch 已存在的 desired 恢复到运行面;
- 不能从 GitHub 获取尚未进入 Gitea branch/snapshot 的 bridge 修复 commit
- 不得把 `selfHeal` 描述为 bridge 故障后的独立 source authority。
- Bridge desired 更新必须经过同一 Argo Application 的 PreSync candidate gate
- owning 配置是 `config/platform-infra/gitea.yaml#sourceAuthority.webhookSync.bridge.candidateGate`
- candidate 使用与正式 Deployment 相同的镜像、`server.mjs` 和 ConfigMap 符号链接挂载形状;
- candidate 使用隔离的临时 inbox,只验证进程启动、durable storage readiness 与 `/healthz`
- candidate 通过后才允许 Argo 更新正式 ConfigMap 和 `Recreate` Deployment
- candidate 失败时必须保留现有 ready bridge,不能继续替换单写者。
- Candidate gate 不是第二触发或恢复路径:
- 不读取 GitHub branch
- 不写 Gitea branch/snapshot
- 不创建业务 PipelineRun
- 不接收或重投 webhook delivery。
- 若 bridge 在 candidate gate 引入前已经不可用:
- 新 PR 不能通过同一故障 bridge 自动部署自身修复;
- 状态必须明确报告自举死锁;
- 禁止用 branch-follower、轮询、人工 mirror sync、直接 Gitea push、人工 PipelineRun、`trigger-current`、sync/flush 或 delivery 重投伪造自动恢复。
## 唯一事实来源
- Gitea source authority、GitHub webhook bridge、公网暴露与 source snapshot 归属 `config/platform-infra/gitea.yaml`
- PaC controller、Repository CR、consumer 参数、Tekton pipeline 名称与 Argo Application 归属 `config/platform-infra/pipelines-as-code.yaml`
- CLI 必须组合两份 YAML,并按 consumer、node、lane、upstream repository、branch 与 Gitea repository 精确解析 authority。不得用 URL heuristic 或 repo 专属特例;`unknown`、歧义和配置错误都必须 `mutation=false` 并 fail-closed。
- 旧 source mutation 入口已退役;历史 help/status 只能返回只读诊断,Gitea/PaC consumer 和 `unknown` authority 都不得回退到 legacy 实现。
- 包含 `gitea-actions` 的历史 snapshot prefix 只为既有 ref 保留,不代表 Gitea Actions 仍是有效触发架构。
- node 级状态入口是 `bun scripts/cli.ts cicd status --node <NODE>`consumer 级默认下钻入口是 `platform-infra pipelines-as-code status|history --target <NODE> --consumer <id>`
- Gitea 公网入口:
- 公开 Web UI 与 owning webhook path 统一由 `config/platform-infra/gitea.yaml#app.publicExposure` 声明;
- NC01 public-edge 直接连接 ClusterIP Service
- 不得为 Gitea 保留 FRPC、PK01 Caddy 或公网回环 fallback
- target 仍通过 `targets[].webhookSync.publicPath` 保持 hook 身份隔离;
- 禁止在 source PR 合并后人工 apply 补齐。
- PaC Repository CR `spec.url` 必须与 Gitea webhook payload 中的 URL 一致。`config/platform-infra/pipelines-as-code.yaml#repositories[].url` 保持公网 Gitea repository URLk8s 内网 service URL 只能写入 `cloneUrl``params.git_read_url`;否则 PaC 会记录 `cannot find a repository match` 且不会创建 PipelineRun。
- JD01 与 NC01 共用的 repository 必须传入 target-specific `node` Repository param,每个 `.tekton` PipelineRun 必须用 `pipelinesascode.tekton.dev/on-cel-expression` 过滤该参数。一个 target 的 push 不得在同一 target cluster 创建另一 target 的 PipelineRun。
## PaC consumer 首发最短路径
- 在 source PR 合并前完成源码侧准备:
- owning YAML 中声明 Gitea repository、PaC repository 与 consumer
- consumer 声明 `sourceArtifact` 时,先在 source worktree 执行 `source-artifact check`;该命令同时检查内联 Pipeline 的 `command``args` 与 shell `script` 实际执行的仓库相对源码入口是否存在;
- 不创建人工 PipelineRun,也不推送 Gitea branch 或 snapshot。
- 只使用同一个组合入口完成控制面首次引导:
```bash
bun scripts/cli.ts platform-infra pipelines-as-code bootstrap --target <NODE> --consumer <consumer> --dry-run
bun scripts/cli.ts platform-infra pipelines-as-code bootstrap --target <NODE> --consumer <consumer> --confirm
```
- 组合入口负责以下职责:
- 组合 `config/platform-infra/gitea.yaml``config/platform-infra/pipelines-as-code.yaml`
- 按 target、Gitea owner/name 与 read URL 精确选择唯一 repository
- 初始化选中的空 Gitea repository
- 安装或更新 PaC controller、consumer RBAC、Repository CR、Argo bootstrap 与 Gitea webhook
- 不同步 source branch,不创建 snapshot,不触发业务 PipelineRun。
- 预检与失败边界:
- 默认 human 与显式 `--json` 使用同一份紧凑 typed projection,按 `yaml-exact-match``github-upstream``gitea-repository` 前置条件,以及 `gitea-init``pac-controller``tekton-consumer``gitops-argo` 阶段展示结果;只有显式 `--full``--raw` 才披露底层组合结果;
- YAML 精确匹配必须显示匹配数量,并区分 `yaml-repository-no-match``yaml-repository-multiple-matches`
- GitHub 上游或凭据不可用、Gitea 初始化失败与 PaC apply 失败必须使用不同 blocker code;不得折叠为同一条未知错误;
- 失败输出只给 owning YAML 修正提示或 consumer 只读 `status` 下钻;不得给 mirror sync、人工 PipelineRun、Argo refresh 或其他 mutation 恢复命令;
- PaC `apply` 在任何 Kubernetes 写入前读取 Gitea repository
- repository 缺失时返回 `gitea-repository-missing`,不留下半套 Tekton/RBAC/Argo 状态;
- YAML 零匹配或多匹配时在本地拒绝,不猜测 repository
- `gitea mirror bootstrap` 未带 `--confirm` 时输出可读 dry-run 与精确 confirm 命令,不再返回空白拒绝。
- 完成 `bootstrap --confirm` 后合并 source PR
- GitHub PR merge 只更新 source authority
- 执行 `release plan` 并审阅范围;
- plan 未扩大时执行 `release trigger --confirm`
- 不再调用 bootstrap、apply、mirror sync、裸建 PipelineRun、Argo refresh 或 closeout。
- 只有出现自动链故障或用户明确要求验收时才读取状态:
- 首选一次 `cicd status --node <NODE>` 获取 node 摘要;
- 只对失败 consumer 使用一次 `pipelines-as-code status --consumer <id>`
- 只有归属或 TaskRun 断点不清楚时再用 `history --id``debug-step --id`
- 默认不使用 `--full``--raw`,避免把大对象带回本机;
- consumer 声明 `sourceArtifact` 且需要精确提交验收时,最后执行一次 `source-artifact verify-runtime`
- node 状态摘要必须保持可读且可下钻:
- text 输出在零 consumer、ready、warning 与失败时都返回非空 typed 摘要;
- 摘要只给出与当前状态匹配的精确下钻命令;
- 不要求操作者阅读源码或手工拼接多个 consumer 命令。
- registry applicability 只由 owning YAML 决定:
- consumer 对应 pipeline 声明 image repository 时,registry 状态适用;
- 适用的 registry 缺失是 blocker
- GitOps-only consumer 未声明 image repository 时,registry 显示 `N/A`
- 不得因 registry 不适用而把 GitOps-only consumer 判为失败。
## PaC 源码侧制品同步
当 owning Pipeline 与消费仓 `.tekton` 内联 `pipelineSpec` 或远程 Pipeline 文件存在漂移时,统一使用以下入口:
```bash
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact plan --target <NODE> --consumer <id> --source-worktree <absolute-path>
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact check --target <NODE> --consumer <id> --source-worktree <absolute-path>
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact write --target <NODE> --consumer <id> --source-worktree <absolute-path> --confirm
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact status --target <NODE> --consumer <id> --source-worktree <absolute-path> [--source-commit <full-sha>]
bun scripts/cli.ts platform-infra pipelines-as-code source-artifact verify-runtime --target <NODE> --consumer <id> --source-worktree <absolute-path> --source-commit <full-sha>
```
- `config/platform-infra/pipelines-as-code.yaml#consumers[].sourceArtifact` 是生成职责的声明入口;未声明的 consumer 必须稳定拒绝,模板不得替它发明 owner。
- `source-artifact plan|check|write` 只能在 source PR 合并前生成或校验该 PR 的受管源码制品,不是合并后的 CI/CD 触发、同步、恢复或补跑入口。
- desired 只来自 owning YAML 与共享 domain rendererlive Pipeline 和 PipelineRun 只能作为只读诊断证据,禁止从运行面反向导出 desired 或源码制品。
- `plan``check``write` 只比较或更新显式消费仓 worktree,不访问运行面;worktree 必须是绝对路径、Git 根目录,并与声明仓库的精确 remote identity 一致。
- `write` 先完成全部路径、内容和 renderer 合同校验,再通过同目录临时文件与 rename 更新;连续执行必须无差异。
- `plan|check|write` 对受管 Pipeline 做通用源码入口检查:
- 只识别实际执行上下文中的仓库相对 `scripts/``src/``deploy/``config/` 入口;
- 缺失入口进入 `sourceEntrypoints.missing` 并使 `check|write` fail-closed
- `..` 逃逸和仓库外路径不参与读取,输出只披露相对路径。
- `status` 是非门禁诊断,允许不传 commit。
- `verify-runtime` 必须满足以下条件:
- 传入完整四十位 `--source-commit`
- `--source-worktree` 干净;
- worktree `HEAD` 与该 commit 完全相同;
- 合并提交的验收新建精确提交 worktree,不使用带未提交修改或停在父提交的开发 worktree;
- PipelineRun 按 PaC/source-commit label 或 annotation 精确筛选,不按 prefix 直接取全局 latest。
- 同一 source commit 因 webhook 重投或 PaC retry 产生多个 PipelineRun 时,只在完整内联 spec 与 provenance 全部一致时确定性选择最新一条并披露候选数;存在冲突必须 fail-closed。
- runtime observer 必须满足以下约束:
- 区分对象 `NotFound`、transport/RBAC/命令不可用和 spec drift
- 完整大 spec 通过受控临时文件传入目标侧原生 observer,不放入 shell argv 或环境变量;
- 默认、`--json``--full` 的错误与 drift 只输出结构路径、类型、长度、SHA-256 或 URL fingerprint
- 不回显脚本、URL 凭据、查询参数、Authorization、Secret、stdout 或 stderr 原文。
- 完整 spec 比较只移除六类已验证的 Tekton admission default,并限定在裸 Pipeline spec、完整 Pipeline 或 PipelineRun `pipelineSpec` 三个明确根;其他同名字段不得过滤。
- `sourceArtifact.taskRunTemplate``hostNetwork``dnsPolicy``fsGroup` 的唯一所有者;生成器不得另设硬编码默认值。
- HWLAB source artifact 必须经过完整 domain renderer、正式 postprocess/verify 和完整 spec 比较。
- Kafka refresh 等业务合同由 owning renderer 与消费者结构化负例测试保障;
- 不得在通用生成器中用字符串 marker 扫描建立第二真相。
- AgentRun source artifact 通过完整 owning Pipeline 与完整 spec 比较保留 RBAC、参数和 manager 环境合同。
## 覆盖矩阵
| Consumer | Source | PaC namespace | Pipeline | Argo Application | 状态命令 |
|---|---|---|---|---|---|
| `agentrun-jd01-v02` | `pikasTech/agentrun@v0.2` | `agentrun-ci` | `agentrun-jd01-v02-ci-image-publish` | `agentrun-jd01-v02` | `platform-infra pipelines-as-code status --target JD01 --consumer agentrun-jd01-v02` |
| `sentinel-jd01-v03` | `pikasTech/unidesk@master` | `devops-infra` | `hwlab-web-probe-sentinel-jd01-pac` | `hwlab-web-probe-sentinel-jd01` | `platform-infra pipelines-as-code status --target JD01 --consumer sentinel-jd01-v03` |
| `hwlab-jd01-v03` | `pikasTech/HWLAB@v0.3` | `hwlab-ci` | `hwlab-jd01-v03-ci-image-publish` | `hwlab-node-v03` | `platform-infra pipelines-as-code status --target JD01 --consumer hwlab-jd01-v03` |
| `agentrun-nc01-v02` | `pikasTech/agentrun@v0.2` | `agentrun-ci` | `agentrun-nc01-v02-ci-image-publish` | `agentrun-nc01-v02` | `platform-infra pipelines-as-code status --target NC01 --consumer agentrun-nc01-v02` |
| `sentinel-nc01-v03` | `pikasTech/unidesk@master` | `devops-infra` | `hwlab-web-probe-sentinel-nc01-pac` | `hwlab-web-probe-sentinel-nc01` | `platform-infra pipelines-as-code status --target NC01 --consumer sentinel-nc01-v03` |
| `hwlab-nc01-v03` | `pikasTech/HWLAB@v0.3` | `hwlab-ci` | `hwlab-nc01-v03-ci-image-publish` | `hwlab-node-v03` | `platform-infra pipelines-as-code status --target NC01 --consumer hwlab-nc01-v03` |
- history 范围:
- 使用 `bun scripts/cli.ts platform-infra pipelines-as-code history --target <NODE> --limit 10` 审计全部 consumer 的触发、耗时与 reuse
- target 汇总读取实时 Gitea Repository CR 与 Tekton PipelineRun/TaskRun,并按 namespace 复用读取、聚合和显式输出 `READ_ERRORS`
- 指定 `--consumer <id>` 或可唯一归属的 `--id` 时只走单 consumer 快路径;
- `config.scope` 明确显示 `target-summary``single-consumer`
- 单次交付耗时查询:
- 使用 `bun scripts/cli.ts platform-infra pipelines-as-code delivery-timing --target <NODE> --consumer <id>`
- 命令从 owning YAML 解析上游 GitHub repository、branch 与 consumer
- 默认关联最新 PipelineRun source commit 对应的 GitHub PR `mergedAt`
- 同时披露 trigger wait、PipelineRun、端到端耗时及 Argo/runtime closeout
- 缺少 PR、时间戳或 provenance 时返回 `partial``evidenceGaps`,不得用 commit 时间替代 `mergedAt`
- 整个入口保持 `mutation=false`,不写入历史库,不触发、同步或补跑交付。
- registry cache 性能验收:
- 冷缓存样本:
- 第一个正常 source PR 只负责预热;
- PipelineRun 成功且 cache 已导出后记录一次 `delivery-timing`
- 不得把首次 `mode=max` 导出耗时当作 cache-hit 回归结果。
- cache-hit 样本:
- 第二个正常 source PR 不得改变目标构建输入;
- 可以使用本来就需要合并的源码或文档变更;
- 禁止制造无语义 source-artifact 刷新。
- 耗时判定:
- 两个样本各执行一次 `delivery-timing`
- 按 owning YAML 的 `deliveryTiming.endToEndBudgetSeconds` 比较 trigger wait、PipelineRun、最长 TaskRun 和端到端耗时;
- `state=partial` 时保留已成立的时间字段与 `evidenceGaps`,不立即串联 `status``history` 或日志;
- 只有真实失败或证据矛盾才按最短分层诊断入口下钻。
- source artifact 收口:
- consumer 声明 `sourceArtifact` 时,在最终 cache-hit commit 建立 clean exact-commit worktree
- 只执行一次 `source-artifact verify-runtime`,完成 artifact、embedded PipelineRun 与 provenance 对齐。
- 禁止项:
- 两个样本分别使用一次 PR merge、一次 plan 和一次手动 webhook
- 不创建人工 PipelineRun
- 不执行 mirror sync、Argo sync、补链或第二触发。
`history --id <pipelinerun>` 必须按 target 内唯一 PipelineRun prefix 或 Tekton pipeline 归属解析实际 consumer,并用该 consumer 生成 status/history `Next`。零匹配、多匹配或显式 `--consumer` 与实际归属冲突时必须在远端读取前 fail-closed;禁止回退默认 consumer。
## 按需只读调查
手动 webhook 发出后,PaC、Tekton、GitOps/Argo 必须自动完成后续交付并记录 terminal 状态。以下入口只在显式调查发布链故障时按需使用:
- `bun scripts/cli.ts platform-infra gitea mirror status --target <NODE>`
- `bun scripts/cli.ts platform-infra gitea mirror webhook status --target <NODE>`
- `bun scripts/cli.ts platform-infra pipelines-as-code status --target <NODE> --consumer <id>`
- `bun scripts/cli.ts platform-infra pipelines-as-code history --target <NODE> --consumer <id> --limit 10`
- 对归属或状态不明的行,使用 `bun scripts/cli.ts platform-infra pipelines-as-code history --target <NODE> --id <pipelinerun>` 下钻 PipelineRun。
- 已知失败 PipelineRun 时使用 `debug-step --target <NODE> --consumer <id> --id <pipelinerun>`;默认结果一次包含失败 TaskRun、step、container、exit code、termination reason 与脱敏有界日志尾。
- `closeout` 兼容边界:
- 只保留为可选的只读历史/诊断兼容入口;
- 不得出现在 migrated consumer 的默认观察顺序、覆盖矩阵、正常下一步或 PR 合并后的主/子代理任务中;
- 不得创建、同步、刷新、重试或补跑任何交付对象;
- 显式 `--wait` 由 Kubernetes watch 持有等待;
- 只有 source commit、GitOps exact/descendant ancestry、Argo 与 runtime sha256 digest 一致时才 ready
- `no-runtime-change` 使用独立保留合同;
- consumer 专属 debug 命令只允许复现单步故障,不得成为正式交付或恢复入口。
GitHub webhook delivery 的持久接收与 refs 提交必须分层:
- receiver 验签并校验 payload 后,只有在 delivery 通过 fsync 与 atomic rename 写入 YAML 声明的 PVC durable inbox 后才能返回 HTTP `202 Accepted`
- `202 Accepted` 只证明 delivery 已持久接收,不证明 Gitea authority branch 或 immutable snapshot 已 committed
- journal 状态必须显式区分 `accepted``processing``committed``failed`,并保留 deliveryId、payload correlation、尝试次数与有界失败摘要;
- 同 deliveryId 与同 payload 必须幂等,异 payload 必须返回 `409`PVC 不可用或容量满必须返回 `503` 并使 readiness=false
- inbox worker 使用 YAML 声明的有界 backoff 自动重试,进程重启后恢复 `accepted` / `processing`,不要求人工 sync、repair、test 或 PipelineRun
- 只有同一 delivery 的 exact-after immutable snapshot 与 authority branch 经 atomic push 后重新读取 refs 证明一致,才能进入 `committed`
- Caddy 只可对尚未成功落盘的请求做小于 10 秒、body-safe 的有界重试,不能把代理成功当作 refs committed。
- 当前 bridge 的权威状态链:
- GitHub delivery GUID -> durable inbox record -> post-push refs proof -> live refs
- HTTP `202` 后记录仍是 `accepted``refsCommitted=false`
- 只有 worker 完成 exact refs 复核后才成为 committed
- 旧 durable journal 上线前的记录可以标记 `pre-durable-bootstrap`,但不得标记 committed
- `ingressRetry` 由 owning YAML 与 NC01 public-edge 自动交付共同控制,不能由操作者手工补配置。
Durable inbox 只是 webhook delivery 的持久接收与重试 journal,不是业务 source/ref 的第二份真相,也不得被 PaC、Tekton、GitOps、Argo 或 runtime 当作源码/read model。最终 source authority 仍只有 Gitea authority branch 与 immutable snapshot。`webhook status` 默认摘要必须显示 accepted -> processing -> committed/failed 分层,并将同一 delivery 的 accepted correlation 与 committed refs proof 关联。非 `202`、缺 accepted correlation、accepted 后未 committed 或进入 failed 都是失败/stale;只能修 webhook bridge、inbox worker、受控 mirror、snapshot controller 或 owning YAML,禁止输出或执行人工 `REPAIR`、mirror sync、直接 Gitea push 等补齐命令。
不得使用 `cicd branch-follower status` 判定三个已迁移 JD01 consumer 是否最新。该入口只保留历史/迁移用途,可能包含 PaC cutover 前的过期状态。
对已迁移 sentinel CI/CD 的 half-state 诊断,PaC `status` 命令负责 source/registry/GitOps/Argo/runtime 归因。它必须通过 target 侧短探针区分 registry-missing、GitOps-missing、Argo-pending 和 runtime-mismatch,并使用 `registry_probe_base` 等 YAML 声明的 probe endpoint;禁止重新把旧 control-plane status 当作主架构,也禁止把 registry manifest `HEAD` 当作 readiness 校验。
Sentinel 的内部 `pac-publish-current` capability 由 `config/platform-infra/pipelines-as-code.yaml#capabilities.sentinelInternalPublish` 单一拥有,当前必须保持 `enabled=false``admissionProvenance=unavailable``.tekton` 继续使用既有 `publish-current` 自动入口;不得因为 capability 关闭而改成人工 publish。Pod env、ownerReferences、ServiceAccount、label、annotation 与 controller metadata 都是普通 workload 可声明或可修改的运行对象,不能作为 creator proof。只有 #1769 定义的独立 admission-owned provenance、专用最小权限 SA/RBAC 与拒绝 workload 自声明标记全部落地后,才能通过 YAML 评审启用 capability。
PaC history/status 必须把候选 PipelineRun 分成 `outer-pac-event``inner-deterministic-publish``unknown`。只有唯一外层 PaC push event 可以驱动 latest、status、debug-step 或 closeout;内层 deterministic publish 只能作为未绑定的执行观察展示,父子关系缺证据时必须标记 `unproven`,不得按名称前缀推断。运行对象 metadata 只能支持“已观察到 PaC 形态”的分类,不能宣称 admission provenance 已验证。
## Reuse 证据解释
- AgentRun `IMAGE_STATUS=reused` 表示本次跳过 image build,或复用了同一 env identity 的 registry artifact。
- Sentinel `ENV_REUSE=hit` 表示依赖可复用;`cache=hit` 是独立的 BuildKit 证据。
- HWLAB `skipped,skip=<n>` 表示 service-level artifact plan 跳过了可复用 build;判定具体变更 service 时应查看 PipelineRun 详情。
## UniDesk Host 运行面变更过滤
`unidesk-host` consumer 将镜像构建与 GitOps 资源发布分离:
- `config/unidesk-host-k8s.yaml#delivery.changeDetection.sharedImagePaths` 只声明所有服务镜像共同复制的源码输入;
- `delivery.services[].imagePaths` 只声明对应服务镜像复制的源码输入;
- `delivery.gitops.resources` 每次都从当前 source commit 确定性渲染,再由 Git diff 判定是否发布;
- `delivery.services[].gitops.releaseStatePath` 指向各服务镜像比较基线。
- `build`
- 至少一个声明的镜像路径发生变更,或没有可信的历史 release state
- 流水线构建镜像、更新 manifest 与 release state,然后由 Argo 收敛。
- `skip`
- source commit 已推进,但没有声明的镜像路径发生变更;
- 流水线不得构建镜像,应保留既有镜像 source commit 与 digest
- GitOps 资源仍独立渲染和发布。
- `disabled``delivery.enabled=false`。删除生成的 manifest 与 release state;这代表 service retirement,不是 `skip` 的同义词。
- 镜像路径边界:
- CLI、文档、issue metadata、GitOps renderer 和交付 helper 不能进入镜像路径列表;
- 否则会把配置发布误判为应用镜像重建。
- 成功跳过镜像构建时:
- 仍应产生一条短 PaC PipelineRun 作为 source observation 证据;
- 允许 GitOps 资源独立形成新 revision
- 默认 `status` 必须校验保留的 digest、GitOps revision、Argo state、runtime readiness 与 health
- 不得强制镜像 source commit 等于更新的非镜像 source commit
- 兼容 `closeout` 只能复用同一只读证据。
缺少 reuse 文本不能证明 reuse path 失败,应先核对 consumer type 与 PipelineRun 详情。