refactor: make Gitea the sole CI authority

This commit is contained in:
pikastech
2026-07-21 17:18:48 +02:00
parent 1115f134fd
commit 5115460df2
23 changed files with 337 additions and 214 deletions
+11 -9
View File
@@ -2,7 +2,7 @@
name: unidesk-cicd
description: >-
UniDesk CI/CD 控制面,覆盖 PaC consumer 首发 bootstrap、Tekton/Argo、GitOps、
git-mirror、L2/L3 手动计划发布、Secret、observability、CI tools image、PipelineRun 清理、
Gitea 单一 source authority、L2/L3 手动计划发布、Secret、observability、CI tools image、PipelineRun 清理、
Tekton 大对象与 Kine/SQLite 控制面退化、AgentRun 与 HWLAB 部署,
以及 branch-follower 退役只读诊断。
用户提到 CI/CD、deploy、rollout、PipelineRun、PaC、bootstrap、GitOps、Tekton、
@@ -14,7 +14,7 @@ description: >-
# UniDesk CI/CD
HWLAB G14 和 AgentRun CI/CD 的受控入口。任何 PR 监控、Tekton/Argo、git-mirror、Secret、observability、CI tools image、PipelineRun 清理或 AgentRun 部署都必须走 `bun scripts/cli.ts`
HWLAB G14 和 AgentRun CI/CD 的受控入口。任何 PR 监控、Tekton/Argo、Gitea source authority、Secret、observability、CI tools image、PipelineRun 清理或 AgentRun 部署都必须走 `bun scripts/cli.ts`
- `$unidesk-devlevel` 用 L2 Development 和 L3 Production 描述两种集群部署方式:
- 本 skill 负责这两种方式的手动计划发布、运行面操作和事故处理;
@@ -41,7 +41,6 @@ bun scripts/cli.ts cicd status --node <NODE>
bun scripts/cli.ts hwlab g14 monitor-prs --lane v02 --once --dry-run
bun scripts/cli.ts hwlab g14 control-plane status --lane v02
bun scripts/cli.ts hwlab nodes control-plane status --node NC01 --lane v03 --json
bun scripts/cli.ts hwlab g14 git-mirror status --lane v02
bun scripts/cli.ts agentrun control-plane status
bun scripts/cli.ts platform-infra gitea mirror status --target JD01
bun scripts/cli.ts platform-infra gitea mirror webhook status --target JD01
@@ -166,7 +165,7 @@ bun scripts/cli.ts hwlab nodes control-plane legacy-cicd --help
- PR monitor 与自动合并: [references/pr-monitor.md](references/pr-monitor.md)。
- Tekton/Argo、node-scoped runtime lane、D601 infra bootstrap: [references/control-plane.md](references/control-plane.md)。
- HWLAB/AgentRun legacy git-mirror source authority 与 flush: [references/git-mirror.md](references/git-mirror.md)。
- legacy git-mirror 退役状态与清理边界: [references/git-mirror.md](references/git-mirror.md)。
- JD01/NC01 Gitea mirror + Pipelines-as-Code 正式架构、三 consumer 覆盖矩阵、target 级 webhook path 和旧入口处置: [references/gitea-pac.md](references/gitea-pac.md)。
- AgentRun/HWLAB env reuse 机制、证据解释和 PaC status/history 观察口径: [references/env-reuse.md](references/env-reuse.md)。
- Secret、observability、platform-infra、CI tools image、PipelineRun 清理和 rollout 补记: [references/platform-ops.md](references/platform-ops.md)。
@@ -294,12 +293,15 @@ bun scripts/cli.ts hwlab nodes control-plane legacy-cicd --help
- warning 必须保留对象、配置路径、错误码和修复入口,但不得改变交付成功终态、跳过业务功能、写回配置或触发补救 mutation;
- 发现既有阻塞实例时逐例降级为 non-blocking warning,不以历史测试、旧门禁或旧合同继续阻止滚动;
- 当前选中对象缺少渲染必需输入、Secret/权限不成立、目标无法唯一解析或 mutation target 不安全时,仍在 mutation 前 fail-closed;这类损害预防不得扩展成全局配置一致性门禁。
- CI/CD source authority 只能来自 YAML 声明的 Kubernetes 托管 source authority
- legacy lane 由受控命令在 k8s 内同步并创建不可变 `refs/unidesk/snapshots/.../<commit>` stage ref
- Gitea/PaC migrated lane 由 GitHub PR merge 更新 GitHub webhook bridge、Gitea controlled mirror 与 immutable snapshot ref,禁止合并后人工同步或创建 snapshot;该 source 更新不触发 PipelineRun
- CI/CD source authority 只能来自 YAML 声明的 Gitea authority
- GitHub PR merge 只更新 GitHub webhook bridge、Gitea authority branch 与 immutable snapshot ref,禁止合并后人工同步或创建 snapshot;该 source 更新不触发 PipelineRun
- build/status/publish 只消费对应 snapshothost worktree、本地 `git fetch/pull`、可变 branch ref 或 Pipeline 内直连 GitHub 都不能作为 authoritative source。
- source branch、snapshot、GitOps branch、artifact catalog、Argo 和 runtime checkout 必须使用同一 Gitea repository
- CLI plan 与 Pipeline 必须从同一个 `gitops_read_url` 恢复 catalog
- promotion 只通过 YAML 声明的 Gitea SecretRef 写回同一仓库;
- 禁止 `git-mirror-http``git-mirror-write`、mirror cache、sync/flush Job、fallback 或第二 authority。
- CLI 必须组合 `config/platform-infra/gitea.yaml``config/platform-infra/pipelines-as-code.yaml`,按 consumer、node、lane、upstream repository、branch 和 Gitea repository 精确解析 delivery authority。不得用 URL 片段或 repo 专属条件判断迁移;当前选中对象零匹配或多匹配时返回 `unknown``mutation=false` 并在 mutation 前 fail-closed,非选中对象和全局一致性错误只进入 `blocking=false` warning。
- PaC 与 `unknown` authority 的 help、plan、status、失败态 `Next``REPAIR` 和实际执行 guard 都不得包含或执行 mutation command`trigger-current|refresh|sync|flush`在 YAML 精确解析为 `legacy-manual` 后进入旧实现,且只从 `legacy-cicd` / `legacy-ops` scoped help 发现;平台 bootstrap、Secret 与配置维护使用独立 scoped help,不得充当 source delivery recovery。
- PaC 与 `unknown` authority 的 help、plan、status、失败态 `Next``REPAIR` 和实际执行 guard 都不得包含或执行 legacy source mutation。`trigger-current|refresh|sync|flush`保留退役诊断,不得创建 Job 或写 ref;平台 bootstrap、Secret 与配置维护使用独立 scoped help,不得充当 source delivery recovery。
- JD01/NC01 `agentrun-<node>-v02``sentinel-<node>-v03``hwlab-<node>-v03` 在手动 webhook 后由 PaC/Tekton/GitOps 自动收敛并写入状态。仅在显式调查发布链故障时读取 `cicd status --node <NODE>``platform-infra pipelines-as-code status|history --target <NODE> --consumer <id>``cicd branch-follower``cicd gitea-actions-poc` 只保留历史/迁移只读用途。
- PaC `.tekton` 文件必须用 Repository CR 的 target/node 参数隔离 JD01/NC01,避免同一个 Gitea push 在一个 target cluster 内额外创建另一个 target 的 PipelineRun。`history --id` 必须按运行面 provenance 和实际 PipelineRun prefix 唯一归属 consumer;零匹配、多匹配或显式 consumer 不一致均 fail-closed,不得回退到默认 consumer 或默认 node。
- PaC source artifact 必须遵循以下边界:
@@ -446,7 +448,7 @@ bun scripts/cli.ts hwlab nodes control-plane legacy-cicd --help
- PR 自动合并、v0.2/v0.3 lane 差异:读 [references/pr-monitor.md](references/pr-monitor.md)。
- Legacy 手动触发、定点 PipelineRun/source commit、RBAC/Pipeline/Argo、node-scoped runtime lane:读 [references/control-plane.md](references/control-plane.md)。
- Legacy git-mirror source authority 或 flush:读 [references/git-mirror.md](references/git-mirror.md)。
- legacy git-mirror 退役核查:读 [references/git-mirror.md](references/git-mirror.md)。
- AgentRun/HWLAB env reuse、`IMAGE_STATUS=reused``ENV_REUSE=hit``skipped,skip=<n>` 或 PaC history/status 解释:读 [references/env-reuse.md](references/env-reuse.md)。
- JD01/NC01 Gitea+PaC 覆盖、旧 branch-follower/Gitea Actions POC 处置和只读观察顺序:读 [references/gitea-pac.md](references/gitea-pac.md)。
- Secret、observability、CI tools image、PipelineRun/PV 清理:读 [references/platform-ops.md](references/platform-ops.md)。
@@ -87,7 +87,7 @@ Use these interpretations:
- Sentinel `ENV_REUSE=hit`: node dependency directory was present and linked before verify/build.
- Sentinel `cache=hit`: BuildKit cache evidence, separate from dependency reuse.
- HWLAB v0.3 `skipped,skip=<n>` in PaC history: service-level artifact planning skipped builds for already reusable services; inspect the detail id before interpreting it as AgentRun-style image reuse.
- HWLAB v0.3 `env-reuse-git-mirror-checkout`: a `codeIdentity` change with unchanged `envIdentity` should mark the service as affected/rolled out while still skipping image build. Evidence is in `plan-artifacts` and `collect-artifacts`: `affectedServices` includes the service, `buildServices=[]`, the artifact has `ciAffected=true`, `ciReason` such as `code-input-changed`, a new `componentCommitId`/`codeInputHash`, and `publishState=reused` / `buildBackend=reused-env-catalog`. This is correct env reuse consumption, not a missed rebuild.
- HWLAB v0.3 `env-reuse-gitea-checkout`: a `codeIdentity` change with unchanged `envIdentity` should mark the service as affected/rolled out while still skipping image build. Evidence is in `plan-artifacts` and `collect-artifacts`: `affectedServices` includes the service, `buildServices=[]`, the artifact has `ciAffected=true`, `ciReason` such as `code-input-changed`, a new `componentCommitId`/`codeInputHash`, and `publishState=reused` / `buildBackend=reused-env-catalog`. This is correct env reuse consumption, not a missed rebuild.
- HWLAB v0.3 shared TS runtime env groups build one representative environment image and let compatible TS services consume that same artifact with different runtime checkout/entrypoint metadata. A semantic env identity change, such as dependency maps, `engines`, `packageManager`, `overrides`, `resolutions`, `type`, or env launcher inputs, should schedule the representative build service; consumer services should keep shared artifact provenance and skip individual image builds.
- HWLAB v0.3 non-reuse image build is expected when `envIdentity` changes, such as shared dependency or env launcher inputs. Then `buildServices` should include services whose environment identity changed and build TaskRuns should be present.
- HWLAB v0.3 treats `package.json` env identity semantically. Arbitrary top-level metadata fields do not count; meaningful env inputs include dependency maps, `overrides`, `resolutions`, `engines`, `packageManager`, and `type`. Use one of those fields when deliberately testing non-reuse behavior.
@@ -1,42 +1,23 @@
# Git Mirror Authority
# Legacy Git Mirror 退役
## 默认只读入口
`git-mirror-http``git-mirror-write`、mirror cache、sync/flush Job 和相关 Secret 已退出 CI/CD 运行架构。它们不得作为 source cache、GitOps write endpoint、故障 fallback 或第二 authority 保留。
Gitea/PaC migrated consumer 的 mirror、authority branch 与 immutable snapshot 由 GitHub PR merge 更新;GitOps publication 只在手动 plan/trigger 后发生。默认只允许读取:
## 稳定规则
- source branch、immutable snapshot、GitOps branch、artifact catalog、Argo 和 runtime checkout 统一使用 owning YAML 声明的 Gitea repository。
- CLI `release plan` 与 Pipeline 内 planner 必须使用同一个 `gitops_read_url`
- GitOps promotion 必须通过 Gitea SecretRef 写回同一仓库,不得恢复匿名 mirror write 或 SSH fallback。
- 历史 `git-mirror status|sync|flush|trigger-current` 只允许返回退役诊断,不得创建 Job、写 ref 或重建 runtime。
- 运行面仍存在 legacy 对象时,先确认活跃 consumer 已无引用,再执行:
```bash
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 hwlab nodes git-mirror status --node <NODE> --lane <lane>
bun scripts/cli.ts agentrun git-mirror status --node <NODE> --lane <lane>
bun scripts/cli.ts hwlab nodes control-plane infra source-authority retire-legacy-runtime --node <NODE> --lane <lane> --dry-run
bun scripts/cli.ts hwlab nodes control-plane infra source-authority retire-legacy-runtime --node <NODE> --lane <lane> --confirm
```
已迁移或 `unknown` authority 必须在远端调用或异步 Job 创建前 fail-closed。状态和失败 `Next` 只能指向 status/history 与自动链修复引用,不得建议 mirror sync/flush、直接 Gitea push、host git、fixed workspace 或第二套 source resolver
- 受控退役只删除 owning YAML 精确命名的旧 Deployment、Service、ConfigMap、PVC、Secret 与同步/flush Job;不得修改 Pipeline、PipelineRun、Argo、registry 或业务 workload
- status 对 Gitea authority 的正确终态是 `legacySourceRuntimeEnabled=false``legacySourceRuntimeAbsent=true`
发布链故障必须修 `config/platform-infra/gitea.yaml``config/platform-infra/pipelines-as-code.yaml`、planner、webhook bridge、受控 mirror worker 或源码,并通过修复 PR 合并后的 plan 与手动 webhook 验收。不得使用 branch-follower、裸建 PipelineRun 或 legacy mirror mutation 补齐当前交付。
## 故障处理
## Legacy scope
Git mirror mutation 只属于 owning YAML 精确解析为 `legacy-manual` 的 lane,并且只能从显式 scoped help 发现:
```bash
bun scripts/cli.ts hwlab nodes git-mirror legacy-ops --help
bun scripts/cli.ts agentrun git-mirror legacy-ops --help
```
Legacy scope 仍须遵守:
- source selection 只使用 YAML 声明的 immutable snapshot,不读取 host worktree、`.worktree/*` 或可变 branch ref
- GitHub transport、proxy、Secret sourceRef 与 snapshot prefix 全部来自 owning YAML
- `sync``flush` 与 apply 只服务明确 legacy lane,不能作为 PaC 恢复手段;
- 验收使用只读 status 证明 mirror、GitOps、Argo、runtime 与目标 source commit 对齐,不能只看 PipelineRun terminal。
## 退役状态清理
Branch-follower 已退役。旧状态清理不属于 mirror 自动链,也不使用默认 `cleanup-state`。确需清理时使用 `cicd branch-follower retired-maintenance --help` 中的受控入口;固定 canonical owning YAML,先列候选,再显式确认。
## D601 legacy transport
D601 legacy lane 的 GitHub upstream transport 由 YAML 固定为 SSH over `ssh.github.com:443`HTTP proxy 仅承担 SSH CONNECT。输出若漂移为 HTTPS token、host env 或未声明 transport,修 owning YAML 和平台配置,不增加 fallback。
Legacy mirror status 中的 GitHub 字段可能来自 `refs/mirror-stage/...` cache,必须标记来源。push 已成功但 post-push fetch 因 transient 失败时,CLI 可以在同一个 legacy 受控实现内做一次有界 recheck;这项行为不得复制到 migrated PaC consumer 的 operator Next。
Gitea source 或 GitOps 链故障只能修 `config/platform-infra/gitea.yaml``config/platform-infra/pipelines-as-code.yaml`、对应 owning YAML、controller、planner 或 Pipeline。修复后重新执行 `release plan`,范围准确时只发送一次手动 webhook。禁止用 mirror sync、flush、直接 Gitea push、裸建 PipelineRun 或 Argo sync 补齐交付。
@@ -37,7 +37,7 @@ GitHub 是唯一上游写入权威。目标 source branch 的 GitHub PR merge
- 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 实现。
- 旧 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 公网入口:
+22 -1
View File
@@ -14,7 +14,7 @@ spec:
timeouts:
pipeline: 600s
taskRunTemplate:
serviceAccountName: default
serviceAccountName: platform-infra-temporal-nc01-tekton-runner
podTemplate:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
@@ -28,6 +28,12 @@ spec:
- name: workspace
emptyDir:
sizeLimit: 1Gi
- name: gitea-auth
secret:
secretName: pac-gitea-sentinel-nc01-v03
items:
- key: token
path: token
steps:
- name: publish-gitops
image: 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
@@ -41,6 +47,18 @@ spec:
script: |
#!/bin/sh
set -eu
askpass=/workspace/gitea-askpass.sh
trap 'rm -f "$askpass"' EXIT
cat >"$askpass" <<'ASKPASS'
#!/bin/sh
case "$1" in
*Username*) printf '%s\n' "${GITEA_USERNAME:?}" ;;
*Password*) cat /workspace/gitea-auth/token ;;
*) exit 1 ;;
esac
ASKPASS
chmod 700 "$askpass"
export GITEA_USERNAME=unidesk-admin GIT_ASKPASS="$askpass" GIT_ASKPASS_REQUIRE=force GIT_TERMINAL_PROMPT=0
git clone --filter=blob:none --no-checkout http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git source
cd source
git fetch --depth=1 --filter=blob:none origin "+$SOURCE_SNAPSHOT_PREFIX/$SOURCE_COMMIT:refs/remotes/origin/unidesk-source-snapshot"
@@ -53,3 +71,6 @@ spec:
volumeMounts:
- name: workspace
mountPath: /workspace
- name: gitea-auth
mountPath: /workspace/gitea-auth
readOnly: true
+38 -1
View File
@@ -14,7 +14,7 @@ spec:
timeouts:
pipeline: 3600s
taskRunTemplate:
serviceAccountName: default
serviceAccountName: unidesk-host-tekton-runner
podTemplate:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
@@ -28,6 +28,12 @@ spec:
- name: workspace
emptyDir:
sizeLimit: 4Gi
- name: gitea-auth
secret:
secretName: pac-gitea-sentinel-nc01-v03
items:
- key: token
path: token
- name: buildkit-state
emptyDir:
sizeLimit: 4Gi
@@ -46,6 +52,18 @@ spec:
script: |
#!/bin/sh
set -eu
askpass=/workspace/gitea-askpass.sh
trap 'rm -f "$askpass"' EXIT
cat >"$askpass" <<'ASKPASS'
#!/bin/sh
case "$1" in
*Username*) printf '%s\n' "${GITEA_USERNAME:?}" ;;
*Password*) cat /workspace/gitea-auth/token ;;
*) exit 1 ;;
esac
ASKPASS
chmod 700 "$askpass"
export GITEA_USERNAME=unidesk-admin GIT_ASKPASS="$askpass" GIT_ASKPASS_REQUIRE=force GIT_TERMINAL_PROMPT=0
rm -rf source release
git clone --filter=blob:none --no-checkout http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git source
cd source
@@ -61,6 +79,9 @@ spec:
volumeMounts:
- name: workspace
mountPath: /workspace
- name: gitea-auth
mountPath: /workspace/gitea-auth
readOnly: true
- name: prepare-buildkit-state
image: 127.0.0.1:5000/hwlab/hwlab-ci-node-tools:node22-alpine-bun-v1
imagePullPolicy: IfNotPresent
@@ -107,6 +128,19 @@ spec:
value: "{{revision}}"
script: |
#!/bin/sh
set -eu
askpass=/workspace/gitea-askpass.sh
trap 'rm -f "$askpass"' EXIT
cat >"$askpass" <<'ASKPASS'
#!/bin/sh
case "$1" in
*Username*) printf '%s\n' "${GITEA_USERNAME:?}" ;;
*Password*) cat /workspace/gitea-auth/token ;;
*) exit 1 ;;
esac
ASKPASS
chmod 700 "$askpass"
export GITEA_USERNAME=unidesk-admin GIT_ASKPASS="$askpass" GIT_ASKPASS_REQUIRE=force GIT_TERMINAL_PROMPT=0
exec bun /workspace/source/scripts/native/cicd/publish-unidesk-host-gitops.mjs \
--config /workspace/source/config/unidesk-host-k8s.yaml \
--source-root /workspace/source \
@@ -117,3 +151,6 @@ spec:
volumeMounts:
- name: workspace
mountPath: /workspace
- name: gitea-auth
mountPath: /workspace/gitea-auth
readOnly: true
+1 -1
View File
@@ -28,7 +28,7 @@ status:
argo: true
runtime: true
public: true
git-mirror: true
git-mirror: false
publicExposures:
NC01:
v03:
+8 -7
View File
@@ -24,15 +24,16 @@ lanes:
version: v0.3
sourceBranch: v0.3
sourceAuthority:
mode: gitMirrorSnapshot
resolver: k8s-git-mirror
mode: giteaSnapshot
resolver: gitea-mirror
giteaMirrorRepoKey: hwlab-nc01-v03
allowHostGit: false
allowHostWorkspace: false
allowGithubDirectInPipeline: false
sourceSnapshot:
stageRefPrefix: "refs/unidesk/snapshots/hwlab-node-runtime/{branch}"
missingObjectPolicy: fail-fast
refreshPolicy: sync-before-snapshot
refreshPolicy: gitea-controlled-snapshot
workspace: /root/hwlab-v03
cicdRepo: /root/hwlab-v03-cicd.git
cicdRepoLock: /tmp/hwlab-v03-cicd-repo.lock
@@ -43,8 +44,8 @@ lanes:
controlPlaneFieldManager: unidesk-hwlab-v03-control-plane
git:
url: git@github.com:pikasTech/HWLAB.git
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local/pikasTech/HWLAB.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
gitopsBranch: v0.3-gitops
catalogPath: deploy/artifact-catalog.v03.json
runtime:
@@ -306,9 +307,9 @@ lanes:
git:
url: git@github.com:pikasTech/HWLAB.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
argo:
repoURL: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
repoURL: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
gitopsBranch: v0.3-gitops
catalogPath: deploy/artifact-catalog.nc01-v03.json
runtime:
+18 -63
View File
@@ -158,8 +158,8 @@ sourceAuthority:
gitOpsDelivery:
enabled: true
targetId: NC01
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
branch: unidesk-host-gitops
sourceSnapshotPrefix: refs/unidesk/snapshots/gitea-actions/unidesk-master-nc01
desiredManifestPath: deploy/gitops/platform-infra/gitea-nc01/resources.yaml
@@ -169,7 +169,7 @@ sourceAuthority:
name: platform-infra-gitea-nc01
namespace: argocd
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
path: deploy/gitops/platform-infra/gitea-nc01
destinationNamespace: devops-infra
@@ -194,8 +194,8 @@ sourceAuthority:
disposition: replaced-by-gitea
- name: gitops-flush
current: legacy-git-mirror
target: github-direct-or-gitea-writeback
disposition: retained-for-gitops-flush
target: gitea-writeback
disposition: replaced-by-gitea
- name: legacy-status
current: branch-follower-status
target: gitea-mirror-status
@@ -215,14 +215,11 @@ sourceAuthority:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-agentrun.git
gitops:
branch: jd01-v0.2-gitops
flushDisposition: retained-for-gitops-flush
flushDisposition: gitea-writeback
snapshot:
naming: historical-gitea-actions-prefix-retained-for-existing-refs
prefix: refs/unidesk/snapshots/gitea-actions/agentrun-v0.2
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/agentrun.git
configRef: config/cicd-branch-followers.yaml#followers.agentrun-jd01-v02.nativeStatus.source.gitMirrorReadUrl
disposition: replaced-by-gitea
legacyGitMirror: null
- key: agentrun-nc01-v02
targetId: NC01
upstream:
@@ -237,14 +234,11 @@ sourceAuthority:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-agentrun.git
gitops:
branch: nc01-v0.2-gitops
flushDisposition: retained-for-gitops-flush
flushDisposition: gitea-writeback
snapshot:
naming: historical-gitea-actions-prefix-retained-for-existing-refs
prefix: refs/unidesk/snapshots/gitea-actions/agentrun-v0.2
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/agentrun.git
configRef: config/cicd-branch-followers.yaml#followers.agentrun-nc01-v02.nativeStatus.source.gitMirrorReadUrl
disposition: replaced-by-gitea
legacyGitMirror: null
- key: agentrun-nc01-release
targetId: NC01
upstream:
@@ -259,13 +253,11 @@ sourceAuthority:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-agentrun.git
gitops:
branch: nc01-release-gitops
flushDisposition: retained-for-gitops-flush
flushDisposition: gitea-writeback
snapshot:
naming: agentrun-release-prefix
prefix: refs/unidesk/snapshots/gitea-actions/agentrun-release
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/agentrun.git
disposition: replaced-by-gitea
legacyGitMirror: null
- key: unidesk-master
targetId: JD01
upstream:
@@ -284,10 +276,7 @@ sourceAuthority:
snapshot:
naming: historical-gitea-actions-prefix-retained-for-existing-refs
prefix: refs/unidesk/snapshots/gitea-actions/unidesk-master
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
configRef: config/cicd-branch-followers.yaml#controller.source.gitMirrorReadUrl
disposition: replaced-by-gitea
legacyGitMirror: null
- key: unidesk-master-nc01
targetId: NC01
upstream:
@@ -306,10 +295,7 @@ sourceAuthority:
snapshot:
naming: historical-gitea-actions-prefix-retained-for-existing-refs
prefix: refs/unidesk/snapshots/gitea-actions/unidesk-master-nc01
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
configRef: config/cicd-branch-followers.yaml#controller.source.gitMirrorReadUrl
disposition: replaced-by-gitea
legacyGitMirror: null
- key: sub2rank-nc01
targetId: NC01
upstream:
@@ -328,10 +314,7 @@ sourceAuthority:
snapshot:
naming: application-source-snapshot
prefix: refs/unidesk/snapshots/gitea-actions/apistate-master-nc01
legacyGitMirror:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-apistate.git
configRef: config/platform-infra/sub2rank.yaml#application.remote
disposition: replaced-by-gitea
legacyGitMirror: null
- key: sub2rank-development-nc01
targetId: NC01
upstream:
@@ -397,28 +380,6 @@ sourceAuthority:
naming: application-source-snapshot
prefix: refs/unidesk/snapshots/gitea-actions/hwpod-home-main-nc01
legacyGitMirror: null
- key: hwlab-jd01-v03
targetId: JD01
upstream:
repository: pikasTech/HWLAB
cloneUrl: https://github.com/pikasTech/HWLAB.git
branch: v0.3
gitea:
owner: mirrors
name: pikasTech-HWLAB
mirrorMode: controlled-push
publicRead: true
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
gitops:
branch: v0.3-gitops
flushDisposition: retained-for-gitops-flush
snapshot:
naming: historical-gitea-actions-prefix-retained-for-existing-refs
prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/v0.3
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
configRef: config/hwlab-node-lanes.yaml#lanes.v03.targets.JD01.git.readUrl
disposition: replaced-by-gitea
- key: hwlab-nc01-v03
targetId: NC01
upstream:
@@ -433,14 +394,11 @@ sourceAuthority:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
gitops:
branch: v0.3-gitops
flushDisposition: retained-for-gitops-flush
flushDisposition: gitea-writeback
snapshot:
naming: historical-gitea-actions-prefix-retained-for-existing-refs
prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/v0.3
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
configRef: config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01.git.readUrl
disposition: replaced-by-gitea
legacyGitMirror: null
- key: hwlab-nc01-production
targetId: NC01
upstream:
@@ -455,14 +413,11 @@ sourceAuthority:
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
gitops:
branch: release-gitops
flushDisposition: retained-for-gitops-flush
flushDisposition: gitea-writeback
snapshot:
naming: gitea-actions-immutable-source
prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/release
legacyGitMirror:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
configRef: config/hwlab-node-lanes.yaml#lanes.production.targets.NC01.git.readUrl
disposition: replaced-by-gitea
legacyGitMirror: null
- key: selfmedia-nc01
targetId: NC01
credentialOverride:
+2 -2
View File
@@ -50,8 +50,8 @@ delivery:
- hyueapi.com
- .hyueapi.com
gitops:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
branch: unidesk-host-gitops
manifestPath: deploy/gitops/platform-infra/hwpod-home-nc01/resources.yaml
releaseStatePath: deploy/gitops-state/platform-infra/hwpod-home-nc01.json
+51 -28
View File
@@ -275,11 +275,6 @@ repositories:
runtime_service_port: "8080"
health_path: /healthz
health_url: http://hwpod-home.hwpod-home.svc.cluster.local:8080/healthz
- extends: templates.repositories.hwlabV03
variables:
NODE: JD01
LANE: v03
url: https://gitea.hwpod.com/mirrors/pikasTech-HWLAB
- extends: templates.repositories.hwlabV03
variables:
NODE: NC01
@@ -478,15 +473,27 @@ consumers:
argoApplication: unidesk-host
deliveryObservation:
runtimeEvidence: required
closeoutGitOpsMirrorFlush: true
closeoutGitOpsMirrorFlush: false
closeoutGitOpsMirrorLane: v03
params:
gitops_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
gitops_write_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
gitops_username: unidesk-admin
gitops_secret_name: pac-gitea-sentinel-nc01-v03
runnerServiceAccount:
name: unidesk-host-tekton-runner
automountServiceAccountToken: false
roleBindingName: unidesk-host-tekton-runner
argoBootstrap:
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
path: deploy/gitops/unidesk-host
destinationNamespace: unidesk
automated: true
repositoryCredential:
secretName: argocd-repo-unidesk-host
username: unidesk-admin
- id: platform-infra-temporal-nc01
repositoryRef: sentinel-nc01-v03
node: NC01
@@ -498,7 +505,7 @@ consumers:
argoApplication: platform-infra-temporal-nc01
deliveryObservation:
runtimeEvidence: required
closeoutGitOpsMirrorFlush: true
closeoutGitOpsMirrorFlush: false
closeoutGitOpsMirrorLane: v03
materializationOnly: true
materializationPaths:
@@ -507,16 +514,27 @@ consumers:
- scripts/native/cicd/publish-platform-infra-temporal-gitops.ts
- .tekton/platform-infra-temporal-nc01-pac.yaml
params:
gitops_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
gitops_write_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
gitops_username: unidesk-admin
gitops_secret_name: pac-gitea-sentinel-nc01-v03
runtime_deployment: temporal
gitops_branch: temporal-nc01-gitops
gitops_manifest_path: deploy/gitops/platform-infra/temporal-nc01/resources.yaml
runnerServiceAccount:
name: platform-infra-temporal-nc01-tekton-runner
automountServiceAccountToken: false
roleBindingName: platform-infra-temporal-nc01-tekton-runner
argoBootstrap:
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: temporal-nc01-gitops
path: deploy/gitops/platform-infra/temporal-nc01
destinationNamespace: temporal
automated: true
repositoryCredential:
secretName: argocd-repo-platform-infra-temporal-nc01
username: unidesk-admin
- id: platform-infra-gitea-nc01
repositoryRef: sentinel-nc01-v03
node: NC01
@@ -540,11 +558,11 @@ consumers:
argoApplication: sub2rank-nc01
deliveryObservation:
runtimeEvidence: required
closeoutGitOpsMirrorFlush: true
closeoutGitOpsMirrorFlush: false
closeoutGitOpsMirrorLane: v03
argoBootstrap:
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
path: deploy/gitops/platform-infra/sub2rank-nc01
destinationNamespace: platform-infra
@@ -554,7 +572,7 @@ consumers:
markerValue: admission-pac-v2:platform-infra-sub2rank-nc01
executionServiceAccountName: sub2rank-nc01-tekton-runner
gitOps:
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
runnerServiceAccount:
name: sub2rank-nc01-tekton-runner
@@ -584,7 +602,7 @@ consumers:
closeoutGitOpsMirrorFlush: false
argoBootstrap:
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
path: deploy/gitops/platform-infra/sub2rank-development-nc01
destinationNamespace: platform-infra-development
@@ -594,7 +612,7 @@ consumers:
markerValue: admission-pac-v2:platform-infra-sub2rank-development-nc01
executionServiceAccountName: sub2rank-development-nc01-tekton-runner
gitOps:
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
runnerServiceAccount:
name: sub2rank-development-nc01-tekton-runner
@@ -621,11 +639,11 @@ consumers:
argoApplication: hwpod-home-nc01
deliveryObservation:
runtimeEvidence: required
closeoutGitOpsMirrorFlush: true
closeoutGitOpsMirrorFlush: false
closeoutGitOpsMirrorLane: v03
argoBootstrap:
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
path: deploy/gitops/platform-infra/hwpod-home-nc01
destinationNamespace: hwpod-home
@@ -635,7 +653,7 @@ consumers:
markerValue: admission-pac-v2:platform-infra-hwpod-home-nc01
executionServiceAccountName: hwpod-home-nc01-tekton-runner
gitOps:
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
runnerServiceAccount:
name: hwpod-home-nc01-tekton-runner
@@ -651,10 +669,6 @@ consumers:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
fsGroup: 1000
- extends: templates.consumers.hwlabV03
variables:
NODE: JD01
LANE: v03
- extends: templates.consumers.hwlabV03
variables:
NODE: NC01
@@ -912,7 +926,7 @@ consumers:
closeoutGitOpsMirrorFlush: false
argoBootstrap:
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
path: deploy/gitops/platform-infra/superapi-development-nc01
destinationNamespace: superapi-development
@@ -946,7 +960,7 @@ consumers:
health_url: http://superapi-gateway.superapi-production.svc.cluster.local:8080/health
argoBootstrap:
project: default
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
targetRevision: unidesk-host-gitops
path: deploy/gitops/platform-infra/superapi-production-nc01
destinationNamespace: superapi-production
@@ -1030,8 +1044,10 @@ templates:
concurrencyLimit: 1
params:
git_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
git_write_url: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
gitops_read_url: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
git_write_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
gitops_read_url: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
gitops_username: unidesk-admin
gitops_secret_name: "pac-gitea-hwlab-${nodeLower}-v03"
source_branch: v0.3
gitops_branch: v0.3-gitops
source_snapshot_prefix: refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/v0.3
@@ -1094,7 +1110,7 @@ templates:
argoApplication: "hwlab-web-probe-sentinel-${nodeLower}"
deliveryObservation:
runtimeEvidence: required
closeoutGitOpsMirrorFlush: true
closeoutGitOpsMirrorFlush: false
closeoutGitOpsMirrorLane: v03
hwlabV03:
id: "hwlab-${nodeLower}-v03"
@@ -1108,11 +1124,18 @@ templates:
argoApplication: hwlab-node-v03
deliveryObservation:
runtimeEvidence: required
closeoutGitOpsMirrorFlush: true
closeoutGitOpsMirrorFlush: false
runnerServiceAccount:
name: "hwlab-${nodeLower}-v03-tekton-runner"
automountServiceAccountToken: false
roleBindingName: "hwlab-${nodeLower}-v03-tekton-runner"
argoBootstrap:
project: hwlab-v03
repoUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
repoUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
targetRevision: v0.3-gitops
path: "deploy/gitops/node/${nodeLower}/runtime-v03"
destinationNamespace: hwlab-v03
automated: true
repositoryCredential:
secretName: "argocd-repo-hwlab-${nodeLower}-v03"
username: unidesk-admin
+4 -4
View File
@@ -94,8 +94,8 @@ delivery:
- hyueapi.com
- .hyueapi.com
gitops:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
branch: unidesk-host-gitops
manifestPath: deploy/gitops/platform-infra/sub2rank-nc01/resources.yaml
releaseStatePath: deploy/gitops-state/platform-infra/sub2rank-nc01.json
@@ -125,8 +125,8 @@ delivery:
buildkitImage: 127.0.0.1:5000/hwlab/buildkit:rootless
sourceSnapshotPrefix: refs/unidesk/snapshots/gitea-actions/apistate-development-nc01
gitops:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
branch: unidesk-host-gitops
manifestPath: deploy/gitops/platform-infra/sub2rank-development-nc01/resources.yaml
releaseStatePath: deploy/gitops-state/platform-infra/sub2rank-development-nc01.json
+6 -2
View File
@@ -37,8 +37,12 @@ delivery:
serviceAccount: default
timeout: 600s
gitops:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
auth:
username: unidesk-admin
secretName: pac-gitea-sentinel-nc01-v03
tokenKey: token
branch: temporal-nc01-gitops
path: deploy/gitops/platform-infra/temporal-nc01
manifestPath: deploy/gitops/platform-infra/temporal-nc01/resources.yaml
+6 -2
View File
@@ -64,8 +64,12 @@ delivery:
- .svc.cluster.local
- .cluster.local
gitops:
readUrl: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/unidesk.git
readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
writeUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-unidesk.git
auth:
username: unidesk-admin
secretName: pac-gitea-sentinel-nc01-v03
tokenKey: token
branch: unidesk-host-gitops
resources:
- id: hwlab-nc01-v03-runtime-gitops-scripts
+9 -1
View File
@@ -190,6 +190,14 @@
## Gitea 与 Pipelines-as-Code 边界
- Gitea 是平台运行时唯一 Git authority
- source branch、immutable snapshot、GitOps branch、artifact catalog、Argo 和 runtime checkout 必须解析到同一 Gitea repository
- CLI plan 与 Pipeline 必须使用同一个 owning YAML `gitops_read_url`
- GitOps promotion 通过 Gitea SecretRef 写回该仓库,不得使用匿名写入、SSH fallback 或第二 remote
- `git-mirror-http``git-mirror-write`、mirror cache、sync/flush Job 和相关 Secret 已退役,不得被 renderer、status 或恢复流程重建;
- 删除遗留 runtime 前先确认所有活跃 consumer 的 read/write/Argo URL 已指向 Gitea,再走 YAML 受控退役入口;
- 故障只能修 owning YAML、Gitea controller、planner 或 Pipeline,然后重新 plan,禁止恢复 legacy runtime。
- Gitea mirror 与 Pipelines-as-Code 是 UniDesk 运维的 CI source/trigger 服务:
- `config/platform-infra/gitea.yaml` 拥有 mirror、webhook 与 NC01 public-edge 暴露;
- `config/platform-infra/pipelines-as-code.yaml` 拥有 PaC Repository 与 consumer 配置;
@@ -207,7 +215,7 @@
- 成立的变化必须写回 owning YAML/源码,经正常 PR 合并后重新 plan,并通过受控手动 webhook 交付;
- 临时 patch 随后撤销或由声明式交付覆盖。
- Migrated consumer 的默认 help、status、`Next``REPAIR` 只能给 `status``history``events``logs`、只读单步下钻以及本节稳定引用。CLI 必须省略 mutation command,而不是只给命令加警告文字。`unknown` authority 同样 fail-closed。
- 旧 `trigger-current``refresh` 和 mirror `sync|flush` 只允许在 owning YAML 明确解析为 `legacy-manual` 后执行,并且只在显式 `legacy-cicd``legacy-ops` scoped help 中可发现。平台 bootstrap、Secret 与配置维护属于独立职责,只在 `platform-bootstrap``platform-maintenance` scoped help 中展示,不能作为 source delivery recovery。
- 旧 `trigger-current``refresh` 和 mirror `sync|flush` 已退役,只能返回只读诊断,不得创建 Job、写 ref 或重建 runtime。平台 bootstrap、Secret 与配置维护属于独立职责,只在 `platform-bootstrap``platform-maintenance` scoped help 中展示,不能作为 source delivery recovery。
- `closeout` 仅保留只读历史/诊断兼容入口,并且只能从 `compatibility-diagnostics` scoped help 发现。会 POST hook test 的 `webhook-test` mutation 入口已经删除;连通性只能通过真正只读的 status、GET 与 readiness 观察,禁止制造伪 push。
- 默认 Gitea webhook 观察入口是 `bun scripts/cli.ts platform-infra gitea mirror webhook status --target <node>`。它应显示 hook readiness、GitHub head、Gitea branch/snapshot、最近 delivery 与 bridge event;状态陈旧时只能给只读下钻和“修复自动链”指引,不得输出人工 `REPAIR`
- GitHub webhook receiver 只有在验签 delivery 通过 fsync 与 atomic rename 写入 YAML 声明的 PVC durable inbox 后才能返回 HTTP `202 Accepted`。状态必须分为 `accepted``processing``committed``failed``202 Accepted` 只证明持久接收,不证明 refs 已提交。只有同一 deliveryId 的 exact-after immutable snapshot 与 authority branch 经 atomic push 后重新读取 refs 证明一致,才能进入 `committed`
@@ -23,7 +23,7 @@
| 上级规格 | [PJ2026-0106 平台运维](PJ2026-0106-platform-ops.md) |
| 规格治理索引 | [规格治理](spec-governance.md) |
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 Git mirror、source commit authority、GitOps 分支、artifact catalog、bundle/mirror URL 和运行面源码真相的通用稳定使命、范围、术语、系统边界、内部分工和原子需求。
本文采用 ISO/IEC/IEEE 29148 需求规格模板的项目裁剪版:正文只保留 Gitea source authority、source commit、GitOps 分支、artifact catalog、bundle URL 和运行面源码真相的通用稳定使命、范围、术语、系统边界、内部分工和原子需求。
## 2. 目的和范围
@@ -33,11 +33,11 @@
### 2.2 范围内
- G14、D601 和平台运行面使用的 Git mirror read/write URL、mirror cache、source branch 和固定 worktree 规则。
- Gitea source/GitOps read-write URL、source branch 和固定 worktree 规则。
- HWLAB 各服务的 source branch、source worktree、GitOps branch、artifact catalog 和 runtime path 的通用 source truth 关系。
- RuntimeAssembly `ResourceBundleRef.kind="gitbundle"` 所需的 repo URL、ref、actual commitbundle 摘要和 mirror 改写边界
- RuntimeAssembly `ResourceBundleRef.kind="gitbundle"` 所需的 Gitea repo URL、ref、actual commitbundle 摘要。
- GitOps desired state 与 source branch 分离,promotion 只写 artifact catalog 和 rendered manifests,不把运行副本变成源码真相。
- 运行面、CLI 和发布输出中的 source revision、artifact catalog、bundle/mirror URL 和 commit 摘要可见性。
- 运行面、CLI 和发布输出中的 source revision、artifact catalog、Gitea URL 和 commit 摘要可见性。
### 2.3 范围外
@@ -52,7 +52,7 @@
| 术语 | 定义 |
| --- | --- |
| source truth | 某服务或资源装配的权威 Git 来源,包括 repo URL、branch/ref、commit 和必要的 GitOps artifact。 |
| Git mirror | 为目标运行面提供 Git read/write 缓存和 source sync 的平台基础设施。 |
| Gitea authority | 为 source branch、GitOps branch、artifact catalog 和运行时 checkout 提供唯一 read/write Git 真相的受控 Gitea 仓库。 |
| source worktree | 固定在目标节点上的 source branch 工作区,只作为预检、同步和直接轻量文档交付入口。 |
| GitOps branch | 与 source branch 分离的 desired state 分支,只保存渲染后运行面资源和 artifact catalog。 |
| artifact catalog | 记录 image、env identity、source commit、runtime path 和 manifest 摘要的发布产物索引。 |
@@ -66,35 +66,39 @@
| 边界项 | 内容 |
| --- | --- |
| 外部使用者 | 发布流水、Runtime装配、agent runner、服务维护者、平台运维 CLI 和业务模块。 |
| 外部输入 | Git remote、source branch、requested ref、commitId、GitOps branch、bundle paths、mirror target、promotion 请求和 source status 查询。 |
| 受控资源 | Git mirror、source worktree、GitOps branch、artifact catalog、gitbundle checkoutactual commit 摘要和 bundle/mirror URL。 |
| 外部输出 | source revision、mirror URL、actual commit、tree/bundle 摘要、artifact catalog path、GitOps revision 和 source sync 状态。 |
| 外部输入 | Git remote、source branch、requested ref、commitId、GitOps branch、bundle paths、Gitea target、promotion 请求和 source status 查询。 |
| 受控资源 | Gitea repository、source worktree、GitOps branch、artifact catalog、gitbundle checkoutactual commit 摘要。 |
| 外部输出 | source revision、Gitea URL、actual commit、tree/bundle 摘要、artifact catalog path、GitOps revision 和 source sync 状态。 |
| 用户接口 | UniDesk CLI、服务自有 CLI source/status 输出、发布流水状态、RuntimeAssembly result/event 摘要。 |
| 系统边界 | 源码同步负责 Git 来源和 artifact 来源可追溯;不执行模型任务,不决定发布是否通过,不把运行面副本或临时目录提升为 source truth。 |
## 5. 内部分工与规格索引
本规格前四个 L3 只承载服务无关的通用源码规则。AgentRun 固定 source branch、fixed worktree、GitOps branchartifact catalog 和 mirror 细则只在 AgentRun 专项 L3 中展开,通用源码同步条款只保留可复用的 source truth 边界。
本规格前四个 L3 只承载服务无关的通用源码规则。AgentRun 固定 source branch、fixed worktree、GitOps branchartifact catalog 细则只在 AgentRun 专项 L3 中展开,通用源码同步条款只保留可复用的 source truth 边界。
| 编号 | 模块或课题 | 规格文档 | 主责边界 | 上游依赖 | 下游支撑 |
| --- | --- | --- | --- | --- | --- |
| PJ2026-01060201 | Mirror同步 | 本规格 6.1 | Git mirror read/write URL、mirror cache 和 source branch 同步 | Git remote、平台网络 | 发布流水、Runtime装配 |
| PJ2026-01060202 | SourceTruth | 本规格 6.2 | fixed worktree、source branch、remote、clean/ff-only 状态 | Git mirror、项目仓库 | 服务 source 预检 |
| PJ2026-01060201 | Gitea同步 | 本规格 6.1 | Gitea read/write URL 和 source branch 同步 | Git remote、平台网络 | 发布流水、Runtime装配 |
| PJ2026-01060202 | SourceTruth | 本规格 6.2 | fixed worktree、source branch、remote、clean/ff-only 状态 | Gitea、项目仓库 | 服务 source 预检 |
| PJ2026-01060203 | GitOps目录 | 本规格 6.3 | GitOps branch、artifact catalog、runtime path 和 desired state | 发布流水 promotion | Argo sync、runtime 发布 |
| PJ2026-01060204 | GitBundle来源 | 本规格 6.4 | repoUrl/ref/actual commit/bundles 摘要和 mirror 改写 | Runtime装配、Git mirror | Agent runner、skills/tools |
| PJ2026-01060205 | AgentRun源码 | [PJ2026-01060205 AgentRun源码真相](PJ2026-01060205-agentrun-v01-source-truth.md) | AgentRun `v0.1` source branch、fixed worktree、GitOps branchartifact catalog 和 mirror 细则 | Git mirror、发布流水 | AgentRun runtime、Runtime装配 |
| PJ2026-01060204 | GitBundle来源 | 本规格 6.4 | Gitea repoUrl/ref/actual commit/bundles 摘要 | Runtime装配、Gitea | Agent runner、skills/tools |
| PJ2026-01060205 | AgentRun源码 | [PJ2026-01060205 AgentRun源码真相](PJ2026-01060205-agentrun-v01-source-truth.md) | AgentRun `v0.1` source branch、fixed worktree、GitOps branchartifact catalog 细则 | Gitea、发布流水 | AgentRun runtime、Runtime装配 |
## 6. 原子需求
### 6.1 OPS-SOURCE-REQ-001 Git Mirror 同步
### 6.1 OPS-SOURCE-REQ-001 Gitea 同步
| 编号 | 短名 | 主责模块 | 关联模块 |
| --- | --- | --- | --- |
| OPS-SOURCE-REQ-001 | Mirror同步 | PJ2026-01060201 Mirror同步 | [发布流水](PJ2026-010601-controlled-release.md)、[Runtime装配](PJ2026-010202-runtime-assembly.md) |
| OPS-SOURCE-REQ-001 | Gitea同步 | PJ2026-01060201 Gitea同步 | [发布流水](PJ2026-010601-controlled-release.md)、[Runtime装配](PJ2026-010202-runtime-assembly.md) |
源码同步应提供 Git mirror read/write 能力,使 CI/CD、RuntimeAssembly 和目标运行面优先通过平台 mirror 获取 GitHub 资源,避免把外网直连失败或临时 clone 作为源码阻塞
源码同步应 Gitea 作为 source branch、GitOps branch 和 artifact catalog 的唯一运行时 Git authority,并通过 owning YAML 声明的 read/write URL 与 SecretRef 完成受控同步
mirror 输出应能说明 owner/repo、read URL、write URL、cache 状态和同步来源,但不得输出 Git credential、SSH private key 或可复制 token。
- PaC、Tekton、Argo 和 runtime checkout 必须读取同一 Gitea 仓库中的对应 branch
- GitOps promotion 必须通过 Gitea SecretRef 写回同一仓库,禁止再写 legacy `git-mirror`
- `git-mirror-http``git-mirror-write`、mirror cache、sync/flush Job 和相关运行时入口必须退役,不得作为 fallback、缓存或第二 authority 保留;
- GitHub 只作为上游 source 输入,不能被 Pipeline 或 runtime 直接提升为第二 GitOps authority
- 输出应说明 owner/repo、read URL、write URL 和同步来源,但不得输出 Git credential、SSH private key 或可复制 token。
### 6.2 OPS-SOURCE-REQ-002 Source Truth 预检
@@ -128,4 +132,4 @@ GitOps branch 只保存目标运行面 desired state 和 artifact catalog,不
源码同步应为 gitbundle 装配提供 source authority,使 `ResourceBundleRef.repoUrl`、requested ref、actual commit、tree、bundles、promptRefs、tools 和 skills 的来源可验证。
runner materialization 可以按平台规则把 GitHub URL 改写到 G14 git mirror,但不得让 prompt、payload、host path、Secret volume、用户上传目录或运行时临时文件成为 gitbundle 的权威来源。event/result 只输出路径、hash、bytes、commit 和 bundle 摘要,不输出文件全文或凭据。
runner materialization 必须把上游 GitHub identity 解析到 owning YAML 声明的 Gitea repository,并从该唯一 authority 读取 requested ref。不得回退到 legacy git-mirror、GitHub 直连、host path、Secret volume、用户上传目录或运行时临时文件。event/result 只输出路径、hash、bytes、commit 和 bundle 摘要,不输出文件全文或凭据。
+108 -13
View File
@@ -87,6 +87,11 @@ import { fingerprintSecretValues, readEnvSourceFile, requiredEnvValue } from "./
export { HWLAB_NODE_CONTROL_PLANE_CONFIG_PATH } from "./hwlab-node-control-plane-model";
export function runHwlabNodeControlPlaneInfra(args: string[]): Record<string, unknown> | RenderedCliResult {
if (args[0] === "source-authority" && args[1] === "retire-legacy-runtime") {
const options = parseInfraOptions(["apply", ...args.slice(2)]);
const { node, target } = controlPlaneContext(options.node, options.lane);
return retireLegacySourceRuntime(node, target, options);
}
if (args[0] === "k3s-config") {
const options = parseInfraOptions(args.slice(1));
const { node, target } = controlPlaneContext(options.node, options.lane);
@@ -170,12 +175,14 @@ export function hwlabNodeControlPlaneInfraHelp(): Record<string, unknown> {
ok: true,
command: "hwlab nodes control-plane infra",
configPath: HWLAB_NODE_CONTROL_PLANE_CONFIG_PATH,
description: "Plan/status/apply YAML-controlled HWLAB node-local k3s, CI/CD and git-mirror control-plane prerequisites. Cross-node PK01/Caddy/FRP/runtime rollout remains explicit semi-automatic CLI work.",
description: "Plan/status/apply YAML-controlled HWLAB node-local k3s and CI/CD prerequisites, including retirement of the legacy Git runtime. Cross-node PK01/Caddy/FRP/runtime rollout remains explicit semi-automatic CLI work.",
usage: [
"bun scripts/cli.ts hwlab nodes control-plane infra plan --node <node> --lane <lane>",
"bun scripts/cli.ts hwlab nodes control-plane infra status --node <node> --lane <lane>",
"bun scripts/cli.ts hwlab nodes control-plane infra apply --node <node> --lane <lane> --dry-run",
"bun scripts/cli.ts hwlab nodes control-plane infra apply --node <node> --lane <lane> --confirm",
"bun scripts/cli.ts hwlab nodes control-plane infra source-authority retire-legacy-runtime --node <node> --lane <lane> --dry-run",
"bun scripts/cli.ts hwlab nodes control-plane infra source-authority retire-legacy-runtime --node <node> --lane <lane> --confirm",
"bun scripts/cli.ts hwlab nodes control-plane infra k3s plan --node JD01 --lane v03",
"bun scripts/cli.ts hwlab nodes control-plane infra k3s install --node JD01 --lane v03 --confirm",
"bun scripts/cli.ts hwlab nodes control-plane infra k3s status --node JD01 --lane v03",
@@ -291,6 +298,12 @@ function infraStatus(_config: ControlPlaneConfig, node: ControlPlaneNodeSpec, ta
const argoObserverRbac = record(argo.argoObserverRbac);
const gitMirror = record(components.gitMirror);
const gitMirrorGithubTransport = record(gitMirror.githubTransport);
const legacySourceRuntimeEnabled = target.source.sourceAuthority.mode === "gitMirrorSnapshot";
const legacySourceRuntimeAbsent = !boolField(gitMirror, "readServiceExists")
&& !boolField(gitMirror, "writeServiceExists")
&& !boolField(gitMirror, "cachePvcExists")
&& !boolField(gitMirror, "readDeploymentReady")
&& !boolField(gitMirror, "writeDeploymentReady");
const tekton = record(components.tekton);
const tektonInstall = record(tekton.install);
const ciNamespace = record(components.ciNamespace);
@@ -312,14 +325,16 @@ function infraStatus(_config: ControlPlaneConfig, node: ControlPlaneNodeSpec, ta
&& boolField(tektonInstall, "deploymentsReady")
&& tektonRuntimeProxyReady
&& boolField(ciNamespace, "exists")
&& boolField(ciGitWorkspaceSecret, "ready")
&& (!legacySourceRuntimeEnabled || boolField(ciGitWorkspaceSecret, "ready"))
&& boolField(runtimeNamespace, "exists")
&& boolField(runtimeObserverRbac, "ready")
&& boolField(gitMirror, "namespaceExists")
&& boolField(gitMirror, "readServiceExists")
&& boolField(gitMirror, "writeServiceExists")
&& (gitMirrorGithubTransport.required !== true || boolField(gitMirrorGithubTransport, "ready"))
&& (boolField(gitMirror, "cachePvcExists") || boolField(gitMirror, "cacheHostPathReady"))
&& (legacySourceRuntimeEnabled
? boolField(gitMirror, "namespaceExists")
&& boolField(gitMirror, "readServiceExists")
&& boolField(gitMirror, "writeServiceExists")
&& (gitMirrorGithubTransport.required !== true || boolField(gitMirrorGithubTransport, "ready"))
&& (boolField(gitMirror, "cachePvcExists") || boolField(gitMirror, "cacheHostPathReady"))
: legacySourceRuntimeAbsent)
&& boolField(registry, "ready")
&& boolField(registry, "toolsImageReady")
&& boolField(argo, "installed")
@@ -359,6 +374,8 @@ function infraStatus(_config: ControlPlaneConfig, node: ControlPlaneNodeSpec, ta
gitMirrorCacheHostPathReady: boolField(gitMirror, "cacheHostPathReady"),
gitMirrorReadReady: boolField(gitMirror, "readDeploymentReady"),
gitMirrorWriteReady: boolField(gitMirror, "writeDeploymentReady"),
legacySourceRuntimeEnabled,
legacySourceRuntimeAbsent,
argoInstalled: boolField(argo, "installed"),
argoProjectExists: boolField(argo, "projectExists"),
argoApplicationExists: boolField(argo, "applicationExists"),
@@ -430,6 +447,79 @@ function infraApply(_config: ControlPlaneConfig, node: ControlPlaneNodeSpec, tar
};
}
function retireLegacySourceRuntime(node: ControlPlaneNodeSpec, target: ControlPlaneTargetSpec, options: InfraOptions): Record<string, unknown> {
if (target.source.sourceAuthority.mode !== "giteaSnapshot") {
throw new Error(`targets.${target.id}.source.sourceAuthority.mode must be giteaSnapshot before retiring the legacy source runtime`);
}
const namespace = target.gitMirror.namespace;
const transportSecretName = target.gitMirror.githubTransport.mode === "https"
? target.gitMirror.githubTransport.tokenSecretName
: target.gitMirror.secretName;
const resources = [
`deployment/${target.gitMirror.serviceReadName}`,
`deployment/${target.gitMirror.serviceWriteName}`,
`service/${target.gitMirror.serviceReadName}`,
`service/${target.gitMirror.serviceWriteName}`,
`configmap/${target.gitMirror.syncConfigMapName}`,
`pvc/${target.gitMirror.cachePvcName}`,
`secret/${transportSecretName}`,
];
const jobPrefixes = [target.gitMirror.syncJobPrefix, target.gitMirror.flushJobPrefix];
const plan = {
namespace,
authority: "gitea",
resources,
jobPrefixes,
excluded: ["pipeline", "pipelinerun", "argo", "runtime-workloads", "registry"],
};
if (!options.confirm) {
return {
ok: true,
command: "hwlab nodes control-plane infra source-authority retire-legacy-runtime",
configPath: HWLAB_NODE_CONTROL_PLANE_CONFIG_PATH,
node: node.id,
lane: target.lane,
mode: "dry-run",
mutation: false,
plan,
next: { confirm: `bun scripts/cli.ts hwlab nodes control-plane infra source-authority retire-legacy-runtime --node ${node.id} --lane ${target.lane} --confirm` },
};
}
const resourceArgs = resources.map((value) => shQuote(value)).join(" ");
const prefixArgs = jobPrefixes.map((value) => shQuote(value)).join(" ");
const script = `
set -eu
namespace=${shQuote(namespace)}
kubectl -n "$namespace" delete ${resourceArgs} --ignore-not-found --wait=true >/tmp/unidesk-legacy-source-runtime-delete.out
for prefix in ${prefixArgs}; do
kubectl -n "$namespace" get jobs -o name 2>/dev/null | while IFS= read -r resource; do
name="\${resource#job.batch/}"
case "$name" in "$prefix"*) kubectl -n "$namespace" delete "$resource" --ignore-not-found --wait=true >/dev/null ;; esac
done
done
remaining=0
for resource in ${resourceArgs}; do
if kubectl -n "$namespace" get "$resource" >/dev/null 2>&1; then remaining=$((remaining + 1)); fi
done
printf '{"retired":true,"remaining":%s,"namespace":"%s"}\n' "$remaining" "$namespace"
test "$remaining" -eq 0
`;
const result = runTransK3s(node.kubeRoute, script, options.timeoutSeconds);
const parsed = parseRemoteJson(result.stdout);
return {
ok: result.exitCode === 0,
command: "hwlab nodes control-plane infra source-authority retire-legacy-runtime",
configPath: HWLAB_NODE_CONTROL_PLANE_CONFIG_PATH,
node: node.id,
lane: target.lane,
mode: "confirmed-retirement",
mutation: result.exitCode === 0,
plan,
result: typeof parsed === "object" && parsed !== null ? parsed : compactCommandResult(result),
next: { status: `bun scripts/cli.ts hwlab nodes control-plane infra status --node ${node.id} --lane ${target.lane}` },
};
}
function runK3sInstallCommand(_config: ControlPlaneConfig, node: ControlPlaneNodeSpec, target: ControlPlaneTargetSpec, options: K3sInstallOptions): Record<string, unknown> {
const spec = node.k3s?.install ?? null;
if (node.k3s === null || spec === null || !spec.enabled) {
@@ -2079,6 +2169,7 @@ function renderInfraManifest(_node: ControlPlaneNodeSpec, target: ControlPlaneTa
"hwlab.pikastech.local/lane": target.lane,
};
const manifests: Record<string, unknown>[] = [];
const legacySourceRuntimeEnabled = target.source.sourceAuthority.mode === "gitMirrorSnapshot";
const namespaces = new Set<string>();
const addNamespace = (name: string): void => {
if (namespaces.has(name)) return;
@@ -2087,7 +2178,7 @@ function renderInfraManifest(_node: ControlPlaneNodeSpec, target: ControlPlaneTa
};
addNamespace(target.ciNamespace);
addNamespace(target.runtimeNamespace);
addNamespace(target.gitMirror.namespace);
if (legacySourceRuntimeEnabled) addNamespace(target.gitMirror.namespace);
if (_node.registry.mode === "k8s-workload") addNamespace(_node.registry.namespace);
manifests.push(...registryInfraManifest(_node.registry, labels));
manifests.push(
@@ -2096,6 +2187,8 @@ function renderInfraManifest(_node: ControlPlaneNodeSpec, target: ControlPlaneTa
tektonRuntimeObserverRoleBinding(target, labels),
tektonArgoObserverRole(target, labels),
tektonArgoObserverRoleBinding(target, labels),
);
if (legacySourceRuntimeEnabled) manifests.push(
{
apiVersion: "v1",
kind: "ConfigMap",
@@ -2109,13 +2202,13 @@ function renderInfraManifest(_node: ControlPlaneNodeSpec, target: ControlPlaneTa
},
},
);
const githubTokenSecret = gitMirrorGithubTokenSecret(target, labels);
const githubTokenSecret = legacySourceRuntimeEnabled ? gitMirrorGithubTokenSecret(target, labels) : null;
if (githubTokenSecret !== null) manifests.push(githubTokenSecret);
const githubSshSecret = gitMirrorGithubSshSecret(target, labels);
const githubSshSecret = legacySourceRuntimeEnabled ? gitMirrorGithubSshSecret(target, labels) : null;
if (githubSshSecret !== null) manifests.push(githubSshSecret);
const ciGitWorkspaceSecret = tektonGitWorkspaceSecret(target, labels);
const ciGitWorkspaceSecret = legacySourceRuntimeEnabled ? tektonGitWorkspaceSecret(target, labels) : null;
if (ciGitWorkspaceSecret !== null) manifests.push(ciGitWorkspaceSecret);
if (target.gitMirror.cacheHostPath === null) {
if (legacySourceRuntimeEnabled && target.gitMirror.cacheHostPath === null) {
manifests.push({
apiVersion: "v1",
kind: "PersistentVolumeClaim",
@@ -2123,11 +2216,13 @@ function renderInfraManifest(_node: ControlPlaneNodeSpec, target: ControlPlaneTa
spec: { accessModes: ["ReadWriteOnce"], resources: { requests: { storage: target.gitMirror.cachePvcStorage } } },
});
}
manifests.push(
if (legacySourceRuntimeEnabled) manifests.push(
service(target.gitMirror.serviceReadName, target.gitMirror.namespace, labels, target.gitMirror.servicePort),
service(target.gitMirror.serviceWriteName, target.gitMirror.namespace, labels, target.gitMirror.servicePort),
gitMirrorDeployment(target.gitMirror.serviceReadName, target.gitMirror.namespace, labels, _node, target, "read"),
gitMirrorDeployment(target.gitMirror.serviceWriteName, target.gitMirror.namespace, labels, _node, target, "write"),
);
manifests.push(
{
apiVersion: "tekton.dev/v1",
kind: "Pipeline",
+1 -1
View File
@@ -34,7 +34,7 @@ export function applyNodeRuntimeDeployYamlOverlay(document: Record<string, unkno
else nextLane.externalPostgres = overlay.externalPostgres;
if (overlay.runtimeStore !== undefined) nextLane.runtimeStore = overlay.runtimeStore;
if (overlay.codeAgentRuntime !== undefined) nextLane.codeAgentRuntime = overlay.codeAgentRuntime;
if (overlay.deployYamlGitMirror !== undefined) nextLane.gitMirror = overlay.deployYamlGitMirror;
delete nextLane.gitMirror;
lanes[laneId] = nextLane;
doc.lanes = lanes;
return doc;
+2 -6
View File
@@ -1661,7 +1661,6 @@ export function nodeRuntimePipelinePostprocessScript(
" runtimeStore: overlay.runtimeStore,",
" codeAgentRuntime: overlay.codeAgentRuntime,",
" observability: overlay.observability,",
" deployYamlGitMirror: overlay.deployYamlGitMirror,",
" runtimeImageRewrites: overlay.runtimeImageRewrites,",
" dockerProxyHttp: overlay.dockerProxyHttp,",
" dockerProxyHttps: overlay.dockerProxyHttps,",
@@ -1712,7 +1711,6 @@ export function nodeRuntimePipelinePostprocessScript(
"else doc.lanes[overlay.lane].externalPostgres = overlay.externalPostgres;",
"if (overlay.runtimeStore !== undefined) doc.lanes[overlay.lane].runtimeStore = overlay.runtimeStore;",
"if (overlay.codeAgentRuntime !== undefined) doc.lanes[overlay.lane].codeAgentRuntime = overlay.codeAgentRuntime;",
"if (overlay.deployYamlGitMirror !== undefined) doc.lanes[overlay.lane].gitMirror = overlay.deployYamlGitMirror;",
"fs.writeFileSync(file, YAML.stringify(doc));",
"console.error(JSON.stringify({ event: 'unidesk-deploy-yaml-overlay', ok: true, lane: overlay.lane, httpProxy: overlay.dockerProxyHttp, noProxyCount: overlay.dockerNoProxyList.length }));",
"NODE_UNIDESK_DEPLOY_YAML_OVERLAY`;",
@@ -1879,7 +1877,7 @@ export function nodeRuntimePipelinePostprocessScript(
" container.env = next;",
" return true;",
"}",
"function isEnvReuseContainer(container) { return envValue(container, 'HWLAB_RUNTIME_MODE') === 'env-reuse-git-mirror-checkout' || envValue(container, 'HWLAB_BOOT_SH') !== undefined || envValue(container, 'HWLAB_BOOT_COMMIT') !== undefined; }",
"function isEnvReuseContainer(container) { return envValue(container, 'HWLAB_RUNTIME_MODE') === 'env-reuse-gitea-checkout' || envValue(container, 'HWLAB_BOOT_SH') !== undefined || envValue(container, 'HWLAB_BOOT_COMMIT') !== undefined; }",
"function workloadName(item) { return item && item.metadata && item.metadata.labels && item.metadata.labels['app.kubernetes.io/name'] ? String(item.metadata.labels['app.kubernetes.io/name']) : String(item && item.metadata && item.metadata.name || ''); }",
"function expectedPublicEndpoint(item) { return workloadName(item) === 'hwlab-cloud-web' ? overlay.publicWebUrl : overlay.publicApiUrl; }",
"function cloudWebRuntimeEnvEntries() {",
@@ -2355,7 +2353,7 @@ export function nodeRuntimePipelinePostprocessScript(
" const item = container.env.find((env) => env && env.name === name);",
" return item && item.valueFrom && item.valueFrom.secretKeyRef ? item.valueFrom.secretKeyRef : {};",
"}",
"function isEnvReuseContainer(container) { return envValue(container, 'HWLAB_RUNTIME_MODE') === 'env-reuse-git-mirror-checkout' || envValue(container, 'HWLAB_BOOT_SH') !== undefined || envValue(container, 'HWLAB_BOOT_COMMIT') !== undefined; }",
"function isEnvReuseContainer(container) { return envValue(container, 'HWLAB_RUNTIME_MODE') === 'env-reuse-gitea-checkout' || envValue(container, 'HWLAB_BOOT_SH') !== undefined || envValue(container, 'HWLAB_BOOT_COMMIT') !== undefined; }",
"function workloadName(item) { return item && item.metadata && item.metadata.labels && item.metadata.labels['app.kubernetes.io/name'] ? String(item.metadata.labels['app.kubernetes.io/name']) : String(item && item.metadata && item.metadata.name || ''); }",
"function expectedPublicEndpoint(item) { return workloadName(item) === 'hwlab-cloud-web' ? overlay.publicWebUrl : overlay.publicApiUrl; }",
"function cloudWebRuntimeEnvEntries() {",
@@ -2884,8 +2882,6 @@ export function nodeRuntimePipelinePostprocessScript(
"if (text.includes('/yaml/-/yaml-') || text.includes('bun add --no-save --ignore-scripts') || text.includes('npm install --package-lock=false --no-save')) { throw new Error(`generated pipeline still downloads yaml during prepare-source in ${pipelinePath}`); }",
"if (text.includes('npm run gitops:ts:check')) { throw new Error(`generated pipeline still uses npm gitops:ts:check gate in ${pipelinePath}`); }",
"fs.writeFileSync(pipelinePath, text);",
"patchGitMirrorHostRouteYaml();",
"patchGitMirrorTransportYaml();",
"function patchArgoYaml(filePath) {",
" if (!YAML || !fs.existsSync(filePath)) return;",
" const docs = YAML.parseAllDocuments(fs.readFileSync(filePath, 'utf8')).map((document) => document.toJS()).filter((doc) => doc !== null);",
-15
View File
@@ -64,19 +64,6 @@ export function nodeRuntimeRenderOverlay(spec: HwlabRuntimeLaneSpec): Record<str
required: true,
},
};
const deployYamlGitMirror = {
...renderGitMirror,
egressProxy: renderGitMirror.egressProxy.mode !== "host-route" ? renderGitMirror.egressProxy : {
mode: "node-global",
required: true,
clientName: renderGitMirror.egressProxy.clientName,
namespace: "platform-infra",
serviceName: renderGitMirror.egressProxy.clientName,
port: httpProxyEndpoint(renderGitMirror.egressProxy.proxyUrl)?.port ?? 10808,
proxyUrl: renderGitMirror.egressProxy.proxyUrl,
noProxy: renderGitMirror.egressProxy.noProxy,
},
};
return {
pipelineProvenanceAnnotations: hwlabRuntimePipelineProvenanceAnnotations(spec),
nodeId: spec.nodeId,
@@ -98,8 +85,6 @@ export function nodeRuntimeRenderOverlay(spec: HwlabRuntimeLaneSpec): Record<str
gitWriteUrl: spec.gitWriteUrl,
toolsImage: gitMirror.toolsImage,
toolsImagePullPolicy: gitMirror.toolsImagePullPolicy,
gitMirror: renderGitMirror,
deployYamlGitMirror,
networkProfileId: spec.networkProfileId,
downloadProfileId: spec.downloadProfileId,
gitSshProxyHost: gitSshProxy?.host,
@@ -1089,14 +1089,13 @@ describe("shared HWLAB deploy overlay", () => {
externalPostgres: null,
runtimeStore: null,
codeAgentRuntime: null,
deployYamlGitMirror: null,
};
const rendered = applyNodeRuntimeDeployYamlOverlay(document, overlay);
expect(document.lanes.v03.externalPostgres).toEqual({ old: true });
expect(rendered.lanes.v03).not.toHaveProperty("externalPostgres");
expect(rendered.lanes.v03.runtimeStore).toBeNull();
expect(rendered.lanes.v03.codeAgentRuntime).toBeNull();
expect(rendered.lanes.v03.gitMirror).toBeNull();
expect(rendered.lanes.v03).not.toHaveProperty("gitMirror");
expect(rendered.lanes.v03.keep).toBe("lane");
expect(nodeRuntimeDeployYamlOverlayShellScript().join("\n")).not.toContain(": Record<string");
});
@@ -1113,7 +1112,6 @@ describe("shared HWLAB deploy overlay", () => {
runtimePath: "deploy/gitops/node/nc01/hwlab-v03", observability: { enabled: true },
dockerProxyHttp: "http://proxy", dockerProxyHttps: "http://proxy", dockerNoProxyList: ["localhost"],
externalPostgres: { host: "postgres" }, runtimeStore: { mode: "postgres" }, codeAgentRuntime: { enabled: true },
deployYamlGitMirror: { readUrl: "http://mirror" },
};
writeFileSync(resolve(temporary, "deploy", "deploy.yaml"), Bun.YAML.stringify(document));
const overlayBase64 = Buffer.from(JSON.stringify(overlay), "utf8").toString("base64");
@@ -1122,6 +1122,15 @@ export function pipelineRunWorkspaces(binding: PacSourceArtifactBinding, desired
};
}
if (name === "git-ssh") return { name, secret: { secretName: requiredParam(binding, "git_ssh_secret") } };
if (name === "gitea-auth") {
return {
name,
secret: {
secretName: requiredParam(binding, "gitops_secret_name"),
items: [{ key: binding.repository.tokenKey, path: "token" }],
},
};
}
throw new Error(`unsupported Pipeline workspace ${name}; declare a renderer mapping before generating the source artifact`);
});
}
@@ -1409,7 +1409,7 @@ function validateConsumerConfig(
if ((consumer.sourceArtifact?.renderer === "sub2rank-platform-service" || consumer.sourceArtifact?.renderer === "static-site-runtime") && consumer.runnerServiceAccount === null) {
throw new Error(`${configLabel}.consumers.${consumer.id}.runnerServiceAccount is required for ${consumer.sourceArtifact.renderer}`);
}
if (consumer.sourceArtifact?.renderer === "selfmedia-runtime" || consumer.sourceArtifact?.renderer === "pikaoa-development-runtime") {
if (consumer.sourceArtifact?.renderer === "selfmedia-runtime" || consumer.sourceArtifact?.renderer === "pikaoa-development-runtime" || consumer.sourceArtifact?.renderer === "hwlab-runtime-lane") {
if (consumer.runnerServiceAccount === null) throw new Error(`${configLabel}.consumers.${consumer.id}.runnerServiceAccount is required for private GitOps runtime renderers`);
if (consumer.argoBootstrap?.repositoryCredential === null || consumer.argoBootstrap?.repositoryCredential === undefined) {
throw new Error(`${configLabel}.consumers.${consumer.id}.argoBootstrap.repositoryCredential is required for the private repository`);