diff --git a/apps/webservice/src/app/[workspaceSlug]/dependencies/DependencyDiagram.tsx b/apps/webservice/src/app/[workspaceSlug]/dependencies/DependencyDiagram.tsx index a9e14102..34f195bb 100644 --- a/apps/webservice/src/app/[workspaceSlug]/dependencies/DependencyDiagram.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/dependencies/DependencyDiagram.tsx @@ -148,13 +148,13 @@ const ReleaseSelector: React.FC<{ const DeploymentNode: React.FC< NodeProps< - Deployment & { latestRelease: { id: string; version: string } | null } + Deployment & { latestActiveRelease: { id: string; version: string } | null } > > = ({ data }) => { const { getEdges, setEdges } = useReactFlow(); const [selectedRelease, setSelectedRelease] = useState( - data.latestRelease?.id, + data.latestActiveRelease?.id, ); const releases = api.release.list.useQuery({ deploymentId: data.id }); const release = releases.data?.items.find((r) => r.id === selectedRelease); @@ -163,7 +163,7 @@ const DeploymentNode: React.FC< useEffect(() => { if (release == null) return; const deps = release.releaseDependencies.filter(isPresent); - if (data.latestRelease == null) return; + if (data.latestActiveRelease == null) return; const edges = getEdges().filter((e) => e.source !== data.id); @@ -193,7 +193,7 @@ const DeploymentNode: React.FC<
{releases.data != null && ( @@ -222,7 +222,7 @@ const edgeTypes = { default: DepEdge }; const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); const DependencyDiagram: React.FC<{ deployments: Array< - Deployment & { latestRelease: { id: string; version: string } | null } + Deployment & { latestActiveRelease: { id: string; version: string } | null } >; }> = ({ deployments }) => { const [nodes, _, onNodesChange] = useNodesState( @@ -262,7 +262,7 @@ const DependencyDiagram: React.FC<{ export const Diagram: React.FC<{ deployments: Array< - Deployment & { latestRelease: { id: string; version: string } | null } + Deployment & { latestActiveRelease: { id: string; version: string } | null } >; }> = ({ deployments }) => { return ( diff --git a/apps/webservice/src/app/[workspaceSlug]/dependencies/page.tsx b/apps/webservice/src/app/[workspaceSlug]/dependencies/page.tsx index 5d9969fc..81a4fa70 100644 --- a/apps/webservice/src/app/[workspaceSlug]/dependencies/page.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/dependencies/page.tsx @@ -15,13 +15,21 @@ export default async function Dependencies({ if ( deployments.length === 0 || - deployments.some((d) => d.latestRelease != null) + deployments.some((d) => d.latestActiveReleases != null) ) return ; + const transformedDeployments = deployments.map((deployment) => ({ + ...deployment, + latestActiveRelease: deployment.latestActiveReleases && { + id: deployment.latestActiveReleases.id, + version: deployment.latestActiveReleases.version, + }, + })); + return (
- +
); } diff --git a/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/TableDeployments.tsx b/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/TableDeployments.tsx index 897f8ba4..e12a302e 100644 --- a/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/TableDeployments.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/TableDeployments.tsx @@ -121,12 +121,13 @@ const DeploymentTable: React.FC<{ environments: Array; deployments: Array< Deployment & { - latestRelease: { + activeReleases: Array<{ id: string; name: string; version: string; createdAt: Date; - } | null; + environmentId: string; + }> | null; } >; workspaceSlug: string; @@ -177,6 +178,9 @@ const DeploymentTable: React.FC<{ {environments.map((env, envIdx) => { + const release = + r.activeReleases?.find((r) => r.environmentId === env.id) ?? + null; return ( +const latestActiveReleaseSubQuery = (db: Tx) => db .select({ id: release.id, @@ -39,13 +41,15 @@ const latestReleaseSubQuery = (db: Tx) => createdAt: release.createdAt, name: release.name, config: release.config, + environmentId: releaseJobTrigger.environmentId, - rank: sql`ROW_NUMBER() OVER (PARTITION BY deployment_id ORDER BY created_at DESC)`.as( + rank: sql`ROW_NUMBER() OVER (PARTITION BY ${release.deploymentId}, ${releaseJobTrigger.environmentId} ORDER BY ${release.createdAt} DESC)`.as( "rank", ), }) .from(release) - .as("release"); + .innerJoin(releaseJobTrigger, eq(releaseJobTrigger.releaseId, release.id)) + .as("active_releases"); export const deploymentRouter = createTRPCRouter({ variable: deploymentVariableRouter, @@ -203,20 +207,26 @@ export const deploymentRouter = createTRPCRouter({ .on({ type: "system", id: input }), }) .query(async ({ ctx, input }) => { - const latestRelease = latestReleaseSubQuery(ctx.db); + const activeRelease = latestActiveReleaseSubQuery(ctx.db); return ctx.db .select() .from(deployment) .leftJoin( - latestRelease, + activeRelease, and( - eq(latestRelease.deploymentId, deployment.id), - eq(latestRelease.rank, 1), + eq(activeRelease.deploymentId, deployment.id), + eq(activeRelease.rank, 1), ), ) .where(eq(deployment.systemId, input)) - .then((r) => - r.map((row) => ({ ...row.deployment, latestRelease: row.release })), + .then((ts) => + _.chain(ts) + .groupBy((t) => t.deployment.id) + .map((t) => ({ + ...t[0]!.deployment, + activeReleases: t.map((a) => a.active_releases).filter(isPresent), + })) + .value(), ); }), @@ -304,21 +314,24 @@ export const deploymentRouter = createTRPCRouter({ }) .input(z.string().uuid()) .query(async ({ ctx, input }) => { - const latestRelease = latestReleaseSubQuery(ctx.db); + const activeRelease = latestActiveReleaseSubQuery(ctx.db); return ctx.db .select() .from(deployment) .innerJoin(system, eq(system.id, deployment.systemId)) .leftJoin( - latestRelease, + activeRelease, and( - eq(latestRelease.deploymentId, deployment.id), - eq(latestRelease.rank, 1), + eq(activeRelease.deploymentId, deployment.id), + eq(activeRelease.rank, 1), ), ) .where(eq(system.workspaceId, input)) .then((r) => - r.map((row) => ({ ...row.deployment, latestRelease: row.release })), + r.map((row) => ({ + ...row.deployment, + latestActiveReleases: row.active_releases, + })), ); }), }); diff --git a/packages/job-dispatch/src/release-job-trigger.ts b/packages/job-dispatch/src/release-job-trigger.ts index f75ee407..9040ebea 100644 --- a/packages/job-dispatch/src/release-job-trigger.ts +++ b/packages/job-dispatch/src/release-job-trigger.ts @@ -112,17 +112,17 @@ class ReleaseJobTriggerBuilder { } async _values() { - const latestReleaseSubQuery = this._releaseSubQuery(); + const latestActiveReleaseSubQuery = this._releaseSubQuery(); const releaseJobTriggers = this.releaseIds ? this._baseQuery().innerJoin( release, eq(release.deploymentId, deployment.id), ) : this._baseQuery().innerJoin( - latestReleaseSubQuery, + latestActiveReleaseSubQuery, and( - eq(latestReleaseSubQuery.deploymentId, deployment.id), - eq(latestReleaseSubQuery.rank, 1), + eq(latestActiveReleaseSubQuery.deploymentId, deployment.id), + eq(latestActiveReleaseSubQuery.rank, 1), ), );