docs: align frontend release validation on master

This commit is contained in:
Codex
2026-05-20 11:42:43 +00:00
parent 8f4827c204
commit 4c94b27920
4 changed files with 36 additions and 9 deletions
+24 -3
View File
@@ -210,11 +210,17 @@ export function deployHelp(action: string | undefined = undefined): Record<strin
apply: "Start an async target-side reconcile job unless --run-now is explicitly present.",
guard: "Run local deployment guards without mutating runtime resources.",
},
releaseV1Frontend: {
producer: "bun scripts/cli.ts ci publish-user-service --service frontend --commit <release-v1-full-sha> --wait-ms 1200000",
devConsumer: "bun scripts/cli.ts deploy apply --env dev --service frontend --commit <release-v1-full-sha>",
prodConsumer: "bun scripts/cli.ts deploy apply --env prod --service frontend --commit <release-v1-full-sha>",
boundary: "--commit selects an existing commit-pinned registry artifact for one reviewed artifact consumer; it does not read a dirty local manifest or make the server rebuild a release path.",
},
options: [
{ name: "--file <path>", default: defaultDeployFile, description: "Desired-state manifest path relative to the repo root. JSON and ESM JS manifests are supported, for example deploy.json or develop.js. Local D601 maintenance apply is limited to approved direct exceptions; Code Queue direct rollout is disabled." },
{ name: "--env <dev|prod>", description: "Read the named environment from origin/master:deploy.json. Dev apply supports backend-core target-side rollout plus reviewed artifact consumers for frontend, baidu-netdisk, decision-center, mdtodo, claudeqq, dev-only code-queue, project-manager, oa-event-flow, code-queue-mgr, todo-note, findjob, pipeline, and met-nonlinear. Prod apply uses reviewed D601 registry artifact consumers; code-queue has no prod target and gated/incomplete services return structured unsupported or dry-run-only output." },
{ name: "--service <id>", description: "Limit reconcile to one service from the manifest." },
{ name: "--commit <full-sha>", description: "Prod artifact rollback/apply override for a selected service; the image must already exist in D601 registry." },
{ name: "--commit <full-sha>", description: "Artifact consumer override for one selected --env dev|prod service; the commit-pinned image must already exist in the D601 registry. This is the supported release/v1 frontend validation and rollback shape without editing a local manifest." },
{ name: "--dry-run", description: "Prepare and validate without mutating the target service." },
{ name: "--force", description: "Redeploy even when the live commit appears up to date." },
{ name: "--timeout-ms <n>", default: defaultTimeoutMs, description: "Per-step timeout budget where supported." },
@@ -485,9 +491,9 @@ function parseOptions(args: string[]): DeployOptions {
if (environment !== null && args.includes("--file")) throw new Error("deploy --env reads deploy.json from the fixed Git ref and cannot be combined with --file");
const commitOverride = optionValue(args, ["--commit"]);
const serviceId = optionValue(args, ["--service", "--service-id"]) ?? null;
if (commitOverride !== undefined && environment !== "prod") throw new Error("deploy --commit is only supported for --env prod artifact rollback/apply");
if (commitOverride !== undefined && environment === null) throw new Error("deploy --commit is only supported for --env dev|prod artifact consumer apply");
if (commitOverride !== undefined && !isFullGitSha(commitOverride)) throw new Error("deploy --commit must be a full 40-character commit SHA");
if (commitOverride !== undefined && serviceId === null) throw new Error("deploy --commit requires --service so prod rollback/apply is unambiguous");
if (commitOverride !== undefined && serviceId === null) throw new Error("deploy --commit requires --service so artifact consumer apply is unambiguous");
return {
file: optionValue(args, ["--file"]) ?? defaultDeployFile,
environment,
@@ -2818,6 +2824,19 @@ function prodArtifactUnsupportedResult(services: DeployManifestService[]): Recor
};
}
function commitOverrideArtifactConsumerError(options: DeployOptions): string | null {
if (options.commitOverride === null) return null;
if (options.environment === "dev") {
if (options.serviceId !== null && devArtifactConsumerServiceIds.has(options.serviceId)) return null;
return `deploy --commit is supported for --env dev only on reviewed artifact consumers (${Array.from(devArtifactConsumerServiceIds).sort().join(", ")}); it must not switch dev target-side source builds such as backend-core away from deploy.json`;
}
if (options.environment === "prod") {
if (options.serviceId !== null && prodArtifactConsumerServiceIds.has(options.serviceId)) return null;
return `deploy --commit is supported for --env prod only on reviewed artifact consumers (${Array.from(prodArtifactConsumerServiceIds).sort().join(", ")})`;
}
return "deploy --commit is supported only for --env dev|prod artifact consumer apply";
}
function prodArtifactConsumerLocalManifestResult(services: DeployManifestService[]): Record<string, unknown> {
return {
ok: false,
@@ -3009,6 +3028,8 @@ export async function runDeployCommand(config: UniDeskConfig | null, args: strin
const action = actionRaw as DeployAction;
const options = parseOptions(args.slice(1));
if (options.environment !== null) {
const commitOverrideError = commitOverrideArtifactConsumerError(options);
if (commitOverrideError !== null) throw new Error(commitOverrideError);
const { manifest, source } = readEnvironmentDeployManifest(options.environment);
if (action === "check" || action === "plan") return environmentDryRunPlan(manifest, source, options, action);
if (options.environment === "prod") {