From 0a9d07c760b5aa2b95ab8103eede0d4af3b18938 Mon Sep 17 00:00:00 2001 From: Codex Date: Thu, 11 Jun 2026 17:47:58 +0000 Subject: [PATCH] fix: make hwlab git mirror lane-aware --- scripts/src/hwlab-g14.ts | 79 ++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/scripts/src/hwlab-g14.ts b/scripts/src/hwlab-g14.ts index 46a54c67..7ff0df47 100644 --- a/scripts/src/hwlab-g14.ts +++ b/scripts/src/hwlab-g14.ts @@ -4327,7 +4327,7 @@ function runRuntimeLaneControlPlane(spec: HwlabRuntimeLaneSpec, options: G14Cont gitMirrorSync: { mode: "skipped-dry-run", wouldSyncBeforeTrigger: true, - command: "bun scripts/cli.ts hwlab g14 git-mirror sync --confirm", + command: `bun scripts/cli.ts hwlab g14 git-mirror sync --lane ${spec.lane} --confirm`, }, controlPlaneRefresh: { mode: "skipped-dry-run", @@ -4403,7 +4403,7 @@ function runRuntimeLaneControlPlane(spec: HwlabRuntimeLaneSpec, options: G14Cont sourceCommit, pipelineRun, }); - const gitMirrorPreSyncStatus = runGitMirrorStatus(); + const gitMirrorPreSyncStatus = runGitMirrorStatus(spec.lane); const gitMirrorSourceAlreadyCurrent = runtimeLaneGitMirrorSourceInSync(spec, sourceCommit, gitMirrorPreSyncStatus); const gitMirrorSync = gitMirrorSourceAlreadyCurrent ? { @@ -4443,6 +4443,28 @@ function runRuntimeLaneControlPlane(spec: HwlabRuntimeLaneSpec, options: G14Cont degradedReason: "git-mirror-sync-before-trigger-failed", }; } + const gitMirrorPostSyncStatus = gitMirrorSourceAlreadyCurrent ? gitMirrorPreSyncStatus : record(gitMirrorSync.status); + if (!runtimeLaneGitMirrorSourceInSync(spec, sourceCommit, gitMirrorPostSyncStatus)) { + return { + ok: false, + command: `hwlab g14 control-plane trigger-current --lane ${spec.lane}`, + lane: spec.lane, + mode: "confirmed-trigger", + sourceCommit, + pipelineRun, + before, + gitMirrorSync: compactGitMirrorSync(gitMirrorSync), + gitMirror: { + ok: gitMirrorPostSyncStatus.ok === true, + summary: record(nested(gitMirrorPostSyncStatus, ["cache", "summary"])), + }, + degradedReason: `${spec.lane}-git-mirror-source-still-stale-after-sync`, + next: { + apply: `bun scripts/cli.ts hwlab nodes git-mirror apply --node ${spec.nodeId} --lane ${spec.lane} --confirm`, + sync: `bun scripts/cli.ts hwlab nodes git-mirror sync --node ${spec.nodeId} --lane ${spec.lane} --confirm`, + }, + }; + } printRuntimeLaneTriggerProgress(spec, { stage: "source-render", status: "started", @@ -5775,6 +5797,25 @@ export function gitMirrorStatusSummary(raw: string): Record { const githubV03Gitops = refs.refs.githubV03Gitops ?? null; const sourceInSync = Boolean(localV02 && githubV02 && localV02 === githubV02); const gitopsInSync = Boolean(localGitops && githubGitops && localGitops === githubGitops); + const runtimeLanes = Object.fromEntries(hwlabRuntimeLaneIds().map((lane) => { + const normalized = lane.slice(0, 1).toUpperCase() + lane.slice(1).toLowerCase(); + const localSource = refs.refs[`local${normalized}`] ?? null; + const githubSource = refs.refs[`github${normalized}`] ?? null; + const localLaneGitops = refs.refs[`local${normalized}Gitops`] ?? null; + const githubLaneGitops = refs.refs[`github${normalized}Gitops`] ?? null; + return [lane, { + localSource, + githubSource, + localGitops: localLaneGitops, + githubGitops: githubLaneGitops, + sourceInSync: Boolean(localSource && githubSource && localSource === githubSource), + gitopsInSync: Boolean(localLaneGitops && githubLaneGitops && localLaneGitops === githubLaneGitops), + }]; + })); + const allRuntimeLanesInSync = Object.values(runtimeLanes).every((item) => { + const laneSummary = record(item); + return laneSummary.sourceInSync === true && laneSummary.gitopsInSync === true; + }); return { localV02, githubV02, @@ -5808,6 +5849,8 @@ export function gitMirrorStatusSummary(raw: string): Record { gitopsInSync, v03SourceInSync: Boolean(localV03 && githubV03 && localV03 === githubV03), v03GitopsInSync: Boolean(localV03Gitops && githubV03Gitops && localV03Gitops === githubV03Gitops), + runtimeLanes, + allRuntimeLanesInSync, githubInSync: sourceInSync && gitopsInSync, }; } @@ -6278,8 +6321,9 @@ function preSyncV02GitMirror(sourceCommit: string, options: Pick { +function runGitMirrorStatus(lane: HwlabRuntimeLane = "v02"): Record { const startedAtMs = Date.now(); + const spec = hwlabRuntimeLaneSpec(lane); const script = [ "set +e", "section() {", @@ -6327,7 +6371,8 @@ function runGitMirrorStatus(): Record { const bundleStderr = bundle.stderr.trim().slice(0, 2000); return { ok: isCommandSuccess(bundle) && shellSectionOk(resources), - command: "hwlab g14 git-mirror status", + command: `hwlab g14 git-mirror status --lane ${lane}`, + lane, namespace: GIT_MIRROR_NAMESPACE, readUrl: V02_GIT_READ_URL, writeUrl: V02_GIT_WRITE_URL, @@ -6355,9 +6400,9 @@ function runGitMirrorStatus(): Record { stderr: shellSectionOk(cache) ? "" : bundleStderr, }, next: { - apply: "bun scripts/cli.ts hwlab g14 git-mirror apply --confirm", - sync: "bun scripts/cli.ts hwlab g14 git-mirror sync --confirm", - flush: "bun scripts/cli.ts hwlab g14 git-mirror flush --confirm", + apply: `bun scripts/cli.ts hwlab g14 git-mirror apply --lane ${spec.lane} --confirm`, + sync: `bun scripts/cli.ts hwlab g14 git-mirror sync --lane ${spec.lane} --confirm`, + flush: `bun scripts/cli.ts hwlab g14 git-mirror flush --lane ${spec.lane} --confirm`, }, }; } @@ -6404,10 +6449,10 @@ function runGitMirrorApply(options: G14GitMirrorOptions): Record " sleep 2", "done", `kubectl logs -n ${shellQuote(GIT_MIRROR_NAMESPACE)} "job/$job" --tail=200 || true`, - `kubectl exec -n ${shellQuote(GIT_MIRROR_NAMESPACE)} deploy/git-mirror-http -- sh -lc 'cat /cache/HWLAB.last-sync.json 2>/dev/null || true; printf "\\n"; git --git-dir=/cache/pikasTech/HWLAB.git rev-parse refs/heads/v0.2 refs/heads/v0.2-gitops refs/heads/G14 2>/dev/null || true'`, + `kubectl exec -n ${shellQuote(GIT_MIRROR_NAMESPACE)} deploy/git-mirror-http -- sh -lc ${shellQuote(`cat /cache/HWLAB.last-sync.json 2>/dev/null || true; printf "\\n"; git --git-dir=/cache/pikasTech/HWLAB.git rev-parse refs/heads/${spec.sourceBranch} refs/mirror-stage/heads/${spec.sourceBranch} refs/heads/${spec.gitopsBranch} refs/mirror-stage/heads/${spec.gitopsBranch} 2>/dev/null || true`)}`, ].join("\n"), ].join("\n"); const result = g14K3s(["script", "--", script], options.timeoutSeconds * 1000 + 30_000); @@ -6464,7 +6509,7 @@ function runGitMirrorSync(options: G14GitMirrorOptions): Record elapsedMs: Date.now() - startedAtMs, manifest: options.dryRun ? manifest : undefined, result: compactCommandResult(result), - status: options.dryRun ? undefined : runGitMirrorStatus(), + status: options.dryRun ? undefined : runGitMirrorStatus(spec.lane), next: options.dryRun ? { sync: syncCommand } : { triggerCurrent: triggerCommand }, }; } @@ -6501,7 +6546,7 @@ function runGitMirrorFlush(options: G14GitMirrorOptions): Record/dev/null || true; printf "\\n"; git --git-dir=/cache/pikasTech/HWLAB.git rev-parse refs/heads/v0.2-gitops refs/mirror-stage/heads/v0.2-gitops 2>/dev/null || true'`, + `kubectl exec -n ${shellQuote(GIT_MIRROR_NAMESPACE)} deploy/git-mirror-http -- sh -lc ${shellQuote(`cat /cache/HWLAB.last-flush.json 2>/dev/null || true; printf "\\n"; git --git-dir=/cache/pikasTech/HWLAB.git rev-parse refs/heads/${options.lane === "v02" ? "v0.2-gitops" : hwlabRuntimeLaneSpec(options.lane).gitopsBranch} refs/mirror-stage/heads/${options.lane === "v02" ? "v0.2-gitops" : hwlabRuntimeLaneSpec(options.lane).gitopsBranch} 2>/dev/null || true`)}`, ].join("\n"), ].join("\n"); const result = g14K3s(["script", "--", script], options.timeoutSeconds * 1000 + 30_000); @@ -6513,13 +6558,15 @@ function runGitMirrorFlush(options: G14GitMirrorOptions): Record { - if (options.action === "status") return runGitMirrorStatus(); + if (options.action === "status") return runGitMirrorStatus(options.lane); if (options.action === "apply") return runGitMirrorApply(options); if (options.action === "flush") return runGitMirrorFlush(options); return runGitMirrorSync(options); @@ -9298,7 +9345,7 @@ function triggerRuntimeLaneCurrent(spec: HwlabRuntimeLaneSpec, timeoutSeconds: n function runtimeLaneStatusWithGitMirror(spec: HwlabRuntimeLaneSpec, sourceCommit: string): Record { const status = runtimeLaneControlPlaneStatus(spec, { sourceCommit, mode: "source-commit" }); - const gitMirrorStatus = runGitMirrorStatus(); + const gitMirrorStatus = runGitMirrorStatus(spec.lane); return { ...status, gitMirror: record(gitMirrorStatus.cache),