72 lines
2.4 KiB
JavaScript
72 lines
2.4 KiB
JavaScript
import { createHash } from "node:crypto";
|
|
|
|
export const CI_PLAN_IDENTITY_VERSION = "v1";
|
|
|
|
export function attachCiPlanIdentity(plan, context = {}) {
|
|
const canonical = canonicalCiPlanIdentity(plan, context);
|
|
const digest = createHash("sha256").update(stableStringify(canonical)).digest("hex");
|
|
return {
|
|
...plan,
|
|
planIdentity: {
|
|
version: CI_PLAN_IDENTITY_VERSION,
|
|
value: `sha256:${digest}`,
|
|
inputs: canonical.inputs,
|
|
scope: canonical.scope
|
|
}
|
|
};
|
|
}
|
|
|
|
export function canonicalCiPlanIdentity(plan, context = {}) {
|
|
const services = Array.isArray(plan?.services) ? plan.services : [];
|
|
return {
|
|
version: CI_PLAN_IDENTITY_VERSION,
|
|
inputs: {
|
|
target: text(context.releaseTarget),
|
|
consumer: text(context.releaseConsumer),
|
|
lane: text(plan?.compatibility?.lane),
|
|
sourceCommitId: text(plan?.sourceCommitId),
|
|
baseCommitId: text(plan?.baseCommitId),
|
|
catalog: {
|
|
authority: text(plan?.artifactCatalog?.authority),
|
|
sourceCommitId: text(plan?.artifactCatalog?.catalogSourceCommitId),
|
|
digest: text(plan?.artifactCatalog?.catalogSha256),
|
|
gitopsCommitId: text(plan?.artifactCatalog?.gitopsCommitId)
|
|
},
|
|
registryProbe: {
|
|
enabled: plan?.inputs?.verifyReuseRegistry === true,
|
|
services: services.map((service) => ({
|
|
serviceId: text(service?.serviceId),
|
|
status: text(service?.reuseRegistry?.status),
|
|
image: text(service?.reuseRegistry?.image),
|
|
digest: text(service?.reuseRegistry?.digest)
|
|
})).filter((service) => service.serviceId).sort(compareServiceId)
|
|
}
|
|
},
|
|
scope: {
|
|
buildServices: sortedStrings(plan?.buildServices),
|
|
rolloutServices: sortedStrings(plan?.rolloutServices),
|
|
affectedServices: sortedStrings(plan?.affectedServices)
|
|
}
|
|
};
|
|
}
|
|
|
|
export function stableStringify(value) {
|
|
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
if (value && typeof value === "object") {
|
|
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`).join(",")}}`;
|
|
}
|
|
return JSON.stringify(value);
|
|
}
|
|
|
|
function sortedStrings(value) {
|
|
return [...new Set(Array.isArray(value) ? value.map(text).filter(Boolean) : [])].sort();
|
|
}
|
|
|
|
function compareServiceId(left, right) {
|
|
return left.serviceId.localeCompare(right.serviceId);
|
|
}
|
|
|
|
function text(value) {
|
|
return typeof value === "string" ? value.trim() : "";
|
|
}
|