From 1ff5ab3dfdba9dcf5dd1cb0f9435bd863a6d0340 Mon Sep 17 00:00:00 2001 From: Nabarun Gogoi Date: Thu, 29 Feb 2024 18:33:34 +0530 Subject: [PATCH] Assign project domain to latest production deployment (#145) * Create ApplicationDeploymentRequest with project DNS * Add comment for filtering AppDeploymentRecord * Fix lint * Handle delete gitHub event * Add sleep before registry write methods --------- Co-authored-by: neeraj --- packages/backend/src/registry.ts | 19 +++++++++---- packages/backend/src/service.ts | 49 +++++++++++++++++++------------- packages/backend/src/types.ts | 1 + packages/backend/src/utils.ts | 2 ++ 4 files changed, 46 insertions(+), 25 deletions(-) diff --git a/packages/backend/src/registry.ts b/packages/backend/src/registry.ts index 8a6e489b..ed30af9f 100644 --- a/packages/backend/src/registry.ts +++ b/packages/backend/src/registry.ts @@ -12,12 +12,14 @@ import { ApplicationDeploymentRequest } from './entity/Deployment'; import { AppDeploymentRecord, PackageJSON } from './types'; +import { sleep } from './utils'; const log = debug('snowball:registry'); const APP_RECORD_TYPE = 'ApplicationRecord'; const APP_DEPLOYMENT_REQUEST_TYPE = 'ApplicationDeploymentRequest'; const APP_DEPLOYMENT_RECORD_TYPE = 'ApplicationDeploymentRecord'; +const SLEEP_DURATION = 1000; // TODO: Move registry code to laconic-sdk/watcher-ts export class Registry { @@ -111,16 +113,21 @@ export class Registry { const crn = this.getCrn(appName); log(`Setting name: ${crn} for record ID: ${result.data.id}`); + await sleep(SLEEP_DURATION); await this.registry.setName( { cid: result.data.id, crn }, this.registryConfig.privateKey, this.registryConfig.fee ); + + await sleep(SLEEP_DURATION); await this.registry.setName( { cid: result.data.id, crn: `${crn}@${applicationRecord.app_version}` }, this.registryConfig.privateKey, this.registryConfig.fee ); + + await sleep(SLEEP_DURATION); await this.registry.setName( { cid: result.data.id, @@ -139,9 +146,9 @@ export class Registry { async createApplicationDeploymentRequest (data: { deployment: Deployment, appName: string, - packageJsonName: string, repository: string, - environmentVariables: { [key: string]: string } + environmentVariables: { [key: string]: string }, + dns: string, }): Promise<{ applicationDeploymentRequestId: string; applicationDeploymentRequestData: ApplicationDeploymentRequest; @@ -160,7 +167,7 @@ export class Registry { version: '1.0.0', name: `${applicationRecord.attributes.name}@${applicationRecord.attributes.app_version}`, application: `${crn}@${applicationRecord.attributes.app_version}`, - dns: `${data.deployment.project.name}-${data.deployment.id}`, + dns: data.dns, // TODO: Not set in test-progressive-web-app CI // deployment: '$CERC_REGISTRY_DEPLOYMENT_CRN', @@ -178,6 +185,7 @@ export class Registry { }) }; + await sleep(SLEEP_DURATION); const result = await this.registry.setRecord( { privateKey: this.registryConfig.privateKey, @@ -211,11 +219,12 @@ export class Registry { true ); - // Filter records with ApplicationRecord ids + // Filter records with ApplicationRecord ID and Deployment specific URL return records.filter((record: AppDeploymentRecord) => deployments.some( (deployment) => - deployment.applicationRecordId === record.attributes.application + deployment.applicationRecordId === record.attributes.application && + record.attributes.url.includes(deployment.id) ) ); } diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index d204537c..5211585c 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -382,8 +382,7 @@ export class Service { async createDeployment ( userId: string, octokit: Octokit, - data: DeepPartial, - recordData: { repoUrl?: string } = {} + data: DeepPartial ): Promise { assert(data.project?.repository, 'Project repository not found'); log( @@ -407,13 +406,10 @@ export class Service { assert(packageJSON.name, "name field doesn't exist in package.json"); - if (!recordData.repoUrl) { - const { data: repoDetails } = await octokit.rest.repos.get({ - owner, - repo - }); - recordData.repoUrl = repoDetails.html_url; - } + const repoUrl = (await octokit.rest.repos.get({ + owner, + repo + })).data.html_url; // TODO: Set environment variables for each deployment (environment variables can`t be set in application record) const { applicationRecordId, applicationRecordData } = @@ -422,7 +418,7 @@ export class Service { packageJSON, appType: data.project!.template!, commitHash: data.commitHash!, - repoUrl: recordData.repoUrl + repoUrl }); // Update previous deployment with prod branch domain @@ -464,11 +460,23 @@ export class Service { { deployment: newDeployment, appName: repo, - packageJsonName: packageJSON.name, - repository: recordData.repoUrl, - environmentVariables: environmentVariablesObj + repository: repoUrl, + environmentVariables: environmentVariablesObj, + dns: `${newDeployment.project.name}-${newDeployment.id}` }); + // To set project DNS + if (data.environment === Environment.Production) { + await this.registry.createApplicationDeploymentRequest( + { + deployment: newDeployment, + appName: repo, + repository: repoUrl, + environmentVariables: environmentVariablesObj, + dns: `${newDeployment.project.name}` + }); + } + await this.db.updateDeploymentById(newDeployment.id, { applicationDeploymentRequestId, applicationDeploymentRequestData }); return newDeployment; @@ -498,8 +506,6 @@ export class Service { per_page: 1 }); - const { data: repoDetails } = await octokit.rest.repos.get({ owner, repo }); - // Create deployment with prod branch and latest commit await this.createDeployment(user.id, octokit, @@ -510,9 +516,6 @@ export class Service { domain: null, commitHash: latestCommit.sha, commitMessage: latestCommit.commit.message - }, - { - repoUrl: repoDetails.html_url } ); @@ -555,8 +558,14 @@ export class Service { } async handleGitHubPush (data: GitPushEventPayload): Promise { - const { repository, ref, head_commit: headCommit } = data; - log(`Handling GitHub push event from repository: ${repository.full_name}`); + const { repository, ref, head_commit: headCommit, deleted } = data; + + if (deleted) { + log(`Branch ${ref} deleted for project ${repository.full_name}`); + return; + } + + log(`Handling GitHub push event from repository: ${repository.full_name}, branch: ${ref}`); const projects = await this.db.getProjects({ where: { repository: repository.full_name } }); diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index eae6929f..80941346 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -24,6 +24,7 @@ export interface GitPushEventPayload { id: string; message: string; }; + deleted: boolean; } export interface AppDeploymentRecordAttributes { diff --git a/packages/backend/src/utils.ts b/packages/backend/src/utils.ts index 693223bb..8d2a8e8b 100644 --- a/packages/backend/src/utils.ts +++ b/packages/backend/src/utils.ts @@ -66,3 +66,5 @@ export const loadAndSaveData = async ( return savedEntity; }; + +export const sleep = async (ms: number): Promise => new Promise(resolve => setTimeout(resolve, ms));