From 5f4be30799a4b880335899225c150517de818a45 Mon Sep 17 00:00:00 2001 From: Nabarun Date: Thu, 25 Apr 2024 16:51:22 +0530 Subject: [PATCH] Remove current deployment and publish ApplicationDeploymentRemovalRequest for project DNS deployment --- packages/backend/src/registry.ts | 13 ++++++ packages/backend/src/service.ts | 40 ++++++++++++++----- .../backend/test/publish-deploy-records.ts | 19 ++++++++- .../deployments/DeploymentDetailsCard.tsx | 3 +- .../project/deployments/DeploymentMenu.tsx | 5 --- packages/gql-client/src/types.ts | 1 + 6 files changed, 64 insertions(+), 17 deletions(-) diff --git a/packages/backend/src/registry.ts b/packages/backend/src/registry.ts index 72423196..d15b6985 100644 --- a/packages/backend/src/registry.ts +++ b/packages/backend/src/registry.ts @@ -232,6 +232,19 @@ export class Registry { ); } + /** + * Fetch ApplicationDeploymentRecords by filter + */ + async getDeploymentRecordsByFilter (filter: { [key: string]: any }): Promise { + return this.registry.queryRecords( + { + type: APP_DEPLOYMENT_RECORD_TYPE, + ...filter + }, + true + ); + } + /** * Fetch ApplicationDeploymentRemovalRecords for deployments */ diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index cba99a48..306afd38 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -553,17 +553,10 @@ export class Service { return acc; }, {} as { [key: string]: string }); - const { applicationDeploymentRequestId, applicationDeploymentRequestData } = await this.registry.createApplicationDeploymentRequest( - { - deployment: newDeployment, - appName: repo, - repository: repoUrl, - environmentVariables: environmentVariablesObj, - dns: `${newDeployment.project.name}-${newDeployment.id}` - }); - // To set project DNS if (data.environment === Environment.Production) { + // On deleting deployment later, project DNS deployment is also deleted + // So publish project DNS deployment first so that ApplicationDeploymentRecord for the same is available when deleting deployment later await this.registry.createApplicationDeploymentRequest( { deployment: newDeployment, @@ -574,6 +567,15 @@ export class Service { }); } + const { applicationDeploymentRequestId, applicationDeploymentRequestData } = await this.registry.createApplicationDeploymentRequest( + { + deployment: newDeployment, + appName: repo, + repository: repoUrl, + environmentVariables: environmentVariablesObj, + dns: `${newDeployment.project.name}-${newDeployment.id}` + }); + await this.db.updateDeploymentById(newDeployment.id, { applicationDeploymentRequestId, applicationDeploymentRequestData }); return newDeployment; @@ -795,10 +797,30 @@ export class Service { const deployment = await this.db.getDeployment({ where: { id: deploymentId + }, + relations: { + project: true } }); if (deployment && deployment.applicationDeploymentRecordId) { + // If deployment is current, remove deployment for project subdomain as well + if (deployment.isCurrent) { + const currentDeploymentURL = `https://${deployment.project.subDomain}`; + + const deploymentRecords = await this.registry.getDeploymentRecordsByFilter({ + application: deployment.applicationRecordId, + url: currentDeploymentURL + }) + + if (!deploymentRecords.length) { + log(`No ApplicationDeploymentRecord found for URL ${currentDeploymentURL} and ApplicationDeploymentRecord id ${deployment.applicationDeploymentRecordId}`); + return false; + } + + await this.registry.createApplicationDeploymentRemovalRequest({ deploymentId: deploymentRecords[0].id }); + } + const result = await this.registry.createApplicationDeploymentRemovalRequest({ deploymentId: deployment.applicationDeploymentRecordId }); await this.db.updateDeploymentById( diff --git a/packages/backend/test/publish-deploy-records.ts b/packages/backend/test/publish-deploy-records.ts index 0819a91c..02bd1e4a 100644 --- a/packages/backend/test/publish-deploy-records.ts +++ b/packages/backend/test/publish-deploy-records.ts @@ -7,7 +7,7 @@ import { Registry } from '@cerc-io/laconic-sdk'; import { Config } from '../src/config'; import { DEFAULT_CONFIG_FILE_PATH } from '../src/constants'; import { getConfig } from '../src/utils'; -import { Deployment, DeploymentStatus } from '../src/entity/Deployment'; +import { Deployment, DeploymentStatus, Environment } from '../src/entity/Deployment'; const log = debug('snowball:publish-deploy-records'); @@ -40,7 +40,7 @@ async function main () { }); for await (const deployment of deployments) { - const url = `${deployment.project.name}-${deployment.id}.${misc.projectDomain}`; + const url = `https://${deployment.project.name}-${deployment.id}.${misc.projectDomain}`; const applicationDeploymentRecord = { type: 'ApplicationDeploymentRecord', @@ -71,6 +71,21 @@ async function main () { registryConfig.fee ); + // Remove deployment for project subdomain if deployment is for production environment + if (deployment.environment === Environment.Production) { + applicationDeploymentRecord.url = `https://${deployment.project.subDomain}` + + await registry.setRecord( + { + privateKey: registryConfig.privateKey, + record: applicationDeploymentRecord, + bondId: registryConfig.bondId + }, + '', + registryConfig.fee + ); + } + log('Application deployment record data:', applicationDeploymentRecord); log(`Application deployment record published: ${result.data.id}`); } diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx index 4c55e246..0e605bc5 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx @@ -38,6 +38,7 @@ const STATUS_COLORS: { [DeploymentStatus.Building]: 'emphasized', [DeploymentStatus.Ready]: 'positive', [DeploymentStatus.Error]: 'negative', + [DeploymentStatus.Deleting]: 'neutral', }; const DeploymentDetailsCard = ({ @@ -48,7 +49,7 @@ const DeploymentDetailsCard = ({ prodBranchDomains, }: DeployDetailsCardProps) => { const getIconByDeploymentStatus = (status: DeploymentStatus) => { - if (status === DeploymentStatus.Building) { + if (status === DeploymentStatus.Building || status === DeploymentStatus.Deleting) { return ; } if (status === DeploymentStatus.Ready) { diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx index 1d6d33b0..5dbb95aa 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentMenu.tsx @@ -161,11 +161,6 @@ export const DeploymentMenu = ({ deleteDeployment()} - disabled={ - deployment.isCurrent || - deployment.environment !== Environment.Production || - !Boolean(currentDeployment) - } > Delete deployment diff --git a/packages/gql-client/src/types.ts b/packages/gql-client/src/types.ts index 786b7519..ac6481e0 100644 --- a/packages/gql-client/src/types.ts +++ b/packages/gql-client/src/types.ts @@ -21,6 +21,7 @@ export enum DeploymentStatus { Building = 'Building', Ready = 'Ready', Error = 'Error', + Deleting = 'Deleting' } export enum DomainStatus {