fix: preserve branch follower stage intervals
This commit is contained in:
+38
-22
@@ -73,14 +73,7 @@ export function compactTimings(timings: FollowerState["timings"]): FollowerState
|
||||
startedAt: timings.startedAt,
|
||||
finishedAt: timings.finishedAt,
|
||||
overBudget: timings.overBudget,
|
||||
stages: timings.stages.slice(0, 24).map((stage) => ({
|
||||
stage: stage.stage,
|
||||
status: stage.status,
|
||||
seconds: stage.seconds,
|
||||
budgetSeconds: stage.budgetSeconds,
|
||||
source: stage.source,
|
||||
object: stage.object,
|
||||
})),
|
||||
stages: timings.stages.slice(0, 24).map((stage) => compactStageTiming(stage, true)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -94,11 +87,7 @@ export function compactListTimings(timings: FollowerState["timings"]): Record<st
|
||||
startedAt: timings.startedAt,
|
||||
finishedAt: timings.finishedAt,
|
||||
overBudget: timings.overBudget,
|
||||
stages: timings.stages.slice(0, 4).map((stage) => ({
|
||||
stage: stage.stage,
|
||||
status: stage.status,
|
||||
seconds: stage.seconds,
|
||||
})),
|
||||
stages: timings.stages.slice(0, 4).map((stage) => compactListStageTiming(stage)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -141,6 +130,31 @@ function noopStoredTotalFinishOverride(
|
||||
return new Date().toISOString();
|
||||
}
|
||||
|
||||
function compactStageTiming(stage: StageTiming, includeDetail: boolean): StageTiming {
|
||||
const row: StageTiming = {
|
||||
stage: stage.stage,
|
||||
status: stage.status,
|
||||
seconds: stage.seconds,
|
||||
budgetSeconds: includeDetail ? stage.budgetSeconds : null,
|
||||
source: includeDetail ? stage.source : "",
|
||||
object: includeDetail ? stage.object : null,
|
||||
};
|
||||
if (stage.startedAt !== null && stage.startedAt !== undefined) row.startedAt = stage.startedAt;
|
||||
if (stage.finishedAt !== null && stage.finishedAt !== undefined) row.finishedAt = stage.finishedAt;
|
||||
return row;
|
||||
}
|
||||
|
||||
function compactListStageTiming(stage: StageTiming): Record<string, unknown> {
|
||||
const row: Record<string, unknown> = {
|
||||
stage: stage.stage,
|
||||
status: stage.status,
|
||||
seconds: stage.seconds,
|
||||
};
|
||||
if (stage.startedAt !== null && stage.startedAt !== undefined) row.startedAt = stage.startedAt;
|
||||
if (stage.finishedAt !== null && stage.finishedAt !== undefined) row.finishedAt = stage.finishedAt;
|
||||
return row;
|
||||
}
|
||||
|
||||
function storedStageTimings(storedTimings: Record<string, unknown> | null): StageTiming[] {
|
||||
if (storedTimings === null) return [];
|
||||
return arrayRecords(storedTimings.stages)
|
||||
@@ -151,6 +165,8 @@ function storedStageTimings(storedTimings: Record<string, unknown> | null): Stag
|
||||
numberOrNull(stage.budgetSeconds),
|
||||
stringOrNull(stage.source) ?? "stored-state",
|
||||
stringOrNull(stage.object),
|
||||
stringOrNull(stage.startedAt),
|
||||
stringOrNull(stage.finishedAt),
|
||||
))
|
||||
.filter((stage) => stage.stage.length > 0)
|
||||
.slice(0, 24);
|
||||
@@ -222,7 +238,7 @@ function stageTimingsFromNativePayload(payload: Record<string, unknown> | null,
|
||||
if (payload === null) return [];
|
||||
const stages: StageTiming[] = [];
|
||||
const statusRead = asOptionalRecord(asOptionalRecord(payload.timings)?.statusRead);
|
||||
stages.push(stageTiming("status-read", "ok", secondsFromMs(numberOrNull(statusRead?.elapsedMs)), numberOrNull(statusRead?.budgetSeconds), "native-status", null));
|
||||
stages.push(stageTiming("status-read", "ok", secondsFromMs(numberOrNull(statusRead?.elapsedMs)), numberOrNull(statusRead?.budgetSeconds), "native-status", null, stringOrNull(statusRead?.startedAt), stringOrNull(statusRead?.finishedAt)));
|
||||
const sourceSyncStage = k8sJobTiming("git-mirror-sync", asOptionalRecord(payload.sourceSync));
|
||||
if (sourceSyncStage !== null) stages.push(sourceSyncStage);
|
||||
const reuseConfig = asOptionalRecord(payload.reuseConfig);
|
||||
@@ -237,18 +253,18 @@ function stageTimingsFromNativePayload(payload: Record<string, unknown> | null,
|
||||
const tekton = asOptionalRecord(payload.tekton);
|
||||
if (tekton !== null) {
|
||||
const status = tekton.succeeded === true ? "succeeded" : tekton.succeeded === false ? `failed:${stringOrNull(tekton.reason) ?? "unknown"}` : "running";
|
||||
stages.push(stageTiming("pipelinerun", status, numberOrNull(tekton.durationSeconds), null, "tekton", stringOrNull(tekton.name)));
|
||||
stages.push(stageTiming("pipelinerun", status, numberOrNull(tekton.durationSeconds), null, "tekton", stringOrNull(tekton.name), stringOrNull(tekton.startTime), stringOrNull(tekton.completionTime)));
|
||||
}
|
||||
const taskRuns = asOptionalRecord(payload.taskRuns);
|
||||
for (const record of taskRuns === null ? [] : prioritizedTaskRunItems(taskRuns)) {
|
||||
const name = stringOrNull(record.pipelineTask) ?? stringOrNull(record.name) ?? "unknown";
|
||||
const status = record.status === "True" ? "succeeded" : record.status === "False" ? `failed:${stringOrNull(record.reason) ?? "unknown"}` : "running";
|
||||
stages.push(stageTiming(`task:${name}`, status, numberOrNull(record.durationSeconds), null, "tekton-taskrun", stringOrNull(record.name)));
|
||||
stages.push(stageTiming(`task:${name}`, status, numberOrNull(record.durationSeconds), null, "tekton-taskrun", stringOrNull(record.name), stringOrNull(record.startTime), stringOrNull(record.completionTime)));
|
||||
}
|
||||
const argo = asOptionalRecord(payload.argo);
|
||||
if (argo !== null) {
|
||||
const sameWindow = total === null || timingOverlapsTotal(total, stringOrNull(argo.operationStartedAt), stringOrNull(argo.operationFinishedAt));
|
||||
stages.push(stageTiming("argo", `${sameWindow ? "" : "current:"}${stringOrNull(argo.syncStatus) ?? "unknown"}/${stringOrNull(argo.healthStatus) ?? "unknown"}`, sameWindow ? numberOrNull(argo.operationDurationSeconds) : null, null, sameWindow ? "argocd" : "argocd-current", stringOrNull(argo.name)));
|
||||
stages.push(stageTiming("argo", `${sameWindow ? "" : "current:"}${stringOrNull(argo.syncStatus) ?? "unknown"}/${stringOrNull(argo.healthStatus) ?? "unknown"}`, sameWindow ? numberOrNull(argo.operationDurationSeconds) : null, null, sameWindow ? "argocd" : "argocd-current", stringOrNull(argo.name), stringOrNull(argo.operationStartedAt), stringOrNull(argo.operationFinishedAt)));
|
||||
}
|
||||
const runtime = asOptionalRecord(payload.runtime);
|
||||
if (runtime !== null) {
|
||||
@@ -296,7 +312,7 @@ function stageTimingsFromCommand(command: Record<string, unknown> | undefined):
|
||||
const tektonSeconds = secondsFromMs(numberOrNull(payload.elapsedMs));
|
||||
if (tektonSeconds !== null) {
|
||||
const status = payload.completed === true ? "completed" : payload.failed === true ? "failed" : payload.stillRunning === true ? "running" : "submitted";
|
||||
stages.push(stageTiming("pipelinerun-wait", status, tektonSeconds, null, "tekton-submit", stringOrNull(command.pipelineRun)));
|
||||
stages.push(stageTiming("pipelinerun-wait", status, tektonSeconds, null, "tekton-submit", stringOrNull(command.pipelineRun), stringOrNull(payload.startedAt), stringOrNull(payload.finishedAt)));
|
||||
}
|
||||
}
|
||||
const closeout = asOptionalRecord(command.closeout);
|
||||
@@ -305,7 +321,7 @@ function stageTimingsFromCommand(command: Record<string, unknown> | undefined):
|
||||
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 ? "over-budget" : "pending";
|
||||
stages.push(stageTiming("closeout", status, secondsFromMs(numberOrNull(closeout.elapsedMs)), null, "k8s-native-closeout", stringOrNull(command.pipelineRun)));
|
||||
stages.push(stageTiming("closeout", status, secondsFromMs(numberOrNull(closeout.elapsedMs)), null, "k8s-native-closeout", stringOrNull(command.pipelineRun), stringOrNull(closeout.startedAt), stringOrNull(closeout.finishedAt)));
|
||||
}
|
||||
return stages;
|
||||
}
|
||||
@@ -313,11 +329,11 @@ function stageTimingsFromCommand(command: Record<string, unknown> | undefined):
|
||||
function k8sJobTiming(stage: string, job: Record<string, unknown> | null, objectOverride?: string | null): StageTiming | null {
|
||||
if (job === null) return null;
|
||||
const status = job.completed === true ? job.reused === true ? "reused" : "completed" : job.failed === true ? "failed" : job.timedOut === true ? "over-budget" : "running";
|
||||
return stageTiming(stage, status, secondsFromMs(numberOrNull(job.elapsedMs)), null, "kubernetes-job", objectOverride ?? stringOrNull(job.jobName));
|
||||
return stageTiming(stage, status, secondsFromMs(numberOrNull(job.elapsedMs)), null, "kubernetes-job", objectOverride ?? stringOrNull(job.jobName), stringOrNull(job.startedAt), stringOrNull(job.finishedAt));
|
||||
}
|
||||
|
||||
function stageTiming(stage: string, status: string, seconds: number | null, budgetSeconds: number | null, source: string, object: string | null): StageTiming {
|
||||
return { stage, status, seconds, budgetSeconds, source, object };
|
||||
function stageTiming(stage: string, status: string, seconds: number | null, budgetSeconds: number | null, source: string, object: string | null, startedAt?: string | null, finishedAt?: string | null): StageTiming {
|
||||
return { stage, status, seconds, budgetSeconds, source, object, startedAt: startedAt ?? null, finishedAt: finishedAt ?? null };
|
||||
}
|
||||
|
||||
function dedupeTimingStages(stages: StageTiming[]): StageTiming[] {
|
||||
|
||||
Reference in New Issue
Block a user