import { defineCommand } from "citty"; import { Listr } from "listr2"; import { assertManagedNamespace } from "../lib/apply"; import { ctx } from "../lib/context"; import { planRollback, rollbackDeployment } from "../lib/rollback"; import { waitForDeploymentRollout } from "../lib/shared"; export const rollback = defineCommand({ meta: { name: "rollback", description: "Roll deployments back to the previous release", alias: "fuck", }, args: { deployment: { type: "positional", description: "Deployment name to roll back (defaults to all managed)", required: false, }, }, 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; } 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 }, ); }, }, ]).run(); }, });