From 5bba3c7f5c9ecbf1a1d587f0024757642873e39d Mon Sep 17 00:00:00 2001 From: IshaVenikar Date: Fri, 4 Oct 2024 16:06:29 +0530 Subject: [PATCH] Add method deployment requests after auction completion --- packages/backend/src/entity/Project.ts | 3 + packages/backend/src/registry.ts | 98 +++++++++++++++++++------- packages/backend/src/schema.gql | 1 + packages/backend/src/service.ts | 93 +++++------------------- 4 files changed, 93 insertions(+), 102 deletions(-) diff --git a/packages/backend/src/entity/Project.ts b/packages/backend/src/entity/Project.ts index 8b5f424a..ac028b4c 100644 --- a/packages/backend/src/entity/Project.ts +++ b/packages/backend/src/entity/Project.ts @@ -49,6 +49,9 @@ export class Project { @Column('varchar', { nullable: true }) auctionId?: string | null; + @Column('varchar', { nullable: true }) + auctionStatus?: string | null; + @Column('varchar', { nullable: true }) deployerLrn?: string[] | null; diff --git a/packages/backend/src/registry.ts b/packages/backend/src/registry.ts index 64179193..b2f53e45 100644 --- a/packages/backend/src/registry.ts +++ b/packages/backend/src/registry.ts @@ -2,6 +2,8 @@ import debug from 'debug'; import assert from 'assert'; import { inc as semverInc } from 'semver'; import { DateTime } from 'luxon'; +import { DeepPartial } from 'typeorm'; +import { Octokit } from 'octokit'; import { Registry as LaconicRegistry, parseGasAndFees } from '@cerc-io/registry-sdk'; @@ -151,17 +153,56 @@ export class Registry { }; } - async createApplicationDeploymentAuction (data: { - deployment: Deployment, + async createApplicationDeploymentAuction ( appName: string, - }, + octokit: Octokit, auctionData: AuctionData, -): Promise<{ + data: DeepPartial, + ): Promise<{ applicationDeploymentAuctionId: string; - applicationDeploymentAuctionData: ApplicationDeploymentAuction; - deployerLrns: string[]; }> { - const lrn = this.getLrn(data.appName); + // TODO: If data.domain is present then call createDeployment (don't need auction) + assert(data.project?.repository, 'Project repository not found'); + const [owner, repo] = data.project.repository.split('/'); + + const { data: packageJSONData } = await octokit.rest.repos.getContent({ + owner, + repo, + path: 'package.json', + ref: data.commitHash, + }); + + if (!packageJSONData) { + throw new Error('Package.json file not found'); + } + + assert(!Array.isArray(packageJSONData) && packageJSONData.type === 'file'); + const packageJSON: PackageJSON = JSON.parse(atob(packageJSONData.content)); + + assert(packageJSON.name, "name field doesn't exist in package.json"); + + 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 } = + await this.createApplicationRecord({ + appName: repo, + packageJSON, + appType: data.project!.template!, + commitHash: data.commitHash!, + repoUrl, + }); + + log( + `Published application record ${applicationRecordId}`, + ); + + const lrn = this.getLrn(appName); const records = await this.registry.resolveNames([lrn]); const applicationRecord = records[0]; @@ -198,8 +239,6 @@ export class Registry { type: APP_DEPLOYMENT_AUCTION_RECORD_TYPE, }; - await sleep(SLEEP_DURATION); - const result = await this.registry.setRecord( { privateKey: this.registryConfig.privateKey, @@ -212,25 +251,8 @@ export class Registry { log(`Application deployment auction record published: ${result.id}`); log('Application deployment auction data:', applicationDeploymentAuction); - let deployerLrns = []; - const { winnerAddresses } = auctionResult.auction; - - for (const auctionWinner of winnerAddresses) { - const deployerRecord = await this.registry.queryRecords( - { - paymentAddress: auctionWinner, - }, - true - ); - - const lrn = deployerRecord.names.length > 0 ? deployerRecord.names[0] : null; - deployerLrns.push(lrn); - } - return { applicationDeploymentAuctionId: auctionResult.auction.id, - applicationDeploymentAuctionData: applicationDeploymentAuction, - deployerLrns }; } @@ -300,6 +322,30 @@ export class Registry { }; } + async getAuctionWinners( + auctionId: string + ): Promise { + const records = await this.registry.getAuctionsByIds([auctionId]); + const auctionResult = records[0]; + + let deployerLrns = []; + const { winnerAddresses } = auctionResult.auction; + + for (const auctionWinner of winnerAddresses) { + const deployerRecord = await this.registry.queryRecords( + { + paymentAddress: auctionWinner, + }, + true + ); + + const lrn = deployerRecord.names.length > 0 ? deployerRecord.names[0] : null; + deployerLrns.push(lrn); + } + + return deployerLrns; + } + /** * Fetch ApplicationDeploymentRecords for deployments */ diff --git a/packages/backend/src/schema.gql b/packages/backend/src/schema.gql index d3178e40..17079448 100644 --- a/packages/backend/src/schema.gql +++ b/packages/backend/src/schema.gql @@ -67,6 +67,7 @@ type Project { description: String deployerLrn: [String] auctionId: String + auctionStatus: String template: String framework: String webhooks: [String!] diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index b2d3be16..23785505 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -657,62 +657,11 @@ export class Service { async createDeploymentFromAuction( userId: string, - octokit: Octokit, + auctionId: string, + // take project data data: DeepPartial, - auctionData: AuctionData - ): Promise { - assert(data.project?.repository, 'Project repository not found'); - log( - `Creating deployment in project ${data.project.name} from branch ${data.branch}`, - ); - const [owner, repo] = data.project.repository.split('/'); - - const { data: packageJSONData } = await octokit.rest.repos.getContent({ - owner, - repo, - path: 'package.json', - ref: data.commitHash, - }); - - if (!packageJSONData) { - throw new Error('Package.json file not found'); - } - - assert(!Array.isArray(packageJSONData) && packageJSONData.type === 'file'); - const packageJSON: PackageJSON = JSON.parse(atob(packageJSONData.content)); - - assert(packageJSON.name, "name field doesn't exist in package.json"); - - 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 } = - await this.registry.createApplicationRecord({ - appName: repo, - packageJSON, - appType: data.project!.template!, - commitHash: data.commitHash!, - repoUrl, - }); - - // Update previous deployment with prod branch domain - // TODO: Fix unique constraint error for domain - if (data.domain) { - await this.db.updateDeployment( - { - domainId: data.domain.id, - }, - { - domain: null, - }, - ); - } - + ) { + // TODO: If data.domain is present then call createDeployment (don't need auction) const newDeployment = await this.db.addDeployment({ project: data.project, branch: data.branch, @@ -720,8 +669,6 @@ export class Service { commitMessage: data.commitMessage, environment: data.environment, status: DeploymentStatus.Building, - applicationRecordId, - applicationRecordData, domain: data.domain, createdBy: Object.assign(new User(), { id: userId, @@ -729,19 +676,11 @@ export class Service { }); log( - `Created deployment ${newDeployment.id} and published application record ${applicationRecordId}`, + `Created deployment ${newDeployment.id}`, ); - const deploymentAuctionData = await this.registry.createApplicationDeploymentAuction({ - deployment: newDeployment, - appName: repo - }, auctionData - ); - - const deploymentAuctionId = deploymentAuctionData.applicationDeploymentAuctionId; - const environmentVariables = - await this.db.getEnvironmentVariablesByProjectId(data.project.id!, { + await this.db.getEnvironmentVariablesByProjectId(data.project!.id!, { environment: Environment.Production, }); @@ -760,21 +699,23 @@ export class Service { // So publish project DNS deployment first so that ApplicationDeploymentRecord for the same is available when deleting deployment later await this.registry.createApplicationDeploymentRequest({ deployment: newDeployment, - appName: repo, - repository: repoUrl, + appName: data.project!.name!, + repository: data.url!, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}`, }); } - for (const deployer in deploymentAuctionData.deployerLrns) { + const deployerLrns = await this.registry.getAuctionWinners(auctionId); + + for (const deployer in deployerLrns) { const { applicationDeploymentRequestId, applicationDeploymentRequestData } = // Create requests for all the deployers await this.registry.createApplicationDeploymentRequest({ deployment: newDeployment, - appName: repo, - repository: repoUrl, - auctionId: deploymentAuctionId, + appName: data.project!.name!, + repository: data.url!, + auctionId, lrn: deployer, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}-${newDeployment.id}`, @@ -843,7 +784,7 @@ export class Service { organizationSlug: string, data: DeepPartial, lrn?: string, - auctiondata?: AuctionData + auctionData?: AuctionData ): Promise { const organization = await this.db.getOrganization({ where: { @@ -878,8 +819,8 @@ export class Service { commitMessage: latestCommit.commit.message, }; - const deployment = auctiondata - ? await this.createDeploymentFromAuction(user.id, octokit, deploymentData, auctiondata) + const deployment = auctionData + ? await this.registry.createApplicationDeploymentAuction(repo, octokit, auctionData!, deploymentData) : await this.createDeployment(user.id, octokit, deploymentData, lrn); await this.createRepoHook(octokit, project);