fix: require current-main deploy desired state
This commit is contained in:
committed by
Code Queue Review
parent
b9b625c4e8
commit
fff45edf4c
@@ -87,7 +87,7 @@ function usage() {
|
||||
"",
|
||||
"Options:",
|
||||
" --plan explicitly request the default read-only JSON plan",
|
||||
" --check exit non-zero when desired-state sources are invalid, drifted, or do not match --promotion-commit",
|
||||
" --check exit non-zero when desired-state sources are invalid, drifted, or do not match an explicit target",
|
||||
" --pretty print indented JSON",
|
||||
" --target-ref REF resolve REF with git and review promotion to its short commit tag",
|
||||
" --target-tag TAG review promotion to an explicit image tag without proving registry existence",
|
||||
@@ -467,7 +467,7 @@ function assertTargetTag(ctx, tag, pathName) {
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveTarget(repoRoot, { targetRef, targetTag, promotionCommit }, ctx) {
|
||||
async function resolveTarget(repoRoot, { targetRef, targetTag, promotionCommit, requireTargetConvergence = false }, ctx) {
|
||||
if (!targetRef && !targetTag && !promotionCommit) return null;
|
||||
let commitId = null;
|
||||
let shortCommitId = null;
|
||||
@@ -503,6 +503,7 @@ async function resolveTarget(repoRoot, { targetRef, targetTag, promotionCommit }
|
||||
if (promotionCommit && commitPattern.test(String(promotionCommit)) && targetTag && targetTag !== promotionCommit.slice(0, 7)) {
|
||||
addMismatch(ctx, "promotion_tag_mismatch", "--target-tag", "promotion target tag must be the short promotion commit", promotionCommit.slice(0, 7), targetTag);
|
||||
}
|
||||
const requireConvergence = Boolean(promotionCommit || requireTargetConvergence);
|
||||
return {
|
||||
targetRef,
|
||||
promotionCommit,
|
||||
@@ -510,10 +511,18 @@ async function resolveTarget(repoRoot, { targetRef, targetTag, promotionCommit }
|
||||
shortCommitId,
|
||||
tag,
|
||||
tagSource: targetTag ? "target-tag" : promotionCommit ? "promotion-commit-short" : "target-ref-short-commit",
|
||||
requireConvergence: Boolean(promotionCommit)
|
||||
requireConvergence,
|
||||
convergenceRequirement: promotionCommit ? "promotion-commit" : requireTargetConvergence ? "target-check" : "plan-only"
|
||||
};
|
||||
}
|
||||
|
||||
function targetLabel(target) {
|
||||
if (target.targetRef && target.tag) return `${target.targetRef} (${target.tag})`;
|
||||
if (target.promotionCommit) return target.promotionCommit;
|
||||
if (target.tag) return `tag ${target.tag}`;
|
||||
return "target";
|
||||
}
|
||||
|
||||
function observationMatchesTarget(observation, target) {
|
||||
if (!target) return null;
|
||||
if (observation.kind === "commit") {
|
||||
@@ -563,16 +572,20 @@ function buildTargetConvergence(ctx, target) {
|
||||
}
|
||||
});
|
||||
} else if (promotionRequired && pending.length > 0) {
|
||||
const promotionCommitRequired = Boolean(target.promotionCommit);
|
||||
addDiagnostic(ctx, {
|
||||
code: "promotion_commit_mismatch",
|
||||
code: promotionCommitRequired ? "promotion_commit_mismatch" : "target_desired_state_mismatch",
|
||||
path: "desired-state",
|
||||
message: "desired-state fields do not match the required promotion commit/tag",
|
||||
message: promotionCommitRequired
|
||||
? "desired-state fields do not match the required promotion commit/tag"
|
||||
: `stale desired-state is not pinned to ${targetLabel(target)}; explicit target checks require current-main/commit-pinned deploy, catalog, workload, and runtime mirror fields`,
|
||||
expected: {
|
||||
commitId: target.commitId,
|
||||
imageTag: target.tag
|
||||
},
|
||||
actual: {
|
||||
pending: pending.length
|
||||
pending: pending.length,
|
||||
samplePendingPaths: pending.slice(0, 8).map((item) => item.path)
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -582,7 +595,9 @@ function buildTargetConvergence(ctx, target) {
|
||||
: pending.length === 0
|
||||
? "already_promoted"
|
||||
: promotionRequired
|
||||
? "promotion_mismatch"
|
||||
? target.promotionCommit
|
||||
? "promotion_mismatch"
|
||||
: "target_mismatch"
|
||||
: "promotion_pending";
|
||||
return {
|
||||
state,
|
||||
@@ -668,7 +683,8 @@ export async function buildDesiredStatePlan(options = {}) {
|
||||
const target = await resolveTarget(repoRoot, {
|
||||
targetRef: options.targetRef ?? null,
|
||||
targetTag: options.targetTag ?? null,
|
||||
promotionCommit: options.promotionCommit ?? null
|
||||
promotionCommit: options.promotionCommit ?? null,
|
||||
requireTargetConvergence: options.requireTargetConvergence === true
|
||||
}, ctx);
|
||||
|
||||
const deployServices = deploy.services ?? [];
|
||||
@@ -910,7 +926,7 @@ export async function buildDesiredStatePlan(options = {}) {
|
||||
prod: false,
|
||||
devLiveClaim: false
|
||||
},
|
||||
checkSemantics: "--check exits non-zero for missing/invalid desired-state sources, internal commit/image mirror drift, invalid target tags, partial target drift, or any mismatch with --promotion-commit. A uniform older desired-state under --target-ref alone is a read-only promotion plan, not a check failure.",
|
||||
checkSemantics: "--check exits non-zero for missing/invalid desired-state sources, internal commit/image mirror drift, invalid target tags, partial target drift, or any mismatch with an explicit --target-ref, --target-tag, or --promotion-commit. Without --check, a uniform older desired-state under --target-ref/--target-tag is a read-only promotion plan.",
|
||||
summary: {
|
||||
desiredCommitId,
|
||||
desiredImageTag,
|
||||
@@ -966,7 +982,8 @@ export async function runDeployDesiredStatePlanCli(argv = process.argv.slice(2),
|
||||
repoRoot: options.repoRoot,
|
||||
targetRef: args.targetRef,
|
||||
targetTag: args.targetTag,
|
||||
promotionCommit: args.promotionCommit
|
||||
promotionCommit: args.promotionCommit,
|
||||
requireTargetConvergence: args.check && Boolean(args.targetRef || args.targetTag)
|
||||
});
|
||||
process.stdout.write(`${JSON.stringify(plan, null, args.pretty ? 2 : 0)}\n`);
|
||||
if (args.check && plan.status === "blocked") {
|
||||
|
||||
Reference in New Issue
Block a user