Merge pull request #1485 from pikasTech/fix/1476-branch-follower-target-status

fix: recognize branch follower closed-out targets
This commit is contained in:
Lyon
2026-07-03 14:09:45 +08:00
committed by GitHub
+43 -18
View File
@@ -871,24 +871,7 @@ async function readAdapterStatus(follower: FollowerSpec, options: ParsedOptions)
"alignment.sourceCommit",
], ["sourceCommit", "observedSha", "observedCommit", "selectedCommit", "selectedSourceCommit"])
?? adapterObservedShaFromText(result.stdout, follower);
const targetSha = firstStringPath(body, [
"summary.targetCommit",
"summary.targetSha",
"summary.runtimeCommit",
"summary.gitopsCommit",
"runtime.sourceCommit",
"runtime.commit",
"target.commit",
"target.sha",
"gitops.sourceCommit",
"deployedCommit",
"currentCommit",
"targetSha",
"summary.runtimeAlignment.managerSourceCommit",
"alignment.runtimeAlignment.managerSourceCommit",
"runtime.manager.sourceCommit",
"manager.sourceCommit",
], ["targetCommit", "targetSha", "runtimeCommit", "gitopsCommit", "deployedCommit", "currentCommit"]);
const targetSha = adapterTargetShaFromStatus(body, result.stdout, follower, observedSha);
const lastTriggeredSha = firstStringPath(body, [
"summary.lastTriggeredSha",
"summary.lastTriggeredCommit",
@@ -960,6 +943,43 @@ function statusMessage(ok: boolean, phase: BranchFollowerPhase, observedSha: str
return "status command completed; observed sha not exposed in compact payload";
}
function adapterTargetShaFromStatus(body: Record<string, unknown> | null, stdout: string, follower: FollowerSpec, observedSha: string | null): string | null {
const structured = firstStringPath(body, [
"summary.targetCommit",
"summary.targetSha",
"summary.runtimeCommit",
"summary.gitopsCommit",
"runtime.sourceCommit",
"runtime.commit",
"target.commit",
"target.sha",
"gitops.sourceCommit",
"deployedCommit",
"currentCommit",
"targetSha",
"summary.runtimeAlignment.managerSourceCommit",
"alignment.runtimeAlignment.managerSourceCommit",
"runtime.manager.sourceCommit",
"manager.sourceCommit",
], ["targetCommit", "targetSha", "runtimeCommit", "gitopsCommit", "deployedCommit", "currentCommit"]);
if (structured !== null) return structured;
if (observedSha !== null && adapterStatusImpliesObservedTarget(body, stdout, follower)) return observedSha;
return null;
}
function adapterStatusImpliesObservedTarget(body: Record<string, unknown> | null, stdout: string, follower: FollowerSpec): boolean {
if (follower.adapter === "hwlab-node-runtime") {
if (booleanAt(body, "ok") === true && booleanAt(body, "summary.ok") !== false) return true;
}
if (follower.adapter === "web-probe-sentinel-cicd") {
if (booleanAt(body, "ok") === true && booleanAt(body, "observed.wait.ready") !== false) return true;
const node = escapeRegex(follower.target.node);
const lane = escapeRegex(follower.target.lane);
if (new RegExp(`\\b${node}\\s+${lane}\\s+ok\\s+status\\b`, "iu").test(stdout)) return true;
}
return false;
}
function mergeFollowerStatus(
registry: BranchFollowerRegistry,
follower: FollowerSpec,
@@ -1338,6 +1358,11 @@ function firstBooleanPath(root: Record<string, unknown> | null, paths: string[])
return null;
}
function booleanAt(root: Record<string, unknown> | null, path: string): boolean | null {
const value = valueAt(root, path);
return typeof value === "boolean" ? value : null;
}
function valueAt(root: unknown, path: string): unknown {
let current = root;
for (const part of path.split(".")) {