test: add code queue cicd dry-run contract
This commit is contained in:
+124
-11
@@ -1002,6 +1002,105 @@ function artifactConsumerPlanValidation(service: UniDeskMicroserviceConfig, envi
|
||||
return ["unsupported service remains blocked before source materialization or runtime mutation"];
|
||||
}
|
||||
|
||||
function unsupportedEnvironmentPlanReason(serviceId: string, environment: DeployEnvironment): string {
|
||||
if (environment === "prod" && serviceId === "code-queue") {
|
||||
return "Code Queue production CD is intentionally unsupported in this phase: only CI image publication and dev artifact-consumer validation are implemented; prod artifact deploy, rollout and manifest mutation are blocked.";
|
||||
}
|
||||
return environment === "prod"
|
||||
? "No standardized prod D601 registry artifact consumer is implemented for this service; legacy maintenance-channel deployment is not allowed."
|
||||
: "No standardized dev deployment or artifact validation path is implemented for this service.";
|
||||
}
|
||||
|
||||
function unsupportedPlanTarget(serviceId: string, environment: DeployEnvironment, reason: string): Record<string, unknown> {
|
||||
const forbiddenActions = [
|
||||
"docker build",
|
||||
"docker compose build",
|
||||
"docker compose up --build",
|
||||
"maintenance-channel source deploy",
|
||||
"dirty worktree source deploy",
|
||||
];
|
||||
if (serviceId === "code-queue") {
|
||||
forbiddenActions.push(
|
||||
"codex deploy",
|
||||
"server rebuild code-queue",
|
||||
"production namespace mutation",
|
||||
"production manifest mutation",
|
||||
"interrupt running Code Queue tasks",
|
||||
"cancel running Code Queue tasks",
|
||||
);
|
||||
}
|
||||
return {
|
||||
consumerKind: "unsupported",
|
||||
runtimeHost: null,
|
||||
deploymentMode: "none",
|
||||
noRuntimeSourceBuild: true,
|
||||
dryRunOnly: true,
|
||||
blockedReason: reason,
|
||||
deployCommandShape: "none",
|
||||
forbiddenActions,
|
||||
...(serviceId === "code-queue"
|
||||
? {
|
||||
excludedTargets: [
|
||||
{
|
||||
namespace: "unidesk",
|
||||
deployments: ["code-queue", "code-queue-read", "code-queue-write", "d601-provider-egress-proxy", "d601-tcp-egress-gateway"],
|
||||
reason: `${environment} dry-run must not mutate production Code Queue execution-plane objects.`,
|
||||
},
|
||||
{
|
||||
operations: ["interrupt", "cancel", "restart scheduler", "restart runner"],
|
||||
reason: "Code Queue cannot self-deploy or alter active task control state from this runner path.",
|
||||
},
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
};
|
||||
}
|
||||
|
||||
function codeQueueCiCdBoundary(serviceId: string, environment: DeployEnvironment): Record<string, unknown> | undefined {
|
||||
if (serviceId !== "code-queue") return undefined;
|
||||
return {
|
||||
serviceId,
|
||||
selfDeployBlocked: true,
|
||||
ciProducer: {
|
||||
command: "bun scripts/cli.ts ci publish-user-service --service code-queue --commit <full-sha>",
|
||||
allowed: true,
|
||||
outputImage: "127.0.0.1:5000/unidesk/code-queue:<full-sha>",
|
||||
responsibility: "build a commit-pinned Code Queue image from pushed Git source, push it to the D601 registry, and report digest/label evidence",
|
||||
forbiddenActions: ["deploy apply", "kubectl apply", "rollout restart", "interrupt", "cancel"],
|
||||
},
|
||||
cdConsumer: environment === "dev"
|
||||
? {
|
||||
environment: "dev",
|
||||
dryRunCommand: "bun scripts/cli.ts deploy apply --env dev --service code-queue --commit <full-sha> --dry-run",
|
||||
liveApplyCommandShape: "bun scripts/cli.ts deploy apply --env dev --service code-queue --commit <full-sha> --run-now",
|
||||
allowedTarget: "unidesk-dev Code Queue scheduler/read/write/provider-egress-proxy only",
|
||||
manualAuthorizationPoint: "operator reviews CI artifact summary and dev dry-run plan, then explicitly authorizes DEV apply outside this Code Queue task",
|
||||
prodMutationAllowed: false,
|
||||
}
|
||||
: {
|
||||
environment: "prod",
|
||||
dryRunCommand: "bun scripts/cli.ts deploy plan --env prod --service code-queue",
|
||||
liveApplyCommandShape: null,
|
||||
allowedTarget: null,
|
||||
manualAuthorizationPoint: "PROD requires a future supervisor-approved Code Queue CD design; current runner output is plan/unsupported only",
|
||||
prodMutationAllowed: false,
|
||||
},
|
||||
manualAuthorization: {
|
||||
dev: "DEV live apply is a human operator decision after dry-run evidence; this task may not execute it.",
|
||||
prod: "PROD live apply is not implemented and must remain unsupported, even with manual intent, until a separate reviewed CD consumer exists.",
|
||||
},
|
||||
forbiddenActions: [
|
||||
"codex deploy",
|
||||
"server rebuild code-queue",
|
||||
"deploy apply --env prod --service code-queue",
|
||||
"artifact-registry deploy-service --env prod --service code-queue",
|
||||
"kubectl apply to namespace unidesk",
|
||||
"rollout restart production Code Queue scheduler/read/write",
|
||||
"interrupt or cancel active Code Queue tasks",
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function environmentPlanServiceConfig(config: UniDeskConfig | null, service: DeployManifestService, environment: DeployEnvironment): UniDeskMicroserviceConfig | null {
|
||||
if (environment === "dev") {
|
||||
const devService = devK3sDeployService(service.id);
|
||||
@@ -2845,7 +2944,12 @@ function environmentDryRunPlan(
|
||||
const unsupported = (environment === "prod" && !prodArtifactConsumerServiceIds.has(service.id))
|
||||
|| (environment === "dev" && !devApplySupportedServiceIds.has(service.id) && !devArtifactConsumerServiceIds.has(service.id));
|
||||
const dryRunBlockedReason = artifactConsumerDryRunBlockedServiceIds.get(service.id) ?? null;
|
||||
const planKind = serviceConfig === null ? "unsupported" : artifactConsumerPlanKind(serviceConfig, environment);
|
||||
const planTarget = serviceConfig === null ? null : artifactConsumerPlanTarget(serviceConfig, environment);
|
||||
const unsupportedReason = unsupported ? unsupportedEnvironmentPlanReason(service.id, environment) : null;
|
||||
const effectiveTarget = unsupported
|
||||
? unsupportedPlanTarget(service.id, environment, unsupportedReason ?? "unsupported")
|
||||
: planTarget;
|
||||
return {
|
||||
id: service.id,
|
||||
repo: service.repo,
|
||||
@@ -2863,24 +2967,33 @@ function environmentDryRunPlan(
|
||||
dryRunOnly: true,
|
||||
blockedReason: "service is missing from config.json and no synthetic deploy service is available for this environment",
|
||||
} : {
|
||||
consumerKind: artifactConsumerPlanKind(serviceConfig, environment),
|
||||
registryImage: `127.0.0.1:5000/unidesk/${service.id}:${service.commitId}`,
|
||||
noRuntimeSourceBuild: artifactConsumerPlanKind(serviceConfig, environment) !== "d601-dev-target-side-build",
|
||||
dryRunOnly: (environment === "prod" && prodArtifactLiveApplyBlockedServiceIds.has(service.id)) || dryRunBlockedReason !== null,
|
||||
blockedReason: dryRunBlockedReason ?? (environment === "prod" ? prodArtifactLiveApplyBlockedServiceIds.get(service.id) ?? null : null),
|
||||
consumerKind: unsupported ? "unsupported" : planKind,
|
||||
registryImage: unsupported ? null : `127.0.0.1:5000/unidesk/${service.id}:${service.commitId}`,
|
||||
noRuntimeSourceBuild: unsupported || planKind !== "d601-dev-target-side-build",
|
||||
dryRunOnly: unsupported || (environment === "prod" && prodArtifactLiveApplyBlockedServiceIds.has(service.id)) || dryRunBlockedReason !== null,
|
||||
blockedReason: unsupportedReason ?? dryRunBlockedReason ?? (environment === "prod" ? prodArtifactLiveApplyBlockedServiceIds.get(service.id) ?? null : null),
|
||||
},
|
||||
target: planTarget,
|
||||
validation: serviceConfig === null ? undefined : artifactConsumerPlanValidation(serviceConfig, environment),
|
||||
target: effectiveTarget,
|
||||
validation: unsupported
|
||||
? ["unsupported service remains blocked before source materialization, registry pull, manifest update, rollout, or runtime mutation"]
|
||||
: serviceConfig === null
|
||||
? undefined
|
||||
: artifactConsumerPlanValidation(serviceConfig, environment),
|
||||
boundary: codeQueueCiCdBoundary(service.id, environment),
|
||||
unsupported: unsupported
|
||||
? {
|
||||
ok: false,
|
||||
supported: false,
|
||||
reason: environment === "prod"
|
||||
? "No standardized prod D601 registry artifact consumer is implemented for this service; legacy maintenance-channel deployment is not allowed."
|
||||
: "No standardized dev deployment or artifact validation path is implemented for this service.",
|
||||
reason: unsupportedReason,
|
||||
}
|
||||
: undefined,
|
||||
liveApply: dryRunBlockedReason !== null
|
||||
liveApply: unsupported
|
||||
? {
|
||||
allowed: false,
|
||||
reason: unsupportedReason,
|
||||
dryRunOnly: true,
|
||||
}
|
||||
: dryRunBlockedReason !== null
|
||||
? {
|
||||
allowed: false,
|
||||
reason: dryRunBlockedReason,
|
||||
|
||||
Reference in New Issue
Block a user