Formalize Cloud Web DEV CD contract

Merge PR #152 after Code Queue rebase and validation. This lands the DEV Cloud Web publish/apply contract, dist freshness checks, artifact identity evidence, and read-only rollout observation. No PROD changes and no live deploy claim.
This commit is contained in:
Lyon
2026-05-23 00:20:19 +08:00
committed by GitHub
parent eb710860dd
commit a44438779f
11 changed files with 509 additions and 85 deletions
+66
View File
@@ -585,13 +585,37 @@ async function validateReport(relativePath) {
const serviceLabel = `${label}.artifactPublish.services[${index}]`;
assertObject(service, serviceLabel);
assertString(service.serviceId, `${serviceLabel}.serviceId`);
if (Object.hasOwn(service, "sourceCommitId")) {
assertString(service.sourceCommitId, `${serviceLabel}.sourceCommitId`);
}
assertString(service.status, `${serviceLabel}.status`);
assertString(service.image, `${serviceLabel}.image`);
assertString(service.imageTag, `${serviceLabel}.imageTag`);
assertShaOrNotPublished(service.digest, `${serviceLabel}.digest`);
assertString(service.implementationState, `${serviceLabel}.implementationState`);
assertString(service.sourceState, `${serviceLabel}.sourceState`);
assert.ok(
artifactSourceStates.has(service.sourceState),
`${serviceLabel}.sourceState must be source-present or intentionally-disabled`
);
if (Object.hasOwn(service, "distFreshness")) {
assertObject(service.distFreshness, `${serviceLabel}.distFreshness`);
assert.equal(service.distFreshness.status, "pass", `${serviceLabel}.distFreshness.status`);
assert.equal(service.distFreshness.distPath, "web/hwlab-cloud-web/dist", `${serviceLabel}.distFreshness.distPath`);
assert.equal(
service.distFreshness.buildCommand,
"node web/hwlab-cloud-web/scripts/build.mjs",
`${serviceLabel}.distFreshness.buildCommand`
);
assert.equal(
service.distFreshness.freshnessCommand,
"node web/hwlab-cloud-web/scripts/build.mjs",
`${serviceLabel}.distFreshness.freshnessCommand`
);
assertArray(service.distFreshness.files, `${serviceLabel}.distFreshness.files`);
assertArray(service.distFreshness.mismatches, `${serviceLabel}.distFreshness.mismatches`);
assert.equal(service.distFreshness.mismatches.length, 0, `${serviceLabel}.distFreshness.mismatches`);
}
if (service.sourceState === "intentionally-disabled") {
assert.equal(service.entrypoint, null, `${serviceLabel}.entrypoint must be null when intentionally disabled`);
}
@@ -813,6 +837,48 @@ function assertDevDeployApplyReport(report, label) {
assertString(replacement.reason, `${replacementLabel}.reason`);
}
if (Object.hasOwn(plan, "cloudWebRollout")) {
assertObject(plan.cloudWebRollout, `${label}.devDeployApply.cloudWebRollout`);
for (const field of [
"serviceId",
"namespace",
"status",
"sourceCommitId",
"image",
"imageTag",
"digest",
"publishState",
"rolloutRevision",
"liveImage",
"imageMatchesDesired",
"verificationCommand",
"readCommand"
]) {
assert.ok(Object.hasOwn(plan.cloudWebRollout, field), `${label}.devDeployApply.cloudWebRollout missing ${field}`);
}
assert.equal(plan.cloudWebRollout.serviceId, "hwlab-cloud-web", `${label}.devDeployApply.cloudWebRollout.serviceId`);
assert.equal(plan.cloudWebRollout.namespace, "hwlab-dev", `${label}.devDeployApply.cloudWebRollout.namespace`);
assert.ok(["observed", "blocked", "not_evaluated"].includes(plan.cloudWebRollout.status), `${label}.devDeployApply.cloudWebRollout.status`);
assertString(plan.cloudWebRollout.sourceCommitId, `${label}.devDeployApply.cloudWebRollout.sourceCommitId`);
assertString(plan.cloudWebRollout.image, `${label}.devDeployApply.cloudWebRollout.image`);
assertString(plan.cloudWebRollout.imageTag, `${label}.devDeployApply.cloudWebRollout.imageTag`);
assertShaOrNotPublished(plan.cloudWebRollout.digest, `${label}.devDeployApply.cloudWebRollout.digest`);
if (plan.cloudWebRollout.rolloutRevision !== null) {
assertString(plan.cloudWebRollout.rolloutRevision, `${label}.devDeployApply.cloudWebRollout.rolloutRevision`);
}
if (plan.cloudWebRollout.liveImage !== null) {
assertString(plan.cloudWebRollout.liveImage, `${label}.devDeployApply.cloudWebRollout.liveImage`);
}
assert.equal(typeof plan.cloudWebRollout.imageMatchesDesired, "boolean", `${label}.devDeployApply.cloudWebRollout.imageMatchesDesired`);
assert.match(plan.cloudWebRollout.verificationCommand, /rollout status deployment\/hwlab-cloud-web/u, `${label}.devDeployApply.cloudWebRollout.verificationCommand`);
assert.match(plan.cloudWebRollout.verificationCommand, /^KUBECONFIG=\/etc\/rancher\/k3s\/k3s\.yaml kubectl /u, `${label}.devDeployApply.cloudWebRollout.verificationCommand`);
assert.match(plan.cloudWebRollout.readCommand, /get deployment hwlab-cloud-web/u, `${label}.devDeployApply.cloudWebRollout.readCommand`);
assert.match(plan.cloudWebRollout.readCommand, /^KUBECONFIG=\/etc\/rancher\/k3s\/k3s\.yaml kubectl /u, `${label}.devDeployApply.cloudWebRollout.readCommand`);
if (plan.cloudWebRollout.status === "blocked") {
assertString(plan.cloudWebRollout.blocker, `${label}.devDeployApply.cloudWebRollout.blocker`);
}
}
assertObject(plan.manualCommands, `${label}.devDeployApply.manualCommands`);
assert.ok(["blocked", "ready"].includes(plan.manualCommands.status), `${label}.devDeployApply.manualCommands.status`);
assertCommandList(plan.manualCommands.beforeHumanApproval, `${label}.devDeployApply.manualCommands.beforeHumanApproval`);