Files
pikasTech-unidesk/.agents/skills/unidesk-cicd/references/gitea-pac.md
T
2026-07-13 09:27:42 +02:00

185 lines
20 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 -> Gitea Repository webhook -> Pipelines-as-Code -> Tekton PipelineRun -> GitOps/Argo -> k8s runtime
```
GitHub 是唯一上游写入权威。目标 source branch 的 GitHub PR merge 是唯一正式交付触发事件;合并后必须由 webhook、mirror、PaC、Tekton、GitOps/Argo 自动推进到运行面,无需主代理、子代理或操作者执行任何 apply、closeout、trigger、sync、flush 或补跑。状态与历史命令只能观察和诊断,不能推进交付。
自动链任一环节不通时,任务目标是修复该环节的 YAML、controller 或源码,并以修复 PR 合并后产生的新自动链事件作为验收证据。禁止用 Gitea Actions、`act_runner`、branch-follower、host worktree、Pipeline 内直连 GitHub、直接 Gitea push、人工 mirror sync、人工 PipelineRun、`trigger-current`、伪 push、hook test 或自定义脚本补齐当前交付。`config/cicd-gitea-actions-poc.yaml` 只保留只读历史材料。会 POST Gitea hook `/tests``webhook-test` 已从 Gitea source-authority 与 PaC 公共 CLI、远端执行器移除,因为它会制造交付事件,不是只读连通性诊断。
## 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。
- 旧人工 mutation 入口只允许在 owning YAML 精确解析为 `legacy-manual` 后从 scoped help 使用;Gitea/PaC migrated 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>`
- 共用 GitHub 上游的多 node PaC consumer 不得共用 webhook bridge URL。每个 target node 在 `config/platform-infra/gitea.yaml#targets[].webhookSync` 声明自己的 GitHub webhook 公网路径与 FRP remote port,并由平台自动交付渲染 node-local bridge、FRPC proxy 和 PK01 Caddy 路径;禁止在 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`
- 不创建人工 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。
- 预检与失败边界:
- 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 是唯一 delivery 触发;
- 不再调用 bootstrap、apply、mirror sync、PipelineRun、Argo refresh 或 closeout
- 正常链路不串联 mirror status、webhook status、PaC status 与 history。
- 只有出现自动链故障或用户明确要求验收时才读取状态:
- 首选一次 `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`
## 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 更新;连续执行必须无差异。
- `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` |
使用 `bun scripts/cli.ts platform-infra pipelines-as-code history --target <NODE> --limit 10` 审计全部 consumer 的触发、耗时与 reuse。命令必须读取 target node 上的实时 Gitea Repository CR 与 Tekton PipelineRun/TaskRun,在 target 侧聚合并显式输出 `READ_ERRORS`
`history --id <pipelinerun>` 必须按 target 内唯一 PipelineRun prefix 或 Tekton pipeline 归属解析实际 consumer,并用该 consumer 生成 status/history `Next`。零匹配、多匹配或显式 `--consumer` 与实际归属冲突时必须在远端读取前 fail-closed;禁止回退默认 consumer。
## 按需只读调查
自动链必须在没有任何操作者命令的情况下完成交付并记录 terminal 状态。以下入口只在显式调查自动链故障时按需使用,不是 PR 合并后的默认顺序、交付前置或“下一步”:
- `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。
`closeout` 只保留为可选的只读历史/诊断兼容入口,不得出现在 migrated consumer 的默认观察顺序、覆盖矩阵、正常下一步或 PR 合并后的主/子代理任务中。它不得创建、同步、刷新、重试或补跑任何交付对象。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` 在自动 PK01 host reconciler 完成前保持关闭,不能由操作者手工补配置。
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 将 source observation 与 runtime delivery 分离。`config/unidesk-host-k8s.yaml#delivery.changeDetection.runtimePaths` 是唯一可编辑的 runtime 变更 source path 列表,`delivery.gitops.releaseStatePath` 指向用作比较基线的 GitOps release state 生成物。
- `build`:至少一个声明的 runtime path 发生变更,或没有可信的历史 release state。流水线构建 image、更新 manifest 与 release state,然后由 Argo 收敛。
- `skip`source commit 已推进,但没有声明的 runtime path 发生变更。流水线不得构建 image、修改 GitOps branch 或触发 Argo rollout,应保留既有 runtime source commit 与 digest 作为 provenance。
- `disabled``delivery.enabled=false`。删除生成的 manifest 与 release state;这代表 service retirement,不是 `skip` 的同义词。
CLI、文档、issue metadata 与 `runtimePaths` 之外的其他文件必须得到 `IMAGE_STATUS=skipped`。成功 skip 仍应产生一条短 PaC PipelineRun 作为 source-observation 证据,但应跳过 image build 与 GitOps publication。默认 `status` 必须校验保留的 digest、GitOps revision、Argo state、runtime readiness 与 health,不得强制 runtime source commit 等于更新的非 runtime source commit;兼容 `closeout` 只能复用同一只读证据。
缺少 reuse 文本不能证明 reuse path 失败,应先核对 consumer type 与 PipelineRun 详情。