fix: flush git mirror during follower closeout

This commit is contained in:
Codex
2026-07-03 13:22:46 +00:00
parent 7c43716b3c
commit 63040ba28c
2 changed files with 84 additions and 0 deletions
+1
View File
@@ -222,6 +222,7 @@ export interface NativeCloseoutWaitResult {
polls: number;
elapsedMs: number;
refresh: Record<string, unknown> | null;
gitMirrorFlush: Record<string, unknown> | null;
summary: Record<string, unknown> | null;
statusAuthority: "k8s-native";
parsedDownstreamCliOutput: false;
+83
View File
@@ -1279,10 +1279,36 @@ async function waitNativeSentinelCloseout(
const deadline = startedAt + Math.max(1, timeoutSeconds) * 1000;
let polls = 0;
let latest: AdapterSummary | null = null;
let gitMirrorFlush: Record<string, unknown> | null = null;
while (Date.now() <= deadline) {
polls += 1;
const remainingSeconds = Math.max(1, Math.ceil((deadline - Date.now()) / 1000));
latest = await readAdapterStatus(registry, follower, { ...options, timeoutSeconds: Math.min(10, remainingSeconds) });
const latestPayload = asOptionalRecord(latest.payload);
const latestGitMirror = asOptionalRecord(latestPayload?.gitMirror);
if (latest.observedSha === observedSha && gitMirrorFlush === null && shouldFlushNativeGitMirrorDuringCloseout(follower, latestGitMirror)) {
const flush = runNativeGitMirrorStage(follower, observedSha, "flush", Math.max(1, Math.min(remainingSeconds, follower.budgets.sourceSyncSeconds)));
gitMirrorFlush = flush === null ? null : {
jobName: flush.jobName,
namespace: flush.namespace,
result: compactNativeK8sJobResult(flush.result),
};
if (flush !== null && !flush.result.ok) {
return {
ok: false,
completed: false,
timedOut: flush.result.timedOut,
polls,
elapsedMs: Date.now() - startedAt,
refresh: refreshResult === null ? null : commandCompact(refreshResult, options),
gitMirrorFlush,
summary: nativeCloseoutSummary(latest),
statusAuthority: "k8s-native",
parsedDownstreamCliOutput: false,
};
}
continue;
}
if (latest.observedSha === observedSha && latest.aligned === true) {
return {
ok: true,
@@ -1291,6 +1317,7 @@ async function waitNativeSentinelCloseout(
polls,
elapsedMs: Date.now() - startedAt,
refresh: refreshResult === null ? null : commandCompact(refreshResult, options),
gitMirrorFlush,
summary: nativeCloseoutSummary(latest),
statusAuthority: "k8s-native",
parsedDownstreamCliOutput: false,
@@ -1306,12 +1333,38 @@ async function waitNativeSentinelCloseout(
polls,
elapsedMs: Date.now() - startedAt,
refresh: refreshResult === null ? null : commandCompact(refreshResult, options),
gitMirrorFlush,
summary: latest === null ? null : nativeCloseoutSummary(latest),
statusAuthority: "k8s-native",
parsedDownstreamCliOutput: false,
};
}
function shouldFlushNativeGitMirrorDuringCloseout(follower: FollowerSpec, gitMirror: Record<string, unknown> | null): boolean {
if (!nativeGitMirrorRequired(follower) || gitMirror === null) return false;
if (gitMirror.sourceSnapshotReady === false) return false;
return gitMirror.pendingFlush === true || gitMirror.githubInSync === false;
}
function compactNativeK8sJobResult(result: NativeK8sJobResult): Record<string, unknown> {
return {
ok: result.ok,
completed: result.completed,
failed: result.failed,
timedOut: result.timedOut,
created: result.created,
reused: result.reused,
jobName: result.jobName,
namespace: result.namespace,
polls: result.polls,
elapsedMs: result.elapsedMs,
conditionReason: result.conditionReason,
conditionMessage: result.conditionMessage,
statusAuthority: result.statusAuthority,
parsedDownstreamCliOutput: false,
};
}
async function waitNativeFollowerCloseout(
registry: BranchFollowerRegistry,
follower: FollowerSpec,
@@ -2016,6 +2069,7 @@ function compactStateCommand(command: Record<string, unknown> | undefined): Reco
timedOut: closeout.timedOut === true,
polls: numberOrNull(closeout.polls),
elapsedMs: numberOrNull(closeout.elapsedMs),
gitMirrorFlush: compactCloseoutGitMirrorFlush(asOptionalRecord(closeout.gitMirrorFlush)),
summary: closeoutSummary,
statusAuthority: stringOrNull(closeout.statusAuthority),
parsedDownstreamCliOutput: false,
@@ -2028,6 +2082,32 @@ function compactStateCommand(command: Record<string, unknown> | undefined): Reco
};
}
function compactCloseoutGitMirrorFlush(value: Record<string, unknown> | null): Record<string, unknown> | null {
if (value === null) return null;
const result = asOptionalRecord(value.result);
return {
jobName: stringOrNull(value.jobName),
namespace: stringOrNull(value.namespace),
result: result === null
? null
: {
ok: result.ok === true,
completed: result.completed === true,
failed: result.failed === true,
timedOut: result.timedOut === true,
created: result.created === true,
reused: result.reused === true,
jobName: stringOrNull(result.jobName),
namespace: stringOrNull(result.namespace),
elapsedMs: numberOrNull(result.elapsedMs),
conditionReason: stringOrNull(result.conditionReason),
conditionMessage: stringOrNull(result.conditionMessage),
statusAuthority: stringOrNull(result.statusAuthority),
parsedDownstreamCliOutput: false,
},
};
}
function compactStateWarnings(warnings: string[]): string[] {
return warnings.slice(0, 4).map((item) => redactText(tailText(item, 400)));
}
@@ -2312,6 +2392,9 @@ function stageTimingsFromCommand(command: Record<string, unknown> | undefined):
}
const closeout = asOptionalRecord(command.closeout);
if (closeout !== null) {
const gitMirrorFlush = asOptionalRecord(closeout.gitMirrorFlush);
const gitMirrorFlushStage = k8sJobTiming("git-mirror-flush", asOptionalRecord(gitMirrorFlush?.result), stringOrNull(gitMirrorFlush?.jobName));
if (gitMirrorFlushStage !== null) stages.push(gitMirrorFlushStage);
const status = closeout.completed === true ? "completed" : closeout.timedOut === true ? "timed-out" : "pending";
stages.push(stageTiming("closeout", status, secondsFromMs(numberOrNull(closeout.elapsedMs)), null, "k8s-native-closeout", stringOrNull(command.pipelineRun)));
}