import { defineCommand } from "citty"; import { Listr } from "listr2"; import { apiRequest, type ApiRequestInit } from "../lib/api"; import { ctx } from "../lib/context"; export type RollbackResult = { deployments: string[] }; export type RollbackApiRequest = ( path: string, init?: ApiRequestInit, ) => Promise; export function runRollback( project: string, name: string | undefined, timeoutMs: number, request: RollbackApiRequest = apiRequest, ): Promise { return request( `/workspaces/${encodeURIComponent(project)}/rollback`, { method: "POST", json: { ...(name && { services: [name] }), timeoutMs, }, }, ); } 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(); let deployments: string[] = []; await new Listr([ { title: "Roll back deployments", 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"); } } }, });