feat: implement rollback command for deployments
- Added a new `rollback` command to roll back deployments to their previous release. - Introduced `findRollbackCandidates` and `rollbackDeployment` functions to handle rollback logic. - Updated CLI command definitions to include the new `rollback` command with an alias. - Enhanced deployment conversion to use resolved images for buildable services. - Introduced a new `graph` module to visualize Kubernetes resources and their relationships. - Added tests for the new rollback functionality and graph rendering. - Updated package version to 1.3.0.
This commit is contained in:
+21
-24
@@ -10,18 +10,18 @@ import {
|
||||
getStaleResources,
|
||||
sortResources,
|
||||
} from "../lib/apply";
|
||||
import { buildServices } from "../lib/build";
|
||||
import { buildServices, resolveBuildImages } from "../lib/build";
|
||||
import { composeToKubernetes, type KubernetesResource } from "../lib/convert";
|
||||
import {
|
||||
getComposePostgresClaims,
|
||||
reconcilePostgresClaims,
|
||||
} from "../lib/database";
|
||||
import { getComposeS3Claims, reconcileS3Claims } from "../lib/storage";
|
||||
import { restartDeployment, waitForDeploymentRollout } from "../lib/shared";
|
||||
import { waitForDeploymentRollout } from "../lib/shared";
|
||||
|
||||
type UpContext = {
|
||||
compose?: ComposeSpecification;
|
||||
changedDeployments?: string[];
|
||||
buildImages?: Record<string, string>;
|
||||
serviceEnv?: Record<string, Record<string, string>>;
|
||||
resources?: KubernetesResource[];
|
||||
staleResources?: KubernetesResource[];
|
||||
@@ -85,11 +85,27 @@ export async function runUp(build: boolean) {
|
||||
},
|
||||
config,
|
||||
);
|
||||
taskCtx.changedDeployments = result.changed;
|
||||
taskCtx.buildImages = result.images;
|
||||
await config.postBuild?.(result, await getHookContext());
|
||||
task.output = `Built ${result.built.length} image${result.built.length === 1 ? "" : "s"}, ${result.changed.length} changed`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Resolve images",
|
||||
enabled: async () =>
|
||||
!build &&
|
||||
Object.values((await compose()).services ?? {}).some(
|
||||
(service) => service.build,
|
||||
),
|
||||
task: async (taskCtx, task) => {
|
||||
taskCtx.buildImages = await resolveBuildImages(
|
||||
project,
|
||||
taskCtx.compose!,
|
||||
config,
|
||||
);
|
||||
task.output = `${Object.keys(taskCtx.buildImages).length} image${Object.keys(taskCtx.buildImages).length === 1 ? "" : "s"}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Reconcile databases",
|
||||
enabled: async () =>
|
||||
@@ -121,7 +137,7 @@ export async function runUp(build: boolean) {
|
||||
taskCtx.compose!,
|
||||
cwd,
|
||||
taskCtx.serviceEnv,
|
||||
config.registry,
|
||||
taskCtx.buildImages,
|
||||
);
|
||||
await config.postRender?.(
|
||||
taskCtx.resources as KuberResource[],
|
||||
@@ -169,25 +185,6 @@ export async function runUp(build: boolean) {
|
||||
{ rendererOptions: { collapseErrors: false } },
|
||||
).run();
|
||||
|
||||
const changedDeployments = taskCtx.changedDeployments ?? [];
|
||||
if (changedDeployments.length > 0) {
|
||||
await new Listr([
|
||||
{
|
||||
title: "Restart changed deployments",
|
||||
task: (_taskCtx, task) => {
|
||||
task.output = `${changedDeployments.length} deployments queued`;
|
||||
return task.newListr(
|
||||
changedDeployments.map((name) => ({
|
||||
title: `Deployment ${name}`,
|
||||
task: () => restartDeployment(name),
|
||||
})),
|
||||
{ concurrent: false, exitOnError: true },
|
||||
);
|
||||
},
|
||||
},
|
||||
]).run();
|
||||
}
|
||||
|
||||
const deployments = getDeploymentNames(taskCtx.resources!);
|
||||
if (deployments.length > 0) {
|
||||
await new Listr([
|
||||
|
||||
Reference in New Issue
Block a user