Skip to content

Commit

Permalink
fix: Trigger release for all resources when moving deployment (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
adityachoudhari26 authored Dec 10, 2024
1 parent 16eb318 commit 0c562f8
Showing 1 changed file with 40 additions and 60 deletions.
100 changes: 40 additions & 60 deletions packages/job-dispatch/src/deployment-update.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,68 @@
import type { ResourceCondition } from "@ctrlplane/validators/resources";
import { isPresent } from "ts-is-present";

import { and, eq, inArray, isNotNull, isNull, takeFirst } from "@ctrlplane/db";
import { and, eq, inArray, isNotNull, takeFirst } from "@ctrlplane/db";
import { db } from "@ctrlplane/db/client";
import * as SCHEMA from "@ctrlplane/db/schema";
import {
ComparisonOperator,
FilterType,
} from "@ctrlplane/validators/conditions";

import { handleEvent } from "./events/index.js";
import { getEventsForDeploymentRemoved, handleEvent } from "./events/index.js";
import { dispatchReleaseJobTriggers } from "./job-dispatch.js";
import { isPassingReleaseStringCheckPolicy } from "./policies/release-string-check.js";
import { isPassingAllPolicies } from "./policy-checker.js";
import { createJobApprovals } from "./policy-create.js";
import { createReleaseJobTriggers } from "./release-job-trigger.js";

const getResourcesOnlyInNewSystem = async (
newSystemId: string,
oldSystemId: string,
const moveRunbooksLinkedToHooksToNewSystem = async (
deployment: SCHEMA.Deployment,
) => {
const isDeploymentHook = and(
eq(SCHEMA.hook.scopeType, "deployment"),
eq(SCHEMA.hook.scopeId, deployment.id),
);

return db.query.hook
.findMany({
where: isDeploymentHook,
with: { runhooks: { with: { runbook: true } } },
})
.then((hooks) => {
const runbookIds = hooks.flatMap((h) =>
h.runhooks.map((rh) => rh.runbook.id),
);
return db
.update(SCHEMA.runbook)
.set({ systemId: deployment.systemId })
.where(inArray(SCHEMA.runbook.id, runbookIds));
});
};

const getResourcesInNewSystem = async (deployment: SCHEMA.Deployment) => {
const hasFilter = isNotNull(SCHEMA.environment.resourceFilter);
const newSystem = await db.query.system.findFirst({
where: eq(SCHEMA.system.id, newSystemId),
where: eq(SCHEMA.system.id, deployment.systemId),
with: { environments: { where: hasFilter } },
});

const oldSystem = await db.query.system.findFirst({
where: eq(SCHEMA.system.id, oldSystemId),
with: { environments: { where: hasFilter } },
});
if (newSystem == null) return [];

if (newSystem == null || oldSystem == null) return [];
const filters = newSystem.environments
.map((env) => env.resourceFilter)
.filter(isPresent);

const newSystemFilter: ResourceCondition = {
type: FilterType.Comparison,
operator: ComparisonOperator.Or,
conditions: newSystem.environments
.flatMap((env) => env.resourceFilter)
.filter(isPresent),
};
if (filters.length === 0) return [];

const notInOldSystemFilter: ResourceCondition = {
const systemFilter: ResourceCondition = {
type: FilterType.Comparison,
operator: ComparisonOperator.Or,
not: true,
conditions: oldSystem.environments
.flatMap((env) => env.resourceFilter)
.filter(isPresent),
};

const filter: ResourceCondition = {
type: FilterType.Comparison,
operator: ComparisonOperator.And,
conditions: [newSystemFilter, notInOldSystemFilter],
conditions: filters,
};

return db.query.resource.findMany({
where: and(
SCHEMA.resourceMatchesMetadata(db, filter),
isNull(SCHEMA.resource.deletedAt),
),
where: SCHEMA.resourceMatchesMetadata(db, systemFilter),
});
};

Expand All @@ -69,43 +71,21 @@ export const handleDeploymentSystemChanged = async (
prevSystemId: string,
userId?: string,
) => {
const resourcesOnlyInNewSystem = await getResourcesOnlyInNewSystem(
deployment.systemId,
prevSystemId,
await getEventsForDeploymentRemoved(deployment, prevSystemId).then((events) =>
Promise.allSettled(events.map(handleEvent)),
);

const events = resourcesOnlyInNewSystem.map((resource) => ({
action: "deployment.resource.removed" as const,
payload: { deployment, resource },
}));
await Promise.allSettled(events.map(handleEvent));
await moveRunbooksLinkedToHooksToNewSystem(deployment);

const isDeploymentHook = and(
eq(SCHEMA.hook.scopeType, "deployment"),
eq(SCHEMA.hook.scopeId, deployment.id),
);
await db.query.hook
.findMany({
where: isDeploymentHook,
with: { runhooks: { with: { runbook: true } } },
})
.then((hooks) => {
const runbookIds = hooks.flatMap((h) =>
h.runhooks.map((rh) => rh.runbook.id),
);
return db
.update(SCHEMA.runbook)
.set({ systemId: deployment.systemId })
.where(inArray(SCHEMA.runbook.id, runbookIds));
});
const resources = await getResourcesInNewSystem(deployment);

const createTriggers =
userId != null
? createReleaseJobTriggers(db, "new_release").causedById(userId)
: createReleaseJobTriggers(db, "new_release");
await createTriggers
.deployments([deployment.id])
.resources(resourcesOnlyInNewSystem.map((r) => r.id))
.resources(resources.map((r) => r.id))
.filter(isPassingReleaseStringCheckPolicy)
.then(createJobApprovals)
.insert()
Expand Down

0 comments on commit 0c562f8

Please sign in to comment.