Remove repo reports and add recurrence guard

This commit is contained in:
Code Queue Review
2026-05-24 02:23:27 +00:00
parent 0c53c94714
commit 4e302faee9
83 changed files with 1042 additions and 27077 deletions
+33 -30
View File
@@ -12,24 +12,25 @@ import {
redactSensitiveText,
resolveDevKubeconfigSelection
} from "./dev-deploy-apply.mjs";
import { ensureNotRepoReportsPath, tempReportPath } from "./report-paths.mjs";
const defaultRepoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
const defaultNamespace = "hwlab-dev";
const defaultLockName = "hwlab-dev-cd-lock";
const defaultTtlSeconds = 3600;
const defaultReportPath = "reports/dev-gate/dev-cd-apply.json";
const defaultReportPath = tempReportPath("dev-cd-apply.json");
const d601NativeKubeconfigPath = "/etc/rancher/k3s/k3s.yaml";
const artifactCatalogPath = "deploy/artifact-catalog.dev.json";
const artifactReportPath = "reports/dev-gate/dev-artifacts.json";
const artifactReportPath = tempReportPath("dev-artifacts.json");
const artifactDesiredStatePaths = [
"deploy/artifact-catalog.dev.json",
"deploy/deploy.json",
"deploy/k8s/base/workloads.yaml",
"reports/dev-gate/dev-artifacts.json"
"deploy/k8s/base/workloads.yaml"
];
const runtimeProvisioningReportPath = "reports/dev-gate/dev-runtime-provisioning-report.json";
const runtimeMigrationReportPath = "reports/dev-gate/dev-runtime-migration-report.json";
const runtimePostflightReportPath = "reports/dev-gate/dev-runtime-postflight-report.json";
const runtimeProvisioningReportPath = tempReportPath("dev-runtime-provisioning-report.json");
const runtimeMigrationReportPath = tempReportPath("dev-runtime-migration-report.json");
const runtimePostflightReportPath = tempReportPath("dev-runtime-postflight-report.json");
const deployApplyReportPath = tempReportPath("dev-deploy-report.json");
const runtimeJobReportPrefix = "/tmp/hwlab-dev-runtime-report";
const browserLiveUrl = "http://74.48.78.17:16666/health/live";
const apiLiveUrl = `${DEV_ENDPOINT}/health/live`;
@@ -103,9 +104,6 @@ export function parseArgs(argv) {
} else if (arg === "--confirmed-non-production") {
args.confirmedNonProduction = true;
args.flags.add(arg);
} else if (arg === "--write-report") {
args.writeReport = true;
args.flags.add(arg);
} else if (arg === "--break-stale-lock") {
args.breakStaleLock = true;
args.flags.add(arg);
@@ -124,6 +122,7 @@ export function parseArgs(argv) {
args.flags.add(arg);
} else if (arg === "--report") {
args.reportPath = readOption(argv, ++index, arg);
args.writeReport = true;
args.flags.add(arg);
} else if (arg === "--target-ref") {
args.targetRef = readOption(argv, ++index, arg);
@@ -182,7 +181,7 @@ export function usage() {
examples: [
"node scripts/dev-cd-apply.mjs --status",
"node scripts/dev-cd-apply.mjs --dry-run",
"node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --write-report"
`node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --report ${defaultReportPath}`
],
options: {
"--status": "Read-only status: target ref, deploy.json, current Lease, and public live health.",
@@ -195,8 +194,7 @@ export function usage() {
"--ttl-seconds SECONDS": "lock TTL; default: 3600",
"--owner-task-id ID": "lock holder; default: Code Queue/env/user derived",
"--break-stale-lock": "May take over an expired lock only with --confirm-dev.",
"--report PATH": `default: ${defaultReportPath}`,
"--write-report": "Write the full report to --report.",
"--report PATH": `write the full transaction JSON outside the repo; packaged scripts use ${defaultReportPath}`,
"--full-output": "Print the full report to stdout instead of the concise summary.",
"--skip-runtime-postflight": "Skip the M3/durable runtime postflight while still applying DEV and verifying 16666/16667 health.",
"--skip-live-verify": "test-only escape hatch; do not use for DEV acceptance"
@@ -326,7 +324,8 @@ async function readDeployJson(repoRoot) {
async function readJsonFileSummary(repoRoot, relativePath, summarize) {
try {
const raw = await readFile(path.join(repoRoot, relativePath), "utf8");
const absolutePath = path.isAbsolute(relativePath) ? relativePath : path.join(repoRoot, relativePath);
const raw = await readFile(absolutePath, "utf8");
const json = JSON.parse(raw);
return {
path: relativePath,
@@ -1854,7 +1853,7 @@ function stepBlockerSafeNextAction(stepResult) {
if (stepResult.id === "runtime-db-provisioning") return "Repair repo-owned runtime provisioning inputs/SecretRefs without printing Secret values, then rerun DEV CD.";
if (stepResult.id === "runtime-db-migration") return "Repair repo-owned runtime migration/schema state, then rerun DEV CD.";
if (stepResult.id === "runtime-durable-postflight") return "Inspect the runtime postflight report, repair durable readiness or M3 evidence persistence, then rerun DEV CD after host-controlled rollout if needed.";
if (stepResult.id === "dev-deploy-apply") return "Inspect reports/dev-gate/dev-deploy-report.json and rerun the repo-owned DEV CD path after the apply blocker is fixed.";
if (stepResult.id === "dev-deploy-apply") return `Inspect ${deployApplyReportPath} and rerun the repo-owned DEV CD path after the apply blocker is fixed.`;
return "Fix the reported step blocker and rerun the repo-owned DEV CD transaction.";
}
@@ -2165,8 +2164,8 @@ function buildStatusNextActions({ target, deployBefore, lock, liveVerify }) {
}
if (actions.length === 0) {
actions.push(target.publishRequired === false
? "Run --apply --confirm-dev --confirmed-non-production --write-report when ready to apply the published deploy.json promotion without republishing HEAD."
: "Run --apply --confirm-dev --confirmed-non-production --write-report when ready to publish/apply DEV.");
? `Run --apply --confirm-dev --confirmed-non-production --report ${defaultReportPath} when ready to apply the published deploy.json promotion without republishing HEAD.`
: `Run --apply --confirm-dev --confirmed-non-production --report ${defaultReportPath} when ready to publish/apply DEV.`);
}
return actions;
}
@@ -2229,7 +2228,7 @@ async function runDevCdStatus(args, ctx, stdout) {
live: compactLiveReport(liveVerify),
liveDelta,
nextActions: buildStatusNextActions({ target, deployBefore, lock, liveVerify }),
fullOutputHint: "Use --apply --confirm-dev --confirmed-non-production --write-report for the full transaction report; use --full-output only when stdout needs the full JSON."
fullOutputHint: `Use --apply --confirm-dev --confirmed-non-production --report ${defaultReportPath} for the full transaction JSON; use --full-output only when stdout needs the full JSON.`
};
stdout.write(`${JSON.stringify(report, null, 2)}\n`);
return 0;
@@ -2284,7 +2283,7 @@ function summarizeDevCdApplyReport(report) {
} : null,
blockers: report.blockers ?? [],
reportPaths: apply.reportPaths ?? {},
fullOutputHint: "Use --full-output to print the full report to stdout. Use --write-report to persist the full report."
fullOutputHint: `Use --full-output to print the full report to stdout. Use --report ${defaultReportPath} to persist the full report outside the repo.`
};
}
@@ -2307,7 +2306,7 @@ function buildReport({
}) {
return {
$schema: "https://hwlab.pikastech.local/schemas/dev-cd-apply.schema.json",
$id: "https://hwlab.pikastech.local/reports/dev-gate/dev-cd-apply.json",
$id: "https://hwlab.pikastech.local/dev-cd/dev-cd-apply.json",
reportVersion: "v1",
issue: "pikasTech/HWLAB#274",
taskId: "dev-cd-apply",
@@ -2357,7 +2356,7 @@ function buildReport({
},
dryRun: {
status: "not_run",
commands: ["node scripts/dev-deploy-apply.mjs --dry-run --expect-blocked --write-report"],
commands: [`node scripts/dev-deploy-apply.mjs --dry-run --expect-blocked --report ${deployApplyReportPath}`],
evidence: ["The transaction path owns live side effects; dry-run remains a preflight support mode."],
summary: "DEV CD mutation requires --apply and the transaction Lease lock."
},
@@ -2422,7 +2421,7 @@ function buildReport({
reportPaths: {
transaction: args.writeReport ? args.reportPath : null,
artifacts: artifactReportPath,
deployApply: "reports/dev-gate/dev-deploy-report.json",
deployApply: deployApplyReportPath,
runtimeProvisioning: runtimeProvisioningReportPath,
runtimeMigration: runtimeMigrationReportPath,
runtimePostflight: runtimePostflightReportPath
@@ -2544,7 +2543,7 @@ export async function runDevCdApply(argv, io = {}) {
type: "contract_blocker",
scope: "artifact-boundary",
status: "open",
summary: "deploy/deploy.json, deploy/artifact-catalog.dev.json, reports/dev-gate/dev-artifacts.json, and the artifact merge parent must resolve to the same promotion commit before apply."
summary: "deploy/deploy.json, deploy/artifact-catalog.dev.json, deploy/k8s/base/workloads.yaml, and the artifact merge parent must resolve to the same promotion commit before apply."
});
throw new DevCdApplyError("artifact desired-state provenance does not match the deploy.json promotion", {
code: "artifact-boundary-provenance-mismatch",
@@ -2635,7 +2634,7 @@ export async function runDevCdApply(argv, io = {}) {
id: "artifact-publish",
phase: "publishing",
command: process.execPath,
args: ["scripts/dev-artifact-publish.mjs", "--publish"],
args: ["scripts/dev-artifact-publish.mjs", "--publish", "--report", artifactReportPath],
timeoutMs: 60 * 60 * 1000,
reportPath: artifactReportPath
},
@@ -2686,7 +2685,8 @@ export async function runDevCdApply(argv, io = {}) {
"--apply",
"--confirm-dev",
"--confirmed-non-production",
"--write-report",
"--report",
runtimeProvisioningReportPath,
"--fail-on-blocked"
],
timeoutMs: 5 * 60 * 1000,
@@ -2702,7 +2702,8 @@ export async function runDevCdApply(argv, io = {}) {
"--apply",
"--confirm-dev",
"--confirmed-non-production",
"--write-report",
"--report",
runtimeMigrationReportPath,
"--fail-on-blocked"
],
timeoutMs: 5 * 60 * 1000,
@@ -2717,11 +2718,12 @@ export async function runDevCdApply(argv, io = {}) {
"--apply",
"--confirm-dev",
"--confirmed-non-production",
"--write-report",
"--report",
deployApplyReportPath,
...(args.kubeconfig ? ["--kubeconfig", args.kubeconfig] : [])
],
timeoutMs: 20 * 60 * 1000,
reportPath: "reports/dev-gate/dev-deploy-report.json"
reportPath: deployApplyReportPath
},
...(
args.skipRuntimePostflight
@@ -2737,7 +2739,8 @@ export async function runDevCdApply(argv, io = {}) {
"--confirmed-non-production",
"--target",
"api",
"--write-report",
"--report",
runtimePostflightReportPath,
"--fail-on-blocked"
],
timeoutMs: 2 * 60 * 1000,
@@ -2871,7 +2874,7 @@ export async function runDevCdApply(argv, io = {}) {
});
if (args.writeReport) {
const absoluteReportPath = path.resolve(ctx.repoRoot, args.reportPath);
const absoluteReportPath = ensureNotRepoReportsPath(ctx.repoRoot, args.reportPath, "--report");
await mkdir(path.dirname(absoluteReportPath), { recursive: true });
await writeFile(absoluteReportPath, `${JSON.stringify(report, null, 2)}\n`);
}