fix: serialize DEV CD apply
This commit is contained in:
@@ -20,6 +20,7 @@ const reportsDir = path.join(repoRoot, "reports/dev-gate");
|
||||
|
||||
const contractIssue = "pikasTech/HWLAB#31";
|
||||
const issueFamily = Object.freeze({
|
||||
DEV_CD_APPLY: "pikasTech/HWLAB#274",
|
||||
DEV_DEPLOY_APPLY: "pikasTech/HWLAB#33",
|
||||
DEV_GATE_PREFLIGHT: "pikasTech/HWLAB#34",
|
||||
DEV_ARTIFACT_PUBLISH: "pikasTech/HWLAB#35",
|
||||
@@ -143,6 +144,32 @@ const requiredDevCloudWorkbenchDocs = [
|
||||
"docs/reference/code-agent-chat-readiness.md"
|
||||
];
|
||||
const reportFamilyTemplates = new Map([
|
||||
[
|
||||
"dev-cd-apply",
|
||||
{
|
||||
issue: issueFamily.DEV_CD_APPLY,
|
||||
requiredDocs: [
|
||||
"docs/reference/deployment-publish.md",
|
||||
"docs/reference/dev-runtime-boundary.md",
|
||||
"docs/dev-artifact-publish.md",
|
||||
"docs/dev-deploy-apply.md",
|
||||
"docs/artifact-catalog.md"
|
||||
],
|
||||
requiredValidationCommands: [
|
||||
"node --check scripts/dev-cd-apply.mjs",
|
||||
"node --check scripts/src/dev-cd-apply.mjs",
|
||||
"node --test scripts/src/dev-cd-apply.test.mjs",
|
||||
"node --check scripts/dev-artifact-publish.mjs",
|
||||
"node --check scripts/src/dev-deploy-apply.mjs",
|
||||
"node --test scripts/src/dev-deploy-apply.test.mjs",
|
||||
"node scripts/deploy-desired-state-plan.mjs --check",
|
||||
"node scripts/validate-artifact-catalog.mjs",
|
||||
"git diff --check"
|
||||
],
|
||||
requiredSmokeCommand: "npm run check",
|
||||
requiredDryRunCommand: "node scripts/dev-deploy-apply.mjs --dry-run --expect-blocked --write-report"
|
||||
}
|
||||
],
|
||||
[
|
||||
"dev-gate-report-contract",
|
||||
{
|
||||
@@ -714,6 +741,9 @@ async function validateReport(relativePath) {
|
||||
if (report.taskId === "dev-deploy-apply") {
|
||||
assertDevDeployApplyReport(report, label);
|
||||
}
|
||||
if (report.taskId === "dev-cd-apply") {
|
||||
assertDevCdApplyReport(report, label);
|
||||
}
|
||||
}
|
||||
|
||||
async function assertDocumentSet(documentsValue, label, requiredDocs) {
|
||||
@@ -937,8 +967,8 @@ function assertDevDeployApplyReport(report, label) {
|
||||
if (plan.conclusion.status === "ready") {
|
||||
assert.equal(plan.manualCommands.status, "ready", `${label}.devDeployApply.manualCommands.status`);
|
||||
assert.ok(
|
||||
plan.manualCommands.afterHumanApproval.includes("node scripts/dev-deploy-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report"),
|
||||
`${label}.devDeployApply.manualCommands.afterHumanApproval missing apply command`
|
||||
plan.manualCommands.afterHumanApproval.includes("node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report"),
|
||||
`${label}.devDeployApply.manualCommands.afterHumanApproval missing transaction apply command`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -963,6 +993,90 @@ function assertDevDeployApplyReport(report, label) {
|
||||
}
|
||||
}
|
||||
|
||||
function assertDevCdApplyReport(report, label) {
|
||||
assert.equal(report.issue, issueFamily.DEV_CD_APPLY, `${label}.issue`);
|
||||
assertStringArray(report.supports, `${label}.supports`, { minLength: 4 });
|
||||
for (const supportedIssue of [
|
||||
"pikasTech/HWLAB#274",
|
||||
"pikasTech/HWLAB#116",
|
||||
"pikasTech/HWLAB#235"
|
||||
]) {
|
||||
assert.ok(report.supports.includes(supportedIssue), `${label}.supports missing ${supportedIssue}`);
|
||||
}
|
||||
|
||||
assertObject(report.transaction, `${label}.transaction`);
|
||||
for (const field of ["transactionId", "ownerTaskId", "targetNamespace", "lockName", "lockBackend", "startedAt", "finishedAt", "ttlSeconds", "phases"]) {
|
||||
assert.ok(Object.hasOwn(report.transaction, field), `${label}.transaction missing ${field}`);
|
||||
}
|
||||
assert.equal(report.transaction.targetNamespace, "hwlab-dev", `${label}.transaction.targetNamespace`);
|
||||
assert.equal(report.transaction.lockName, "hwlab-dev-cd-lock", `${label}.transaction.lockName`);
|
||||
assert.equal(report.transaction.lockBackend, "Lease", `${label}.transaction.lockBackend`);
|
||||
assertString(report.transaction.transactionId, `${label}.transaction.transactionId`);
|
||||
assertString(report.transaction.ownerTaskId, `${label}.transaction.ownerTaskId`);
|
||||
assert.ok(Number.isInteger(report.transaction.ttlSeconds), `${label}.transaction.ttlSeconds`);
|
||||
assertArray(report.transaction.phases, `${label}.transaction.phases`);
|
||||
assert.ok(
|
||||
report.transaction.phases.some((phase) => phase.phase === "publishing"),
|
||||
`${label}.transaction.phases must include publishing`
|
||||
);
|
||||
|
||||
assertObject(report.devCdApply, `${label}.devCdApply`);
|
||||
for (const field of ["mode", "target", "deployJson", "lock", "steps", "liveBefore", "liveVerify", "reportPaths", "safety"]) {
|
||||
assert.ok(Object.hasOwn(report.devCdApply, field), `${label}.devCdApply missing ${field}`);
|
||||
}
|
||||
assert.equal(report.devCdApply.mode, "apply", `${label}.devCdApply.mode`);
|
||||
|
||||
assertObject(report.devCdApply.target, `${label}.devCdApply.target`);
|
||||
assert.equal(report.devCdApply.target.namespace, "hwlab-dev", `${label}.devCdApply.target.namespace`);
|
||||
assert.equal(report.devCdApply.target.apiEndpoint, "http://74.48.78.17:16667", `${label}.devCdApply.target.apiEndpoint`);
|
||||
assert.equal(report.devCdApply.target.browserEndpoint, "http://74.48.78.17:16666/", `${label}.devCdApply.target.browserEndpoint`);
|
||||
assertString(report.devCdApply.target.shortCommitId, `${label}.devCdApply.target.shortCommitId`);
|
||||
|
||||
assertObject(report.devCdApply.deployJson, `${label}.devCdApply.deployJson`);
|
||||
for (const side of ["before", "after"]) {
|
||||
assertObject(report.devCdApply.deployJson[side], `${label}.devCdApply.deployJson.${side}`);
|
||||
assert.equal(report.devCdApply.deployJson[side].path, "deploy/deploy.json", `${label}.devCdApply.deployJson.${side}.path`);
|
||||
assertString(report.devCdApply.deployJson[side].hash, `${label}.devCdApply.deployJson.${side}.hash`);
|
||||
assertString(report.devCdApply.deployJson[side].commitId, `${label}.devCdApply.deployJson.${side}.commitId`);
|
||||
}
|
||||
|
||||
assertObject(report.devCdApply.lock, `${label}.devCdApply.lock`);
|
||||
assert.equal(typeof report.devCdApply.lock.acquired, "boolean", `${label}.devCdApply.lock.acquired`);
|
||||
|
||||
assertArray(report.devCdApply.steps, `${label}.devCdApply.steps`);
|
||||
for (const [index, step] of report.devCdApply.steps.entries()) {
|
||||
const stepLabel = `${label}.devCdApply.steps[${index}]`;
|
||||
assertObject(step, stepLabel);
|
||||
for (const field of ["id", "phase", "status", "command", "code", "startedAt", "finishedAt"]) {
|
||||
assert.ok(Object.hasOwn(step, field), `${stepLabel} missing ${field}`);
|
||||
}
|
||||
assert.ok(["publishing", "applying"].includes(step.phase), `${stepLabel}.phase`);
|
||||
assert.ok(["pass", "blocked"].includes(step.status), `${stepLabel}.status`);
|
||||
assertString(step.command, `${stepLabel}.command`);
|
||||
}
|
||||
|
||||
assertObject(report.devCdApply.liveVerify, `${label}.devCdApply.liveVerify`);
|
||||
assert.ok(["pass", "blocked", "not_run"].includes(report.devCdApply.liveVerify.status), `${label}.devCdApply.liveVerify.status`);
|
||||
assertArray(report.devCdApply.liveVerify.endpoints, `${label}.devCdApply.liveVerify.endpoints`);
|
||||
assertObject(report.devCdApply.liveVerify.summary, `${label}.devCdApply.liveVerify.summary`);
|
||||
if (report.devCdApply.liveVerify.status !== "not_run") {
|
||||
const urls = report.devCdApply.liveVerify.endpoints.map((endpoint) => endpoint.url);
|
||||
assert.ok(urls.includes("http://74.48.78.17:16666/health/live"), `${label}.devCdApply.liveVerify missing 16666 health`);
|
||||
assert.ok(urls.includes("http://74.48.78.17:16667/health/live"), `${label}.devCdApply.liveVerify missing 16667 health`);
|
||||
}
|
||||
|
||||
assertObject(report.devCdApply.reportPaths, `${label}.devCdApply.reportPaths`);
|
||||
assert.equal(report.devCdApply.reportPaths.artifacts, "reports/dev-gate/dev-artifacts.json", `${label}.devCdApply.reportPaths.artifacts`);
|
||||
assert.equal(report.devCdApply.reportPaths.deployApply, "reports/dev-gate/dev-deploy-report.json", `${label}.devCdApply.reportPaths.deployApply`);
|
||||
|
||||
assertObject(report.devCdApply.safety, `${label}.devCdApply.safety`);
|
||||
assert.equal(report.devCdApply.safety.prodTouched, false, `${label}.devCdApply.safety.prodTouched`);
|
||||
assert.equal(report.devCdApply.safety.secretValuesRead, false, `${label}.devCdApply.safety.secretValuesRead`);
|
||||
assert.equal(report.devCdApply.safety.secretValuesPrinted, false, `${label}.devCdApply.safety.secretValuesPrinted`);
|
||||
assert.equal(report.devCdApply.safety.oldPublicPortsUsed, false, `${label}.devCdApply.safety.oldPublicPortsUsed`);
|
||||
assert.equal(report.devCdApply.safety.singleLock, "Lease/hwlab-dev/hwlab-dev-cd-lock", `${label}.devCdApply.safety.singleLock`);
|
||||
}
|
||||
|
||||
|
||||
function assertShaOrNotPublished(value, label) {
|
||||
assertString(value, label);
|
||||
|
||||
Reference in New Issue
Block a user