fix: 对齐 runtime GitOps verify terminal 合同

This commit is contained in:
Codex
2026-07-14 00:33:33 +02:00
parent 700b5eec89
commit cb218b61b4
+86 -5
View File
@@ -25,6 +25,12 @@ function exactSkipMarker(records, event) {
&& item.reason === "no-build-no-rollout-plan") || null;
}
function exactRuntimeGitopsVerifyMarker(records) {
return [...records].reverse().find((item) => item.event === "gitops-promote"
&& item.status === "continuing"
&& item.reason === "no-build-no-rollout-plan-gitops-verify") || null;
}
const pacContractTasks = new Set(["plan-artifacts", "collect-artifacts", "gitops-promote"]);
function firstString(...values) {
@@ -365,10 +371,11 @@ function extractPacSourceObservation(recordsInput) {
const plan = [...records].reverse().find((item) => item.event === "pac-delivery-plan" || item.event === "g14-ci-plan") || null;
const collectMarker = exactSkipMarker(records, "collect-artifacts");
const promoteMarker = exactSkipMarker(records, "gitops-promote");
const runtimeGitopsVerifyMarker = exactRuntimeGitopsVerifyMarker(records);
const planTask = exactTaskTerminal(records, "plan-artifacts");
const collectTask = exactTaskTerminal(records, "collect-artifacts");
const promoteTask = exactTaskTerminal(records, "gitops-promote");
if (plan === null && collectMarker === null && promoteMarker === null && planTask === null && collectTask === null && promoteTask === null) return null;
if (plan === null && collectMarker === null && promoteMarker === null && runtimeGitopsVerifyMarker === null && planTask === null && collectTask === null && promoteTask === null) return null;
const affected = stringArray(plan?.affectedServices);
const rollout = stringArray(plan?.rolloutServices);
@@ -384,6 +391,8 @@ function extractPacSourceObservation(recordsInput) {
const noRuntimeChangeMarkers = collectMarker !== null && promoteMarker !== null;
const skipMarkerSeen = collectMarker !== null || promoteMarker !== null;
const skipMarkerConflict = skipMarkerSeen && !noRuntimeChangePlan;
const runtimeGitopsVerifyMarkerConflict = runtimeGitopsVerifyMarker !== null
&& (!noRuntimeChangePlan || skipMarkerSeen);
const deliveryTerminalReady = planTask?.status === "succeeded"
&& collectTask?.status === "succeeded"
&& promoteTask?.status === "succeeded";
@@ -394,10 +403,14 @@ function extractPacSourceObservation(recordsInput) {
let mode = "inconsistent";
let valid = false;
let reason = "structured-plan-or-terminal-marker-is-incomplete";
if (planShapeValid && sourceCommitValid && noRuntimeChangePlan && noRuntimeChangeMarkers) {
if (planShapeValid && sourceCommitValid && noRuntimeChangePlan && noRuntimeChangeMarkers && runtimeGitopsVerifyMarker === null) {
mode = "no-runtime-change";
valid = true;
reason = "no-build-no-rollout-plan";
} else if (planShapeValid && sourceCommitValid && noRuntimeChangePlan && runtimeGitopsVerifyMarker !== null && !runtimeGitopsVerifyMarkerConflict && deliveryTerminalReady) {
mode = "runtime-gitops-verify";
valid = true;
reason = "no-build-no-rollout-plan-gitops-verify";
} else if (planShapeValid && sourceCommitValid && !noRuntimeChangePlan && !skipMarkerConflict && deliveryTerminalReady) {
mode = "delivery";
valid = true;
@@ -406,10 +419,14 @@ function extractPacSourceObservation(recordsInput) {
reason = "source-commit-invalid-or-missing";
} else if (!planShapeValid) {
reason = "delivery-plan-shape-invalid-or-missing";
} else if (runtimeGitopsVerifyMarkerConflict) {
reason = "runtime-gitops-verify-marker-conflicts-with-plan-or-skip-marker";
} else if (skipMarkerConflict) {
reason = "no-runtime-change-marker-conflicts-with-delivery-plan";
} else if (deliveryTerminalFailed) {
reason = "delivery-terminal-failed";
} else if (noRuntimeChangePlan && runtimeGitopsVerifyMarker !== null) {
reason = "runtime-gitops-verify-terminal-evidence-incomplete";
} else if (!noRuntimeChangePlan) {
reason = "delivery-terminal-evidence-incomplete";
}
@@ -440,7 +457,9 @@ function extractPacSourceObservation(recordsInput) {
terminalSources: {
planArtifacts: terminalSource(planTask, plan, "observed", planMarkerSource),
collectArtifacts: terminalSource(collectTask, collectMarker),
gitopsPromote: terminalSource(promoteTask, promoteMarker),
gitopsPromote: runtimeGitopsVerifyMarker === null
? terminalSource(promoteTask, promoteMarker)
: terminalSource(promoteTask, runtimeGitopsVerifyMarker, "continuing", "runtime-gitops-verify-structured-log"),
},
valuesPrinted: false,
};
@@ -602,14 +621,14 @@ function evaluatePacStatus(inputValue) {
const deliveryDisabled = artifact.imageStatus === "disabled";
const deliverySkipped = artifact.imageStatus === "skipped";
const sourceObservationMode = stringOrNull(sourceObservation.mode);
const hwlabCatalogDelivery = sourceObservationMode === "delivery"
const hwlabCatalogDelivery = (sourceObservationMode === "delivery" || sourceObservationMode === "runtime-gitops-verify")
&& sourceObservation.contract === "hwlab-g14-ci-plan";
const noRuntimeChange = sourceObservationMode === "no-runtime-change";
const catalog = record(artifact.catalog);
const catalogPresent = catalog.present === true;
const catalogSourceCommit = stringOrNull(catalog.sourceCommit);
const catalogSourceMatches = catalogSourceCommit !== null && catalogSourceCommit === sourceCommit;
const catalogDeliveryEvidence = sourceObservationMode === "delivery"
const catalogDeliveryEvidence = (sourceObservationMode === "delivery" || sourceObservationMode === "runtime-gitops-verify")
&& sourceObservation.valid === true
&& catalogPresent
&& catalog.status === "published"
@@ -892,6 +911,24 @@ function deliveryObservation(sourceCommit = "c".repeat(40)) {
]);
}
function runtimeGitopsVerifyObservation(sourceCommit = "c".repeat(40)) {
return extractPacSourceObservation([
{
event: "g14-ci-plan",
sourceCommitId: sourceCommit,
affectedServices: [],
rolloutServices: [],
buildServices: [],
reusedServices: Array.from({ length: 8 }, (_item, index) => `service-${index}`),
noImageBuildReason: "test-only-change",
},
{ event: "gitops-promote", status: "continuing", reason: "no-build-no-rollout-plan-gitops-verify" },
{ event: "pac-task-terminal", pipelineTask: "plan-artifacts", taskRun: "plan", status: "succeeded", reason: "Succeeded", results: [] },
{ event: "pac-task-terminal", pipelineTask: "collect-artifacts", taskRun: "collect", status: "succeeded", reason: "Succeeded", results: [] },
{ event: "pac-task-terminal", pipelineTask: "gitops-promote", taskRun: "promote", status: "succeeded", reason: "Succeeded", results: [] },
]);
}
function publishedCatalog(sourceCommit = "c".repeat(40)) {
return { present: true, status: "published", sourceCommit, registryVerified: true };
}
@@ -902,6 +939,7 @@ function runPacStatusFixtureChecks() {
const revision = "b".repeat(40);
const retained = noRuntimeChangeObservation();
const delivery = deliveryObservation();
const runtimeGitopsVerify = runtimeGitopsVerifyObservation();
const exactArgo = { sync: "Synced", health: "Healthy", revision, revisionRelation: { relation: "exact", expectedRevision: revision, observedRevision: revision } };
const cases = [
{
@@ -910,6 +948,24 @@ function runPacStatusFixtureChecks() {
expectedCode: "pac-ready-no-runtime-change",
input: fixtureInput({ artifact: { imageStatus: "retained", sourceObservation: retained } }),
},
{
id: "runtime-gitops-verify-ready",
expectedOk: true,
expectedCode: "pac-ready-gitops-exact",
input: fixtureInput({ artifact: { imageStatus: "reused", digest: digestA, digests: [digestA], gitopsCommit: revision, sourceObservation: runtimeGitopsVerify, catalog: publishedCatalog() }, argo: exactArgo }),
},
{
id: "runtime-gitops-verify-catalog-missing",
expectedOk: false,
expectedCode: "pac-artifact-catalog-missing",
input: fixtureInput({ artifact: { imageStatus: "reused", digest: digestA, digests: [digestA], gitopsCommit: revision, sourceObservation: runtimeGitopsVerify }, argo: exactArgo }),
},
{
id: "runtime-gitops-verify-gitops-missing",
expectedOk: false,
expectedCode: "pac-gitops-missing",
input: fixtureInput({ artifact: { imageStatus: "reused", digest: digestA, digests: [digestA], sourceObservation: runtimeGitopsVerify, catalog: publishedCatalog() }, argo: exactArgo }),
},
{
id: "retained-gitops-missing",
expectedOk: false,
@@ -1000,6 +1056,31 @@ function runPacStatusFixtureChecks() {
expectedCode: "pac-source-observation-inconsistent",
input: fixtureInput({ artifact: { sourceObservation: extractPacSourceObservation([{ event: "g14-ci-plan", sourceCommitId: "c".repeat(40), affectedServices: [], rolloutServices: [], buildServices: [], reusedServices: [] }]) } }),
},
{
id: "runtime-gitops-verify-marker-missing",
expectedOk: false,
expectedCode: "pac-source-observation-inconsistent",
input: fixtureInput({ artifact: { sourceObservation: extractPacSourceObservation([
{ event: "g14-ci-plan", sourceCommitId: "c".repeat(40), affectedServices: [], rolloutServices: [], buildServices: [], reusedServices: ["service"] },
{ event: "pac-task-terminal", pipelineTask: "plan-artifacts", taskRun: "plan", status: "succeeded", reason: "Succeeded", results: [] },
{ event: "pac-task-terminal", pipelineTask: "collect-artifacts", taskRun: "collect", status: "succeeded", reason: "Succeeded", results: [] },
{ event: "pac-task-terminal", pipelineTask: "gitops-promote", taskRun: "promote", status: "succeeded", reason: "Succeeded", results: [] },
]) } }),
},
{
id: "runtime-gitops-verify-marker-conflict",
expectedOk: false,
expectedCode: "pac-source-observation-inconsistent",
input: fixtureInput({ artifact: { sourceObservation: extractPacSourceObservation([
{ event: "g14-ci-plan", sourceCommitId: "c".repeat(40), affectedServices: [], rolloutServices: [], buildServices: [], reusedServices: ["service"] },
{ event: "collect-artifacts", status: "skipped", reason: "no-build-no-rollout-plan" },
{ event: "gitops-promote", status: "skipped", reason: "no-build-no-rollout-plan" },
{ event: "gitops-promote", status: "continuing", reason: "no-build-no-rollout-plan-gitops-verify" },
{ event: "pac-task-terminal", pipelineTask: "plan-artifacts", taskRun: "plan", status: "succeeded", reason: "Succeeded", results: [] },
{ event: "pac-task-terminal", pipelineTask: "collect-artifacts", taskRun: "collect", status: "succeeded", reason: "Succeeded", results: [] },
{ event: "pac-task-terminal", pipelineTask: "gitops-promote", taskRun: "promote", status: "succeeded", reason: "Succeeded", results: [] },
]) } }),
},
{
id: "retained-source-mismatch",
expectedOk: false,