This commit is contained in:
2026-09-03 11:28:30 +07:00 Unverified
parent 26c2d0f015
commit 82d0fe3e0d
93 changed files with 19237 additions and 1285 deletions
+43 -39
View File
@@ -1,9 +1,31 @@
import { defineCommand } from "citty";
import { Listr } from "listr2";
import { assertManagedNamespace } from "../lib/apply";
import { apiRequest, type ApiRequestInit } from "../lib/api";
import { ctx } from "../lib/context";
import { planRollback, rollbackDeployment } from "../lib/rollback";
import { waitForDeploymentRollout } from "../lib/shared";
export type RollbackResult = { deployments: string[] };
export type RollbackApiRequest = <T>(
path: string,
init?: ApiRequestInit,
) => Promise<T>;
export function runRollback(
project: string,
name: string | undefined,
timeoutMs: number,
request: RollbackApiRequest = apiRequest,
): Promise<RollbackResult> {
return request<RollbackResult>(
`/workspaces/${encodeURIComponent(project)}/rollback`,
{
method: "POST",
json: {
...(name && { services: [name] }),
timeoutMs,
},
},
);
}
export const rollback = defineCommand({
meta: {
@@ -20,48 +42,30 @@ export const rollback = defineCommand({
},
async run({ args }) {
const { project, config } = ctx();
await assertManagedNamespace(project);
const names = args.deployment ? [args.deployment] : undefined;
const candidates = await planRollback(names);
if (candidates.length === 0) {
if (names) {
console.log(`${names[0]} has no previous release to roll back to`);
} else {
console.log("No deployments have a previous release to roll back to");
}
return;
}
let deployments: string[] = [];
await new Listr([
{
title: "Roll back deployments",
task: (taskCtx, task) => {
task.output = `${candidates.length} deployment${candidates.length === 1 ? "" : "s"} queued`;
return task.newListr(
candidates.map((candidate) => ({
title: `Deployment ${candidate.name}`,
task: () => rollbackDeployment(candidate),
})),
{ concurrent: false, exitOnError: true },
);
},
},
{
title: "Wait for rollout",
task: (taskCtx, task) => {
task.output = `${candidates.length} deployment${candidates.length === 1 ? "" : "s"} queued`;
return task.newListr(
candidates.map((candidate) => ({
title: `Deployment ${candidate.name}`,
task: () =>
waitForDeploymentRollout(candidate.name, config.rolloutTimeoutMs),
})),
{ concurrent: false, exitOnError: true },
);
task: async (_taskCtx, task) => {
({ deployments } = await runRollback(
project,
args.deployment,
config.rolloutTimeoutMs,
));
task.output = `${deployments.length} deployment${deployments.length === 1 ? "" : "s"} queued`;
},
},
]).run();
if (deployments.length === 0) {
if (args.deployment) {
console.log(
`${args.deployment} has no previous release to roll back to`,
);
} else {
console.log("No deployments have a previous release to roll back to");
}
}
},
});