完善(08-09-deployment-contract-single-source-harness): 收敛部署合同并补失败路径
这个提交包含在:
@@ -7,6 +7,7 @@ import { isIP } from "node:net";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { deriveCandidateBuildEnv } from "./check-source-provenance.mjs";
|
||||
|
||||
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
||||
const ROOT_DIR = path.resolve(SCRIPT_DIR, "../..");
|
||||
@@ -275,8 +276,12 @@ function main() {
|
||||
|
||||
if (process.env.CANDIDATE_COMMIT == null) fail("CANDIDATE_COMMIT_MISSING");
|
||||
const candidateCommit = String(process.env.CANDIDATE_COMMIT).trim();
|
||||
if (!/^[0-9a-f]{40,64}$/iu.test(candidateCommit)) fail("CANDIDATE_COMMIT_INVALID");
|
||||
const candidateShortCommit = candidateCommit.slice(0, 12);
|
||||
let candidateBuildEnv;
|
||||
try {
|
||||
candidateBuildEnv = deriveCandidateBuildEnv(candidateCommit);
|
||||
} catch {
|
||||
fail("CANDIDATE_COMMIT_INVALID");
|
||||
}
|
||||
const candidateManifest = collectMigrationManifest(ROOT_DIR, candidateCommit);
|
||||
const candidateSet = new Set(candidateManifest);
|
||||
if (expectedPending.some((migration) => !candidateSet.has(migration))) {
|
||||
@@ -305,8 +310,9 @@ function main() {
|
||||
`STORAGE_HOST_DIR=${shellQuote(storageHostDir)}`,
|
||||
`EXPECTED_PRODUCTION_ORIGIN_SHA256=${shellQuote(sha256Text(expectedOrigin))}`,
|
||||
`EXPECTED_PRODUCTION_DB_NAME_SHA256=${shellQuote(expectedDbNameHash)}`,
|
||||
`BUILD_SHA=${shellQuote(candidateCommit)}`,
|
||||
`VITE_BUILD_SHA=${shellQuote(candidateShortCommit)}`,
|
||||
...Object.entries(candidateBuildEnv).map(
|
||||
([key, value]) => `${key}=${shellQuote(value)}`,
|
||||
),
|
||||
`CANDIDATE_MIGRATIONS_CSV=${shellQuote(candidateManifest.join(","))}`,
|
||||
`EXPECTED_PENDING_MIGRATIONS_CSV=${shellQuote(expectedPending.join(","))}`,
|
||||
"bash -s",
|
||||
@@ -321,14 +327,6 @@ function main() {
|
||||
});
|
||||
const stdout = result.stdout || "";
|
||||
const rawStatus = extractPrismaStatus(stdout);
|
||||
if (rawStatus != null) {
|
||||
validatePrismaStatusText(rawStatus);
|
||||
const sanitizedStatus = sanitizePrismaStatus(rawStatus, [expectedOrigin]);
|
||||
writeFileSync(path.join(reportDir, "prisma-migrate-status.txt"), `${sanitizedStatus}\n`, {
|
||||
encoding: "utf8",
|
||||
mode: 0o600,
|
||||
});
|
||||
}
|
||||
const stableSummary = stableRemoteSummary(stdout);
|
||||
writeFileSync(path.join(reportDir, "preflight-output.txt"), `${stableSummary}\n`, {
|
||||
encoding: "utf8",
|
||||
@@ -343,6 +341,12 @@ function main() {
|
||||
stderr: result.stderr,
|
||||
rawStatus,
|
||||
});
|
||||
validatePrismaStatusText(rawStatus);
|
||||
const sanitizedStatus = sanitizePrismaStatus(rawStatus, [expectedOrigin]);
|
||||
writeFileSync(path.join(reportDir, "prisma-migrate-status.txt"), `${sanitizedStatus}\n`, {
|
||||
encoding: "utf8",
|
||||
mode: 0o600,
|
||||
});
|
||||
console.log("[production-preflight][PASS] 生产目标与迁移只读门禁通过");
|
||||
} catch (error) {
|
||||
const code = error instanceof ProductionPreflightError
|
||||
|
||||
在新工单中引用
屏蔽一个用户