Files
pikasTech-HWLAB/scripts/src/dev-cd-transaction-guard.mjs
T
Codex e23b675afb Merge remote-tracking branch 'origin/main' into fix/cd-artifact-fastpath-20260524
# Conflicts:
#	scripts/dev-artifact-publish.mjs
#	scripts/src/dev-cd-transaction-guard.mjs
#	scripts/src/dev-deploy-apply.test.mjs
2026-05-24 06:13:51 +00:00

123 lines
3.7 KiB
JavaScript

import { tempReportPath } from "./report-paths.mjs";
const transactionEnvNames = [
"HWLAB_CD_TRANSACTION_ID",
"HWLAB_CD_TRANSACTION_OWNER",
"HWLAB_CD_LOCK_NAME"
];
const ciArtifactIdentityEnvNames = [
"HWLAB_CI_ARTIFACT_RUN_ID",
"GITHUB_RUN_ID",
"CI_PIPELINE_ID",
"BUILDKITE_BUILD_ID"
];
const artifactPublishIdentityEnvNames = [
...ciArtifactIdentityEnvNames,
...transactionEnvNames
];
export function hasDevCdTransactionEnv(env = process.env) {
return typeof env.HWLAB_CD_TRANSACTION_ID === "string" && env.HWLAB_CD_TRANSACTION_ID.trim().length > 0;
}
export function hasCiArtifactPublishEnv(env = process.env) {
return ciArtifactIdentityEnvNames.some((name) => typeof env[name] === "string" && env[name].trim().length > 0);
}
export function hasDevCiArtifactEnv(env = process.env) {
return hasCiArtifactPublishEnv(env);
}
export function hasDevArtifactSideEffectEnv(env = process.env) {
return hasDevCdTransactionEnv(env) || hasCiArtifactPublishEnv(env);
}
export function devArtifactProducer(env = process.env) {
if (hasCiArtifactPublishEnv(env)) {
const idName = ciArtifactIdentityEnvNames.find((name) => typeof env[name] === "string" && env[name].trim().length > 0);
return {
kind: "ci-artifact",
runId: env[idName],
owner: env.HWLAB_CI_ARTIFACT_RUN_OWNER ?? idName ?? null
};
}
if (hasDevCdTransactionEnv(env)) {
return {
kind: "cd-transaction-legacy",
runId: env.HWLAB_CD_TRANSACTION_ID,
owner: env.HWLAB_CD_TRANSACTION_OWNER ?? null
};
}
return {
kind: "missing",
runId: null,
owner: null
};
}
export function devCdTransactionGuardFailure({
script,
mode,
requiredEnv = "HWLAB_CD_TRANSACTION_ID"
}) {
return {
ok: false,
status: "blocked",
error: "cd-transaction-required",
code: "cd-transaction-required",
script,
mode,
requiredEnv,
acceptedEnv: transactionEnvNames,
entrypoint: `node scripts/dev-cd-apply.mjs --apply --confirm-dev --confirmed-non-production --report ${tempReportPath("dev-cd-apply.json")}`,
summary: `${script} ${mode} is a DEV CD side-effect step and must run inside scripts/dev-cd-apply.mjs.`,
devOnly: true,
prodTouched: false,
mutationAttempted: false
};
}
export function devArtifactPublishIdentityGuardFailure({
script,
mode,
requiredEnv = "HWLAB_CI_ARTIFACT_RUN_ID or HWLAB_CD_TRANSACTION_ID"
}) {
return {
ok: false,
status: "blocked",
error: "artifact-publish-identity-required",
code: "artifact-publish-identity-required",
script,
mode,
requiredEnv,
acceptedEnv: artifactPublishIdentityEnvNames,
entrypoint: `HWLAB_CI_ARTIFACT_RUN_ID=<run-id> node scripts/dev-artifact-publish.mjs --publish --report ${tempReportPath("dev-artifacts.json")}`,
summary: `${script} ${mode} is a DEV artifact publish side-effect step and must run under CI artifact identity, or the legacy DEV CD transaction path.`,
devOnly: true,
prodTouched: false,
cdLockRequired: false,
rolloutAttempted: false,
mutationAttempted: false
};
}
export function devArtifactSideEffectGuardFailure(options) {
return devArtifactPublishIdentityGuardFailure(options);
}
export function requireDevCdTransactionForSideEffect({ env = process.env, script, mode }) {
if (hasDevCdTransactionEnv(env)) return null;
return devCdTransactionGuardFailure({ script, mode });
}
export function requireDevArtifactPublishIdentity({ env = process.env, script, mode }) {
if (hasCiArtifactPublishEnv(env) || hasDevCdTransactionEnv(env)) return null;
return devArtifactPublishIdentityGuardFailure({ script, mode });
}
export function requireDevArtifactSideEffectEnv(options) {
return requireDevArtifactPublishIdentity(options);
}