diff --git a/scripts/hwlab-g14-contract-test.ts b/scripts/hwlab-g14-contract-test.ts index 81c9cbc6..22af130d 100644 --- a/scripts/hwlab-g14-contract-test.ts +++ b/scripts/hwlab-g14-contract-test.ts @@ -480,6 +480,12 @@ assertCondition( && sourceText.includes("protected-latest-pipelinerun"), "control-plane cleanup-runs must protect the latest PipelineRun per lane by default", ); +assertCondition( + sourceText.includes("selectedReason: ageMinutes === null ? \"missing-creation-timestamp\" : \"below-min-age\"") + && sourceText.includes("target-pipelinerun-not-found-or-not-terminal") + && sourceText.indexOf("const target = terminalRuns.find((item) => item.name === targetPipelineRun)") < sourceText.indexOf("target-pipelinerun-not-found-or-not-terminal"), + "targeted cleanup-runs must report below-min-age terminal PipelineRuns instead of hiding them as not found", +); assertCondition( hwlabHelpUsage.some((line) => line.includes("hwlab nodes control-plane cleanup-runs --node G14 --lane v03 --pipeline-run")) && hwlabHelpUsage.some((line) => line.includes("hwlab nodes control-plane cleanup-runs --node G14 --lane v03 --source-commit")) diff --git a/scripts/src/hwlab-g14.ts b/scripts/src/hwlab-g14.ts index e5d3052e..79aaf0d2 100644 --- a/scripts/src/hwlab-g14.ts +++ b/scripts/src/hwlab-g14.ts @@ -2629,26 +2629,37 @@ function listCleanupPipelineRuns(options: G14ControlPlaneOptions): Record String(b.createdAt).localeCompare(String(a.createdAt)))[0]; if (latest !== undefined) protectedLatestByPrefix.set(prefix, latest.name); } + if (targetPipelineRun !== undefined) { + const target = terminalRuns.find((item) => item.name === targetPipelineRun); + if (target === undefined) { + return [{ + name: targetPipelineRun, + createdAt: null, + ageMinutes: null, + status: null, + reason: "target-pipelinerun-not-found-or-not-terminal", + selected: false, + }]; + } + const ageMinutes = typeof target.ageMinutes === "number" ? target.ageMinutes : null; + const belowMinAge = ageMinutes === null || ageMinutes < options.minAgeMinutes; + return [{ + ...target, + selected: !belowMinAge, + ...(belowMinAge + ? { selectedReason: ageMinutes === null ? "missing-creation-timestamp" : "below-min-age" } + : {}), + }]; + } const candidates = terminalRuns - .filter((item) => targetPipelineRun === undefined || item.name === targetPipelineRun) .filter((item) => typeof item.ageMinutes === "number" && item.ageMinutes >= options.minAgeMinutes) .map((item) => { - const protectedLatest = targetPipelineRun === undefined && [...protectedLatestByPrefix.values()].includes(item.name); + const protectedLatest = [...protectedLatestByPrefix.values()].includes(item.name); return protectedLatest ? { ...item, selected: false, selectedReason: "protected-latest-pipelinerun" } : item; }) .slice(0, options.limit); - if (targetPipelineRun !== undefined && candidates.length === 0) { - return [{ - name: targetPipelineRun, - createdAt: null, - ageMinutes: null, - status: null, - reason: "target-pipelinerun-not-found-or-not-terminal", - selected: false, - }]; - } return candidates; }