cicd branch follower native closeout
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
const key = process.argv[2] || "";
|
||||
const input = JSON.parse(readFileSync(0, "utf8"));
|
||||
|
||||
function cleanMap(value) {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) return {};
|
||||
const out = {};
|
||||
for (const [k, v] of Object.entries(value)) {
|
||||
if (k === "kubectl.kubernetes.io/last-applied-configuration") continue;
|
||||
out[k] = v;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function metadata(obj) {
|
||||
return {
|
||||
name: obj?.metadata?.name || null,
|
||||
namespace: obj?.metadata?.namespace || null,
|
||||
labels: cleanMap(obj?.metadata?.labels),
|
||||
annotations: cleanMap(obj?.metadata?.annotations),
|
||||
};
|
||||
}
|
||||
|
||||
function compactContainer(container) {
|
||||
return {
|
||||
name: container?.name || null,
|
||||
image: container?.image || null,
|
||||
env: Array.isArray(container?.env)
|
||||
? container.env.filter((item) => item && typeof item.name === "string" && typeof item.value === "string").map((item) => ({ name: item.name, value: item.value }))
|
||||
: [],
|
||||
};
|
||||
}
|
||||
|
||||
function condition(obj, type) {
|
||||
const conditions = Array.isArray(obj?.status?.conditions) ? obj.status.conditions : [];
|
||||
return conditions.find((item) => item?.type === type) || conditions[0] || null;
|
||||
}
|
||||
|
||||
function timestampMs(value) {
|
||||
const parsed = Date.parse(String(value || ""));
|
||||
return Number.isFinite(parsed) ? parsed : null;
|
||||
}
|
||||
|
||||
function durationSeconds(start, end) {
|
||||
const s = timestampMs(start);
|
||||
const e = timestampMs(end);
|
||||
return s === null || e === null || e < s ? null : Math.round((e - s) / 1000);
|
||||
}
|
||||
|
||||
let output = input;
|
||||
if (key === "pipelineRun") {
|
||||
const succeeded = condition(input, "Succeeded");
|
||||
output = {
|
||||
apiVersion: input.apiVersion,
|
||||
kind: input.kind,
|
||||
metadata: metadata(input),
|
||||
spec: { params: Array.isArray(input?.spec?.params) ? input.spec.params : [] },
|
||||
status: {
|
||||
conditions: Array.isArray(input?.status?.conditions) ? input.status.conditions : [],
|
||||
startTime: input?.status?.startTime || null,
|
||||
completionTime: input?.status?.completionTime || null,
|
||||
durationSeconds: durationSeconds(input?.status?.startTime, input?.status?.completionTime),
|
||||
succeeded: succeeded?.status || null,
|
||||
reason: succeeded?.reason || null,
|
||||
},
|
||||
};
|
||||
} else if (key === "taskRuns") {
|
||||
const items = (Array.isArray(input?.items) ? input.items : []).map((item) => {
|
||||
const succeeded = condition(item, "Succeeded");
|
||||
return {
|
||||
name: item?.metadata?.name || null,
|
||||
namespace: item?.metadata?.namespace || null,
|
||||
pipelineTask: item?.metadata?.labels?.["tekton.dev/pipelineTask"] || item?.metadata?.labels?.["tekton.dev/task"] || null,
|
||||
status: succeeded?.status || null,
|
||||
reason: succeeded?.reason || null,
|
||||
startTime: item?.status?.startTime || null,
|
||||
completionTime: item?.status?.completionTime || null,
|
||||
durationSeconds: durationSeconds(item?.status?.startTime, item?.status?.completionTime),
|
||||
};
|
||||
}).sort((left, right) => String(left.startTime || "").localeCompare(String(right.startTime || "")));
|
||||
const slow = items.filter((item) => typeof item.durationSeconds === "number" && item.durationSeconds > 60);
|
||||
output = {
|
||||
ok: true,
|
||||
count: items.length,
|
||||
succeededCount: items.filter((item) => item.status === "True").length,
|
||||
failedCount: items.filter((item) => item.status === "False").length,
|
||||
activeCount: items.filter((item) => item.status !== "True" && item.status !== "False").length,
|
||||
items,
|
||||
performance: { slowCount: slow.length, slowTaskRuns: slow.slice(0, 8), warning: slow.length > 0 ? "taskrun-over-60s" : null },
|
||||
statusAuthority: "kubernetes-api-serviceaccount",
|
||||
};
|
||||
} else if (key === "argoApplication") {
|
||||
output = {
|
||||
apiVersion: input.apiVersion,
|
||||
kind: input.kind,
|
||||
metadata: metadata(input),
|
||||
status: {
|
||||
sync: input?.status?.sync || null,
|
||||
health: input?.status?.health || null,
|
||||
operationState: input?.status?.operationState
|
||||
? { phase: input.status.operationState.phase || null, message: input.status.operationState.message || null, finishedAt: input.status.operationState.finishedAt || null }
|
||||
: null,
|
||||
},
|
||||
};
|
||||
} else if (/^workload\d+$/.test(key)) {
|
||||
const template = input?.spec?.template || {};
|
||||
output = {
|
||||
apiVersion: input.apiVersion,
|
||||
kind: input.kind,
|
||||
metadata: metadata(input),
|
||||
spec: {
|
||||
replicas: input?.spec?.replicas ?? null,
|
||||
template: {
|
||||
metadata: { labels: cleanMap(template?.metadata?.labels), annotations: cleanMap(template?.metadata?.annotations) },
|
||||
spec: { containers: Array.isArray(template?.spec?.containers) ? template.spec.containers.map(compactContainer) : [] },
|
||||
},
|
||||
},
|
||||
status: {
|
||||
replicas: input?.status?.replicas ?? null,
|
||||
readyReplicas: input?.status?.readyReplicas ?? null,
|
||||
availableReplicas: input?.status?.availableReplicas ?? null,
|
||||
updatedReplicas: input?.status?.updatedReplicas ?? null,
|
||||
conditions: Array.isArray(input?.status?.conditions) ? input.status.conditions.map((item) => ({ type: item.type || null, status: item.status || null, reason: item.reason || null })) : [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(output));
|
||||
Reference in New Issue
Block a user