From b24dc9b1db75fe4772ded9fa25aed4273efdc38b Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 1 Jun 2026 22:48:27 +0800 Subject: [PATCH] fix(cicd): allow mirror fetch by exact commit --- docs/reference/spec-v02-cicd.md | 2 ++ scripts/g14-gitops-render.mjs | 2 +- scripts/g14-gitops-render.test.ts | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/reference/spec-v02-cicd.md b/docs/reference/spec-v02-cicd.md index 265c1427..563682bc 100644 --- a/docs/reference/spec-v02-cicd.md +++ b/docs/reference/spec-v02-cicd.md @@ -130,6 +130,8 @@ devops-infra git mirror 仍是 PipelineRun 和 Argo CD 的集群内读写源。` `devops-infra` git mirror/relay 同样不设周期 CronJob。标准触发命令 `bun scripts/cli.ts hwlab g14 control-plane trigger-current --lane v02 --confirm` 会在创建 PipelineRun 前按需同步 mirror;`bun scripts/cli.ts hwlab g14 git-mirror sync --confirm` 只作为显式 mirror 维护或诊断入口。promotion 成功后可执行 `bun scripts/cli.ts hwlab g14 git-mirror flush --confirm` 把本地 `v0.2-gitops` 推送到 GitHub。`git-mirror apply` 维护 mirror 的 PVC、读服务、写服务、同步/flush 脚本和旧 CronJob 清理;`git-mirror sync` 创建一次性 Job,只同步 allowlist refs `v0.2`、`v0.2-gitops`、`G14` 和 `G14-gitops`,先 fetch 到隐藏 staging refs,校验 commit/tree/object closure,再用 `update-ref` 发布到公开 refs。这样 mirror read path 与 GitOps write path 都落在本地磁盘和集群网络,同时避免 CI 看到 ref 已更新但对象还不可 checkout 的半发布窗口。 +mirror 的 HTTP upload-pack 必须允许按精确 commit SHA 拉取已存在对象:`uploadpack.allowReachableSHA1InWant=true` 且 `uploadpack.allowAnySHA1InWant=true`。v0.2 Code Agent 通过 AgentRun 传递 `resourceBundleRef.commitId` 来复现实验时的源码身份,runner 会执行等价的 `git fetch --depth=1 origin `;如果 mirror 只允许 advertised refs,旧 runtime commit、GitOps 已推进后的 commit 或隐藏 staging 已验证对象会返回 `Server does not allow request for unadvertised object` 并表现为 `git fetch failed with code 128`。这不是把 AgentRun 降级成浮动 branch fetch 的理由,修复点是 mirror read service 的 upload-pack 策略。 + `hwlab-cli` 不属于 v0.2 CI/CD service matrix。它是 `G14:/root/hwlab-v02` 和 v0.2 worktree 内的短连接源码 client,只用 Bun 直接调用 Cloud Web 同源 API;不得加入 PipelineRun `services` 参数、artifact catalog、BuildKit publish、runtime desired state、Deployment、Service、Job 或 image build。CLI-only source 变更推送到 `origin/v0.2` 后,`trigger-current --lane v02` 应表现为 `build=0 reuse=` 的 source-only fast path,用于证明 source/mirror/GitOps 没有产生旧 runtime artifact 副作用。若出现 `build-hwlab-cli` TaskRun、`hwlab-cli` artifact service、CLI 镜像或 CLI 常驻服务,均视为旧门禁/旧断言残留,直接删除并回到 `docs/reference/spec-v02-hwlab-cli.md` 的短连接 client 口径。 `rpt004:mvp:e2e`、`runner:issue-visibility:preflight` 和 `dev-base-image:preflight` 不属于 v0.2 最小 CI/CD 校验入口;它们代表旧验收、旧 runner 可见性预检或旧镜像基础预检口径。v0.2 `check/validate` 不再引用这些任务,若它们重新进入默认 check plan、package script 或 PipelineRun,应直接删除该入口,而不是为其补兼容逻辑。 diff --git a/scripts/g14-gitops-render.mjs b/scripts/g14-gitops-render.mjs index f06e0459..69b5bd7a 100644 --- a/scripts/g14-gitops-render.mjs +++ b/scripts/g14-gitops-render.mjs @@ -3193,7 +3193,7 @@ fi /script/install-hooks.sh git -C "$repo_path" config uploadpack.hideRefs refs/mirror-stage git -C "$repo_path" config uploadpack.allowReachableSHA1InWant true -git -C "$repo_path" config uploadpack.allowAnySHA1InWant false +git -C "$repo_path" config uploadpack.allowAnySHA1InWant true git -C "$repo_path" config --unset-all remote.origin.fetch 2>/dev/null || true git -C "$repo_path" config --add remote.origin.fetch '+refs/heads/v0.2:refs/mirror-stage/heads/v0.2' git -C "$repo_path" config --add remote.origin.fetch '+refs/heads/v0.2-gitops:refs/mirror-stage/heads/v0.2-gitops' diff --git a/scripts/g14-gitops-render.test.ts b/scripts/g14-gitops-render.test.ts index 318c9eff..3315a108 100644 --- a/scripts/g14-gitops-render.test.ts +++ b/scripts/g14-gitops-render.test.ts @@ -134,6 +134,8 @@ test("v02 render follows TypeScript runtime checks and does not self-patch boots const gitMirrorConfigMap = gitMirrorJson.items.find((item) => item.kind === "ConfigMap" && item.metadata?.name === "git-mirror-sync-script"); const gitMirrorScripts = gitMirrorConfigMap?.data ?? {}; const gitMirrorScript = gitMirrorScripts["sync.sh"] ?? ""; + assert.match(gitMirrorScript, /uploadpack\.allowReachableSHA1InWant true/u); + assert.match(gitMirrorScript, /uploadpack\.allowAnySHA1InWant true/u); assert.match(gitMirrorScript, /refs\/heads\/v0\.2:refs\/mirror-stage\/heads\/v0\.2/u); assert.match(gitMirrorScript, /refs\/heads\/v0\.2-gitops:refs\/mirror-stage\/heads\/v0\.2-gitops/u); assert.match(gitMirrorScript, /refs\/heads\/G14:refs\/mirror-stage\/heads\/G14/u);