From 510e0de654f6af1dbe6a63a2a6101fc9fc892611 Mon Sep 17 00:00:00 2001 From: Adw8 Date: Thu, 17 Oct 2024 11:28:22 +0530 Subject: [PATCH 01/10] Create Deployer entity --- packages/backend/src/entity/Deployer.ts | 14 +++++++++ packages/backend/src/entity/Deployment.ts | 6 ++-- packages/backend/src/schema.gql | 11 ++++++- packages/backend/src/service.ts | 29 ++++++++++--------- .../components/projects/create/Configure.tsx | 2 +- 5 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 packages/backend/src/entity/Deployer.ts diff --git a/packages/backend/src/entity/Deployer.ts b/packages/backend/src/entity/Deployer.ts new file mode 100644 index 00000000..056ed64c --- /dev/null +++ b/packages/backend/src/entity/Deployer.ts @@ -0,0 +1,14 @@ +import { Entity, PrimaryColumn, Column, OneToMany } from 'typeorm'; +import { Deployment } from './Deployment'; + +@Entity() +export class Deployer { + @PrimaryColumn() + deployerId!: string; + + @Column() + deployerLrn!: string; + + @Column() + deployerApiUrl!: string; +} diff --git a/packages/backend/src/entity/Deployment.ts b/packages/backend/src/entity/Deployment.ts index 0036aed9..68c731d7 100644 --- a/packages/backend/src/entity/Deployment.ts +++ b/packages/backend/src/entity/Deployment.ts @@ -13,6 +13,7 @@ import { import { Project } from './Project'; import { Domain } from './Domain'; import { User } from './User'; +import { Deployer } from './Deployer'; import { AppDeploymentRecordAttributes, AppDeploymentRemovalRecordAttributes } from '../types'; export enum Environment { @@ -127,8 +128,9 @@ export class Deployment { @Column('simple-json', { nullable: true }) applicationDeploymentRemovalRecordData!: AppDeploymentRemovalRecordAttributes | null; - @Column('varchar') - deployerLrn!: string; + @ManyToOne(() => Deployer) + @JoinColumn({ name: 'deployerId' }) + deployer!: Deployer; @Column({ enum: Environment diff --git a/packages/backend/src/schema.gql b/packages/backend/src/schema.gql index 8c222fb2..897de44c 100644 --- a/packages/backend/src/schema.gql +++ b/packages/backend/src/schema.gql @@ -104,7 +104,7 @@ type Deployment { commitMessage: String! url: String environment: Environment! - deployerLrn: String + deployerId: String isCurrent: Boolean! baseDomain: String status: DeploymentStatus! @@ -132,6 +132,15 @@ type EnvironmentVariable { updatedAt: String! } +type Deployer { + deployerId: String! + deployerLrn: String! + deployerApiUrl: String! + createdAt: String! + updatedAt: String! +} + + type AuthResult { token: String! } diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index 3f7e7f98..baa86b87 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -14,6 +14,7 @@ import { Project } from './entity/Project'; import { Permission, ProjectMember } from './entity/ProjectMember'; import { User } from './entity/User'; import { Registry } from './registry'; +import { Deployer } from './entity/Deployer'; import { GitHubConfig, RegistryConfig } from './config'; import { AddProjectFromTemplateInput, @@ -235,7 +236,7 @@ export class Service { for (const deployment of prodDeployments) { const projectDeployments = await this.db.getDeploymentsByProjectId(deployment.projectId); const oldDeployments = projectDeployments - .filter(projectDeployment => projectDeployment.deployerLrn === deployment.deployerLrn && projectDeployment.id !== deployment.id); + .filter(projectDeployment => projectDeployment.deployer.deployerLrn === deployment.deployer.deployerLrn && projectDeployment.id !== deployment.id); for (const oldDeployment of oldDeployments) { await this.db.updateDeployment( { id: oldDeployment.id }, @@ -587,7 +588,7 @@ export class Service { domain: prodBranchDomains[0], commitHash: oldDeployment.commitHash, commitMessage: oldDeployment.commitMessage, - deployerLrn: oldDeployment.deployerLrn + deployer: oldDeployment.deployer }); return newDeployment; @@ -625,7 +626,7 @@ export class Service { ); } - const newDeployment = await this.createDeploymentFromData(userId, data, data.deployerLrn!, applicationRecordId, applicationRecordData); + const newDeployment = await this.createDeploymentFromData(userId, data, data.deployer!.deployerId!, applicationRecordId, applicationRecordData); const { repo, repoUrl } = await getRepoDetails(octokit, data.project.repository, data.commitHash); const environmentVariablesObj = await this.getEnvVariables(data.project!.id!); @@ -639,7 +640,7 @@ export class Service { repository: repoUrl, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}`, - lrn: data.deployerLrn! + lrn: data.deployer!.deployerLrn! }); } @@ -648,7 +649,7 @@ export class Service { deployment: newDeployment, appName: repo, repository: repoUrl, - lrn: data.deployerLrn!, + lrn: data.deployer!.deployerLrn!, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}-${newDeployment.id}`, }); @@ -740,7 +741,7 @@ export class Service { async createDeploymentFromData( userId: string, data: DeepPartial, - deployerLrn: string, + deployerId: string, applicationRecordId: string, applicationRecordData: ApplicationRecord, ): Promise { @@ -757,7 +758,9 @@ export class Service { createdBy: Object.assign(new User(), { id: userId, }), - deployerLrn, + deployer: Object.assign(new Deployer(), { + deployerId, + }), }); log(`Created deployment ${newDeployment.id}`); @@ -936,6 +939,7 @@ export class Service { branch, }); + // TODO: Store deployer in project const deployers = project.deployerLrns; if (!deployers) { log(`No deployer present for project ${project.id}`) @@ -955,7 +959,7 @@ export class Service { domain, commitHash: headCommit.id, commitMessage: headCommit.message, - deployerLrn: deployer + // deployer: deployer }, ); } @@ -1011,8 +1015,7 @@ export class Service { let newDeployment: Deployment; if (oldDeployment.project.auctionId) { - // TODO: Discuss creating applicationRecord for redeployments - newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployerLrn); + newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployer.deployerLrn); } else { newDeployment = await this.createDeployment(user.id, octokit, { @@ -1023,7 +1026,7 @@ export class Service { domain: oldDeployment.domain, commitHash: oldDeployment.commitHash, commitMessage: oldDeployment.commitMessage, - deployerLrn: oldDeployment.deployerLrn + deployer: oldDeployment.deployer } ); } @@ -1101,14 +1104,14 @@ export class Service { await this.laconicRegistry.createApplicationDeploymentRemovalRequest({ deploymentId: latestRecord.id, - deployerLrn: deployment.deployerLrn + deployerLrn: deployment.deployer.deployerLrn }); } const result = await this.laconicRegistry.createApplicationDeploymentRemovalRequest({ deploymentId: deployment.applicationDeploymentRecordId, - deployerLrn: deployment.deployerLrn + deployerLrn: deployment.deployer.deployerLrn }); await this.db.updateDeploymentById(deployment.id, { diff --git a/packages/frontend/src/components/projects/create/Configure.tsx b/packages/frontend/src/components/projects/create/Configure.tsx index 7d81ee77..ac08ae2b 100644 --- a/packages/frontend/src/components/projects/create/Configure.tsx +++ b/packages/frontend/src/components/projects/create/Configure.tsx @@ -308,4 +308,4 @@ const Configure = () => { ); }; -export default Configure; +export default Configure; \ No newline at end of file -- 2.45.2 From 4bd111611df727bf36c603678f79a86dcadebc14 Mon Sep 17 00:00:00 2001 From: Adw8 Date: Thu, 17 Oct 2024 11:58:27 +0530 Subject: [PATCH 02/10] Add methods for deployer entity --- packages/backend/src/database.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/backend/src/database.ts b/packages/backend/src/database.ts index 5f840da5..61f3263d 100644 --- a/packages/backend/src/database.ts +++ b/packages/backend/src/database.ts @@ -23,6 +23,7 @@ import { EnvironmentVariable } from './entity/EnvironmentVariable'; import { Domain } from './entity/Domain'; import { getEntities, loadAndSaveData } from './utils'; import { UserOrganization } from './entity/UserOrganization'; +import { Deployer } from './entity/Deployer'; const ORGANIZATION_DATA_PATH = '../test/fixtures/organizations.json'; @@ -573,4 +574,19 @@ export class Database { return domains; } + + async addDeployer (data: DeepPartial): Promise { + const deployerRepository = this.dataSource.getRepository(Deployer); + const newDomain = await deployerRepository.save(data); + + return newDomain; + } + + async getDeployerById (deployerId: string): Promise { + const deployerRepository = this.dataSource.getRepository(Deployer); + + const deployer = await deployerRepository.findOne({ where: { deployerId } }); + + return deployer; + } } -- 2.45.2 From b15d998ed2087e0b143eb2fa009d0f925884816b Mon Sep 17 00:00:00 2001 From: Adw8 Date: Thu, 17 Oct 2024 13:10:13 +0530 Subject: [PATCH 03/10] Update method to return webapp deployer records from registry --- packages/backend/src/entity/Deployer.ts | 1 - packages/backend/src/registry.ts | 22 ++++++++++++---------- packages/backend/src/schema.gql | 1 - packages/backend/src/service.ts | 21 +++++++++++---------- packages/backend/src/types.ts | 17 +++++++++++++++++ 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/packages/backend/src/entity/Deployer.ts b/packages/backend/src/entity/Deployer.ts index 056ed64c..40d91a77 100644 --- a/packages/backend/src/entity/Deployer.ts +++ b/packages/backend/src/entity/Deployer.ts @@ -1,5 +1,4 @@ import { Entity, PrimaryColumn, Column, OneToMany } from 'typeorm'; -import { Deployment } from './Deployment'; @Entity() export class Deployer { diff --git a/packages/backend/src/registry.ts b/packages/backend/src/registry.ts index 5368d36f..79d0cc64 100644 --- a/packages/backend/src/registry.ts +++ b/packages/backend/src/registry.ts @@ -14,7 +14,7 @@ import { ApplicationDeploymentRequest, ApplicationDeploymentRemovalRequest } from './entity/Deployment'; -import { AppDeploymentRecord, AppDeploymentRemovalRecord, AuctionParams } from './types'; +import { AppDeploymentRecord, AppDeploymentRemovalRecord, AuctionParams, DeployerRecord } from './types'; import { getConfig, getRepoDetails, sleep } from './utils'; const log = debug('snowball:registry'); @@ -25,6 +25,7 @@ const APP_DEPLOYMENT_REQUEST_TYPE = 'ApplicationDeploymentRequest'; const APP_DEPLOYMENT_REMOVAL_REQUEST_TYPE = 'ApplicationDeploymentRemovalRequest'; const APP_DEPLOYMENT_RECORD_TYPE = 'ApplicationDeploymentRecord'; const APP_DEPLOYMENT_REMOVAL_RECORD_TYPE = 'ApplicationDeploymentRemovalRecord'; +const WEBAPP_DEPLOYER_RECORD_TYPE = 'WebappDeployer' const SLEEP_DURATION = 1000; // TODO: Move registry code to registry-sdk/watcher-ts @@ -116,7 +117,7 @@ export class Registry { this.registryConfig.privateKey, fee ); - + log("Result: ", result); log(`Published application record ${result.id}`); log('Application record data:', applicationRecord); @@ -291,32 +292,33 @@ export class Registry { }; } - async getAuctionWinningDeployers( + async getAuctionWinningDeployerRecords( auctionId: string - ): Promise { + ): Promise { const records = await this.registry.getAuctionsByIds([auctionId]); const auctionResult = records[0]; - let deployerLrns = []; + let deployerRecords = []; const { winnerAddresses } = auctionResult; for (const auctionWinner of winnerAddresses) { - const deployerRecords = await this.registry.queryRecords( + const records = await this.registry.queryRecords( { paymentAddress: auctionWinner, + type: WEBAPP_DEPLOYER_RECORD_TYPE, }, true ); - for (const record of deployerRecords) { - if (record.names && record.names.length > 0) { - deployerLrns.push(record.names[0]); + for (const record of records) { + if (record.id) { + deployerRecords.push(record); break; } } } - return deployerLrns; + return deployerRecords; } async releaseDeployerFunds( diff --git a/packages/backend/src/schema.gql b/packages/backend/src/schema.gql index 897de44c..a559868c 100644 --- a/packages/backend/src/schema.gql +++ b/packages/backend/src/schema.gql @@ -140,7 +140,6 @@ type Deployer { updatedAt: String! } - type AuthResult { token: String! } diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index baa86b87..70b6b530 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -308,20 +308,21 @@ export class Service { completedAuctionIds.includes(project.auctionId!) ); - for (const project of projectsToBedeployed) { - const deployerLrns = await this.laconicRegistry.getAuctionWinningDeployers(project.auctionId!); - if (!deployerLrns) { + for (const project of projectsToBedeployed) { + const deployers = await this.laconicRegistry.getAuctionWinningDeployerRecords(project!.auctionId!); + + if (!deployers) { log(`No winning deployer for auction ${project!.auctionId}`); } else { - // Update project with deployer LRNs - await this.db.updateProjectById(project.id!, { - deployerLrns - }); + // TODO:Update project with deployer LRNs + // await this.db.updateProjectById(project.id!, { + // deployers + // }); - for (const deployer of deployerLrns) { + for (const deployer of deployers) { log(`Creating deployment for deployer LRN ${deployer}`); - await this.createDeploymentFromAuction(project, deployer); + await this.createDeploymentFromAuction(project, deployer.names[0]); } } } @@ -588,7 +589,7 @@ export class Service { domain: prodBranchDomains[0], commitHash: oldDeployment.commitHash, commitMessage: oldDeployment.commitMessage, - deployer: oldDeployment.deployer + deployer: oldDeployment.deployer }); return newDeployment; diff --git a/packages/backend/src/types.ts b/packages/backend/src/types.ts index 0b6a3a1b..4ea4123c 100644 --- a/packages/backend/src/types.ts +++ b/packages/backend/src/types.ts @@ -82,3 +82,20 @@ export interface EnvironmentVariables { key: string, value: string, } + +export interface DeployerRecord { + id: string; + names: string[]; + owners: string[]; + bondId: string; + createTime: string; + expiryTime: string; + attributes: { + apiUrl: string; + name: string; + paymentAddress: string; + publicKey: string; + type: string; + version: string; + }; +} -- 2.45.2 From ae20f171a154baab315f8a70ffac87c9fcfd1df1 Mon Sep 17 00:00:00 2001 From: Adw8 Date: Thu, 17 Oct 2024 16:43:12 +0530 Subject: [PATCH 04/10] Store deployer data on auction completion --- packages/backend/src/service.ts | 63 +++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index 70b6b530..5bf955f6 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -175,7 +175,7 @@ export class Service { applicationDeploymentRequestId: record.attributes.request, })), relations: { - project: true, + deployer: true, }, order: { createdAt: 'DESC', @@ -206,22 +206,6 @@ export class Service { await this.db.updateDeploymentById(deployment.id, deployment); - const baseDomains = deployment.project.baseDomains || []; - - if (!baseDomains.includes(baseDomain)) { - baseDomains.push(baseDomain); - } - - // Release deployer funds on successful deployment - if (!deployment.project.fundsReleased) { - const fundsReleased = await this.releaseDeployerFundsByProjectId(deployment.projectId); - - await this.db.updateProjectById(deployment.projectId, { - baseDomains, - fundsReleased, - }); - } - log( `Updated deployment ${deployment.id} with URL ${record.attributes.url}`, ); @@ -320,9 +304,41 @@ export class Service { // deployers // }); - for (const deployer of deployers) { - log(`Creating deployment for deployer LRN ${deployer}`); - await this.createDeploymentFromAuction(project, deployer.names[0]); + const deployerRecords = await this.laconicRegistry.getAuctionWinningDeployerRecords(project!.auctionId!); + + if (!deployerRecords) { + log(`No winning deployer for auction ${project!.auctionId}`); + } else { + const deployerLrns = []; + const deployerIds = []; + + for (const record of deployerRecords) { + const deployerId = record.id; + const deployerLrn = record.names[0] + const deployerApiUrl = record.attributes.apiUrl; + + deployerIds.push(deployerId); + deployerLrns.push(deployerLrn); + + const deployerData = { + deployerId, + deployerLrn, + deployerApiUrl, + }; + + // Store the deployer in the DB + await this.db.addDeployer(deployerData); + } + + // Update project with deployer LRNs + await this.db.updateProjectById(project.id!, { + deployerLrns + }); + + for (const deployer of deployerIds) { + log(`Creating deployment for deployer LRN ${deployer}`); + await this.createDeploymentFromAuction(project, deployer); + } } } } @@ -665,7 +681,7 @@ export class Service { async createDeploymentFromAuction( project: DeepPartial, - deployerLrn: string + deployerId: string ): Promise { const octokit = await this.getOctokit(project.ownerId!); const [owner, repo] = project.repository!.split('/'); @@ -691,6 +707,9 @@ export class Service { const applicationRecordId = record.id; const applicationRecordData = record.attributes; + const deployer = await this.db.getDeployerById(deployerId); + const deployerLrn = deployer!.deployerLrn + // Create deployment with prod branch and latest commit const deploymentData = { project, @@ -701,7 +720,7 @@ export class Service { commitMessage: latestCommit.commit.message, }; - const newDeployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerLrn, applicationRecordId, applicationRecordData); + const newDeployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerId, applicationRecordId, applicationRecordData); const environmentVariablesObj = await this.getEnvVariables(project!.id!); // To set project DNS -- 2.45.2 From 94a6c66c36e65c9fcab0ecf1874a5d9bc7795191 Mon Sep 17 00:00:00 2001 From: Neeraj Date: Thu, 17 Oct 2024 19:31:01 +0530 Subject: [PATCH 05/10] Fetch deployment build logs --- packages/backend/src/database.ts | 3 ++- packages/backend/src/schema.gql | 3 ++- .../project/deployments/DeploymentDetailsCard.tsx | 9 +++++++-- packages/gql-client/src/queries.ts | 7 ++++++- packages/gql-client/src/types.ts | 9 ++++++++- 5 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/backend/src/database.ts b/packages/backend/src/database.ts index 61f3263d..2798f1bc 100644 --- a/packages/backend/src/database.ts +++ b/packages/backend/src/database.ts @@ -216,7 +216,8 @@ export class Database { relations: { project: true, domain: true, - createdBy: true + createdBy: true, + deployer: true, }, where: { project: { diff --git a/packages/backend/src/schema.gql b/packages/backend/src/schema.gql index a559868c..1d788b67 100644 --- a/packages/backend/src/schema.gql +++ b/packages/backend/src/schema.gql @@ -104,7 +104,8 @@ type Deployment { commitMessage: String! url: String environment: Environment! - deployerId: String + deployer: Deployer + applicationDeploymentRequestId: String isCurrent: Boolean! baseDomain: String status: DeploymentStatus! diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx index 2d36cdbe..54916591 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx @@ -72,6 +72,11 @@ const DeploymentDetailsCard = ({ leftIcon={getIconByDeploymentStatus(deployment.status)} size="xs" type={STATUS_COLORS[deployment.status] ?? 'neutral'} + onClick={async()=> { + let url = `${deployment.deployer.deployerApiUrl}/log/${deployment.applicationDeploymentRequestId}` + const res = await fetch(url); + console.log(">>>>RESPONSE",await res.text()) + }} > {deployment.status} @@ -96,9 +101,9 @@ const DeploymentDetailsCard = ({ )} - {deployment.deployerLrn && ( + {deployment.deployer.deployerLrn && ( - Deployer LRN: {deployment.deployerLrn} + Deployer LRN: {deployment.deployer.deployerLrn} )} diff --git a/packages/gql-client/src/queries.ts b/packages/gql-client/src/queries.ts index a87a4cb8..c41c75a4 100644 --- a/packages/gql-client/src/queries.ts +++ b/packages/gql-client/src/queries.ts @@ -136,7 +136,11 @@ query ($projectId: String!) { commitHash commitMessage url - deployerLrn + deployer { + deployerId + deployerLrn, + deployerApiUrl, + } environment isCurrent baseDomain @@ -148,6 +152,7 @@ query ($projectId: String!) { name email } + applicationDeploymentRequestId } } `; diff --git a/packages/gql-client/src/types.ts b/packages/gql-client/src/types.ts index 15b9e073..af46bfa5 100644 --- a/packages/gql-client/src/types.ts +++ b/packages/gql-client/src/types.ts @@ -105,7 +105,7 @@ export type Deployment = { commitHash: string; commitMessage: string; url?: string; - deployerLrn: string; + deployer: Deployer; environment: Environment; isCurrent: boolean; baseDomain?: string; @@ -113,8 +113,15 @@ export type Deployment = { createdBy: User; createdAt: string; updatedAt: string; + applicationDeploymentRequestId: string; }; +export type Deployer = { + deployerApiUrl: string; + deployerId: string; + deployerLrn: string; +} + export type OrganizationMember = { id: string; member: User; -- 2.45.2 From 1b2d49c2e99ba88baf069112caacbb9562c76cf9 Mon Sep 17 00:00:00 2001 From: Neeraj Date: Fri, 18 Oct 2024 10:47:10 +0530 Subject: [PATCH 06/10] Add style to deployment logs dialog --- .../deployments/DeploymentDetailsCard.tsx | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx index 54916591..ae3e452b 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx @@ -1,4 +1,4 @@ -import { useCallback } from 'react'; +import { useCallback, useState } from 'react'; import { Deployment, DeploymentStatus, @@ -15,15 +15,32 @@ import { LoadingIcon, WarningIcon, } from 'components/shared/CustomIcon'; +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, +} from '@mui/material'; import { Heading } from 'components/shared/Heading'; import { OverflownText } from 'components/shared/OverflownText'; import { Tag, TagTheme } from 'components/shared/Tag'; +import { Button } from 'components/shared/Button'; import { getInitials } from 'utils/geInitials'; import { relativeTimeMs } from 'utils/time'; import { SHORT_COMMIT_HASH_LENGTH } from '../../../../constants'; import { formatAddress } from '../../../../utils/format'; import { DeploymentMenu } from './DeploymentMenu'; +const DEPLOYMENT_LOGS_STYLE = { + backgroundColor: "rgba(0,0,0, .9)", + padding: "2em", + borderRadius: "0.5em", + marginLeft: "0.5em", + marginRight: "0.5em", + color: "gray", + fontSize: "small", +}; + interface DeployDetailsCardProps { deployment: Deployment; currentDeployment: Deployment; @@ -48,6 +65,12 @@ const DeploymentDetailsCard = ({ project, prodBranchDomains, }: DeployDetailsCardProps) => { + const [openDialog, setOpenDialog] = useState(false); + const handleOpenDialog = () => setOpenDialog(true); + const handleCloseDialog = () => setOpenDialog(false); + const [deploymentLogs, setDeploymentLogs] = useState(); + + const getIconByDeploymentStatus = (status: DeploymentStatus) => { if ( status === DeploymentStatus.Building || @@ -75,7 +98,10 @@ const DeploymentDetailsCard = ({ onClick={async()=> { let url = `${deployment.deployer.deployerApiUrl}/log/${deployment.applicationDeploymentRequestId}` const res = await fetch(url); - console.log(">>>>RESPONSE",await res.text()) + const logs = await res.text() + // console.log(">>>>RESPONSE",await res.text()) + setDeploymentLogs(logs) + handleOpenDialog() }} > {deployment.status} @@ -172,6 +198,15 @@ const DeploymentDetailsCard = ({ prodBranchDomains={prodBranchDomains} /> + + Deployment logs + + {deploymentLogs &&
{deploymentLogs}
} +
+ + + +
); }; -- 2.45.2 From f61a44751567496d91fce3664bbfcd3983a45036 Mon Sep 17 00:00:00 2001 From: Neeraj Date: Fri, 18 Oct 2024 12:12:28 +0530 Subject: [PATCH 07/10] Enable the deploy button when LRN is provided --- .../deployments/DeploymentDetailsCard.tsx | 17 +++++++++-------- .../frontend/src/pages/components/modals.tsx | 9 +++++++-- .../frontend/src/stories/MockStoriesData.ts | 9 +++++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx index ae3e452b..e03fc7ac 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx @@ -87,6 +87,14 @@ const DeploymentDetailsCard = ({ } }; + const fetchDeploymentLogs = useCallback(async () => { + let url = `${deployment.deployer.deployerApiUrl}/log/${deployment.applicationDeploymentRequestId}`; + const res = await fetch(url); + const logs = await res.text(); + setDeploymentLogs(logs); + handleOpenDialog(); + }, [deployment.deployer.deployerApiUrl, deployment.applicationDeploymentRequestId, handleOpenDialog]); + const renderDeploymentStatus = useCallback( (className?: string) => { return ( @@ -95,14 +103,7 @@ const DeploymentDetailsCard = ({ leftIcon={getIconByDeploymentStatus(deployment.status)} size="xs" type={STATUS_COLORS[deployment.status] ?? 'neutral'} - onClick={async()=> { - let url = `${deployment.deployer.deployerApiUrl}/log/${deployment.applicationDeploymentRequestId}` - const res = await fetch(url); - const logs = await res.text() - // console.log(">>>>RESPONSE",await res.text()) - setDeploymentLogs(logs) - handleOpenDialog() - }} + onClick={fetchDeploymentLogs} > {deployment.status} diff --git a/packages/frontend/src/pages/components/modals.tsx b/packages/frontend/src/pages/components/modals.tsx index 1eece68c..f1830c02 100644 --- a/packages/frontend/src/pages/components/modals.tsx +++ b/packages/frontend/src/pages/components/modals.tsx @@ -36,7 +36,11 @@ const deployment: Deployment = { url: 'https://deploy1.example.com', environment: Environment.Production, isCurrent: true, - deployerLrn: 'lrn://example/deployers/webapp-deployer-api.test.com', + deployer: { + deployerApiUrl: 'https://webapp-deployer-api.example.com', + deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu', + deployerLrn:'lrn://example/deployers/webapp-deployer-api.example.com' + }, status: DeploymentStatus.Ready, createdBy: { id: 'user1', @@ -49,6 +53,7 @@ const deployment: Deployment = { }, createdAt: '1677676800', // 2023-03-01T12:00:00Z updatedAt: '1677680400', // 2023-03-01T13:00:00Z + applicationDeploymentRequestId: 'bafyreiaycvq6imoppnpwdve4smj6t6ql5svt5zl3x6rimu4qwyzgjorize', }; const domains: Domain[] = [ @@ -270,4 +275,4 @@ const ModalsPage: React.FC = () => { ); }; -export default ModalsPage; +export default ModalsPage; \ No newline at end of file diff --git a/packages/frontend/src/stories/MockStoriesData.ts b/packages/frontend/src/stories/MockStoriesData.ts index 5559cbed..fc5e186d 100644 --- a/packages/frontend/src/stories/MockStoriesData.ts +++ b/packages/frontend/src/stories/MockStoriesData.ts @@ -102,7 +102,12 @@ export const deployment0: Deployment = { domain: domain0, commitMessage: 'Commit Message', createdBy: user, - deployerLrn: 'lrn://deployer.apps.snowballtools.com ', + deployer: { + deployerApiUrl: 'https://webapp-deployer-api.example.com', + deployerId: 'bafyreicrtgmkir4evvvysxdqxddf2ftdq2wrzuodgvwnxr4rmubi4obdfu', + deployerLrn:'lrn://deployer.apps.snowballtools.com ' + }, + applicationDeploymentRequestId: 'bafyreiaycvq6imoppnpwdve4smj6t6ql5svt5zl3x6rimu4qwyzgjorize', }; export const project: Project = { @@ -126,4 +131,4 @@ export const project: Project = { icon: 'Icon', fundsReleased: true, baseDomains: ['baseDomain'], -}; +}; \ No newline at end of file -- 2.45.2 From 380cc0cba6db1c2a21518579c94aa37564d5e62a Mon Sep 17 00:00:00 2001 From: Neeraj Date: Fri, 18 Oct 2024 13:08:23 +0530 Subject: [PATCH 08/10] Update project deployer relation in db --- packages/backend/src/entity/Deployer.ts | 3 +++ packages/backend/src/entity/Project.ts | 8 +++----- packages/backend/src/service.ts | 24 ++++++++++++------------ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/backend/src/entity/Deployer.ts b/packages/backend/src/entity/Deployer.ts index 40d91a77..8dc309ec 100644 --- a/packages/backend/src/entity/Deployer.ts +++ b/packages/backend/src/entity/Deployer.ts @@ -10,4 +10,7 @@ export class Deployer { @Column() deployerApiUrl!: string; + + @Column() + baseDomain!: string; } diff --git a/packages/backend/src/entity/Project.ts b/packages/backend/src/entity/Project.ts index d9696767..43b1f759 100644 --- a/packages/backend/src/entity/Project.ts +++ b/packages/backend/src/entity/Project.ts @@ -14,6 +14,7 @@ import { User } from './User'; import { Organization } from './Organization'; import { ProjectMember } from './ProjectMember'; import { Deployment } from './Deployment'; +import { Deployer } from './Deployer'; @Entity() export class Project { @@ -49,8 +50,8 @@ export class Project { @Column('varchar', { nullable: true }) auctionId!: string | null; - @Column({ type: 'simple-array', nullable: true }) - deployerLrns!: string[] | null; + @OneToMany(() => Deployer, (deployer) => deployer.deployerId) + deployers!: Deployer[]; @Column('boolean', { default: false, nullable: true }) fundsReleased!: boolean; @@ -70,9 +71,6 @@ export class Project { @Column('varchar') icon!: string; - @Column({ type: 'simple-array', nullable: true }) - baseDomains!: string[] | null; - @CreateDateColumn() createdAt!: Date; diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index 5bf955f6..0ec8849f 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -330,10 +330,10 @@ export class Service { await this.db.addDeployer(deployerData); } - // Update project with deployer LRNs - await this.db.updateProjectById(project.id!, { - deployerLrns - }); + // TODO:Update project with deployer LRNs + // await this.db.updateProjectById(project.id!, { + // deployerLrns + // }); for (const deployer of deployerIds) { log(`Creating deployment for deployer LRN ${deployer}`); @@ -889,7 +889,7 @@ export class Service { await this.updateProject(project.id, { auctionId: applicationDeploymentAuctionId }) } else { await this.createDeployment(user.id, octokit, deploymentData); - await this.updateProject(project.id, { deployerLrns: [lrn!] }) + // await this.updateProject(project.id, { deployerLrns: [lrn!] }) } await this.createRepoHook(octokit, project); @@ -960,13 +960,13 @@ export class Service { }); // TODO: Store deployer in project - const deployers = project.deployerLrns; - if (!deployers) { - log(`No deployer present for project ${project.id}`) - return; - } + // const deployers = project.deployerLrns; + // if (!deployers) { + // log(`No deployer present for project ${project.id}`) + // return; + // } - for (const deployer of deployers) { + // for (const deployer of deployers) { // Create deployment with branch and latest commit in GitHub data await this.createDeployment(project.ownerId, octokit, { @@ -982,7 +982,7 @@ export class Service { // deployer: deployer }, ); - } + // } } } -- 2.45.2 From 224672382fce3e318b39b286b0312a55bae1e144 Mon Sep 17 00:00:00 2001 From: IshaVenikar Date: Mon, 21 Oct 2024 14:15:23 +0530 Subject: [PATCH 09/10] Store base domains in deployer table --- packages/backend/src/entity/Deployer.ts | 18 ++-- packages/backend/src/entity/Deployment.ts | 3 - packages/backend/src/registry.ts | 29 ++++--- packages/backend/src/service.ts | 87 +++++++++++-------- .../deployments/DeploymentDetailsCard.tsx | 20 +++-- 5 files changed, 92 insertions(+), 65 deletions(-) diff --git a/packages/backend/src/entity/Deployer.ts b/packages/backend/src/entity/Deployer.ts index 8dc309ec..b37e735f 100644 --- a/packages/backend/src/entity/Deployer.ts +++ b/packages/backend/src/entity/Deployer.ts @@ -1,16 +1,16 @@ -import { Entity, PrimaryColumn, Column, OneToMany } from 'typeorm'; +import { Entity, PrimaryColumn, Column } from 'typeorm'; @Entity() export class Deployer { - @PrimaryColumn() - deployerId!: string; + @PrimaryColumn('varchar') + deployerId!: string; - @Column() - deployerLrn!: string; + @Column('varchar') + deployerLrn!: string; - @Column() - deployerApiUrl!: string; + @Column('varchar') + deployerApiUrl!: string; - @Column() - baseDomain!: string; + @Column('varchar') + baseDomain!: string; } diff --git a/packages/backend/src/entity/Deployment.ts b/packages/backend/src/entity/Deployment.ts index 68c731d7..21bfb4e4 100644 --- a/packages/backend/src/entity/Deployment.ts +++ b/packages/backend/src/entity/Deployment.ts @@ -140,9 +140,6 @@ export class Deployment { @Column('boolean', { default: false }) isCurrent!: boolean; - @Column('varchar', { nullable: true }) - baseDomain!: string | null; - @Column({ enum: DeploymentStatus }) diff --git a/packages/backend/src/registry.ts b/packages/backend/src/registry.ts index 79d0cc64..f4df1353 100644 --- a/packages/backend/src/registry.ts +++ b/packages/backend/src/registry.ts @@ -117,7 +117,7 @@ export class Registry { this.registryConfig.privateKey, fee ); - log("Result: ", result); + log(`Published application record ${result.id}`); log('Application record data:', applicationRecord); @@ -302,13 +302,9 @@ export class Registry { const { winnerAddresses } = auctionResult; for (const auctionWinner of winnerAddresses) { - const records = await this.registry.queryRecords( - { - paymentAddress: auctionWinner, - type: WEBAPP_DEPLOYER_RECORD_TYPE, - }, - true - ); + const records = await this.getDeployerRecordsByFilter({ + paymentAddress: auctionWinner, + }); for (const record of records) { if (record.id) { @@ -361,6 +357,19 @@ export class Registry { ); } + /** + * Fetch WebappDeployer Records by filter + */ + async getDeployerRecordsByFilter(filter: { [key: string]: any }): Promise { + return this.registry.queryRecords( + { + type: WEBAPP_DEPLOYER_RECORD_TYPE, + ...filter + }, + true + ); + } + /** * Fetch ApplicationDeploymentRecords by filter */ @@ -441,8 +450,8 @@ export class Registry { const auctions = await this.registry.getAuctionsByIds(auctionIds); const completedAuctions = auctions - .filter((auction: { id: string, status: string }) => auction.status === 'completed') - .map((auction: { id: string, status: string }) => auction.id); + .filter((auction: { id: string, status: string }) => auction.status === 'completed') + .map((auction: { id: string, status: string }) => auction.id); return completedAuctions; } diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index 0ec8849f..111e3a20 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -176,6 +176,7 @@ export class Service { })), relations: { deployer: true, + project: true, }, order: { createdAt: 'DESC', @@ -194,17 +195,19 @@ export class Service { const deploymentUpdatePromises = records.map(async (record) => { const deployment = recordToDeploymentsMap[record.attributes.request]; - const parts = record.attributes.url.replace('https://', '').split('.'); - const baseDomain = parts.slice(1).join('.'); + if (!deployment.project) { + log(`Project ${deployment.projectId} not found`); + return; + } + else { + deployment.applicationDeploymentRecordId = record.id; + deployment.applicationDeploymentRecordData = record.attributes; + deployment.url = record.attributes.url; + deployment.status = DeploymentStatus.Ready; + deployment.isCurrent = deployment.environment === Environment.Production; - deployment.applicationDeploymentRecordId = record.id; - deployment.applicationDeploymentRecordData = record.attributes; - deployment.url = record.attributes.url; - deployment.baseDomain = baseDomain; - deployment.status = DeploymentStatus.Ready; - deployment.isCurrent = deployment.environment === Environment.Production; - - await this.db.updateDeploymentById(deployment.id, deployment); + await this.db.updateDeploymentById(deployment.id, deployment); + } log( `Updated deployment ${deployment.id} with URL ${record.attributes.url}`, @@ -314,27 +317,27 @@ export class Service { for (const record of deployerRecords) { const deployerId = record.id; - const deployerLrn = record.names[0] - const deployerApiUrl = record.attributes.apiUrl; + const deployerLrn = record.names[0]; deployerIds.push(deployerId); deployerLrns.push(deployerLrn); + const deployerApiUrl = record.attributes.apiUrl; + const apiURL = new URL(deployerApiUrl); + const baseDomain = apiURL.hostname.split('.').slice(-3).join('.'); + const deployerData = { deployerId, deployerLrn, deployerApiUrl, + baseDomain }; // Store the deployer in the DB + // TODO: Update project with deployer await this.db.addDeployer(deployerData); } - // TODO:Update project with deployer LRNs - // await this.db.updateProjectById(project.id!, { - // deployerLrns - // }); - for (const deployer of deployerIds) { log(`Creating deployment for deployer LRN ${deployer}`); await this.createDeploymentFromAuction(project, deployer); @@ -676,6 +679,19 @@ export class Service { applicationDeploymentRequestData, }); + // const deployerRecord = await this.laconicRegistry.getDeployerRecordsByFilter({ + // name: deployerLrn, + // }); + + // TODO: Store deployer data + // newDeployment.project.deployers.push({ + // deployerId: deployerRecord[0].id, + // deployerApiUrl: deployerRecord[0].attributes.apiUrl, + // }) + // await this.updateProject(newDeployment.project.id, { + // deployers: + // }); + return newDeployment; } @@ -886,7 +902,7 @@ export class Service { if (auctionParams) { const { applicationDeploymentAuctionId } = await this.laconicRegistry.createApplicationDeploymentAuction(repo, octokit, auctionParams!, deploymentData); - await this.updateProject(project.id, { auctionId: applicationDeploymentAuctionId }) + await this.updateProject(project.id, { auctionId: applicationDeploymentAuctionId }); } else { await this.createDeployment(user.id, octokit, deploymentData); // await this.updateProject(project.id, { deployerLrns: [lrn!] }) @@ -966,22 +982,25 @@ export class Service { // return; // } + const deployers = project.deployers; + if (!deployers) return; + // for (const deployer of deployers) { - // Create deployment with branch and latest commit in GitHub data - await this.createDeployment(project.ownerId, octokit, - { - project, - branch, - environment: - project.prodBranch === branch - ? Environment.Production - : Environment.Preview, - domain, - commitHash: headCommit.id, - commitMessage: headCommit.message, - // deployer: deployer - }, - ); + // Create deployment with branch and latest commit in GitHub data + await this.createDeployment(project.ownerId, octokit, + { + project, + branch, + environment: + project.prodBranch === branch + ? Environment.Production + : Environment.Preview, + domain, + commitHash: headCommit.id, + commitMessage: headCommit.message, + // deployer: deployer + }, + ); // } } } @@ -1101,7 +1120,7 @@ export class Service { if (deployment && deployment.applicationDeploymentRecordId) { // If deployment is current, remove deployment for project subdomain as well if (deployment.isCurrent) { - const currentDeploymentURL = `https://${(deployment.project.name).toLowerCase()}.${deployment.baseDomain}`; + const currentDeploymentURL = `https://${(deployment.project.name).toLowerCase()}.${deployment.deployer.baseDomain}`; // TODO: Store the latest DNS deployment record const deploymentRecords = diff --git a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx index e03fc7ac..499aed76 100644 --- a/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx +++ b/packages/frontend/src/components/projects/project/deployments/DeploymentDetailsCard.tsx @@ -6,6 +6,14 @@ import { Environment, Project, } from 'gql-client'; + +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, +} from '@mui/material'; + import { Avatar } from 'components/shared/Avatar'; import { BranchStrokeIcon, @@ -15,12 +23,6 @@ import { LoadingIcon, WarningIcon, } from 'components/shared/CustomIcon'; -import { - Dialog, - DialogTitle, - DialogContent, - DialogActions, -} from '@mui/material'; import { Heading } from 'components/shared/Heading'; import { OverflownText } from 'components/shared/OverflownText'; import { Tag, TagTheme } from 'components/shared/Tag'; @@ -66,10 +68,10 @@ const DeploymentDetailsCard = ({ prodBranchDomains, }: DeployDetailsCardProps) => { const [openDialog, setOpenDialog] = useState(false); - const handleOpenDialog = () => setOpenDialog(true); - const handleCloseDialog = () => setOpenDialog(false); const [deploymentLogs, setDeploymentLogs] = useState(); + const handleOpenDialog = () => setOpenDialog(true); + const handleCloseDialog = () => setOpenDialog(false); const getIconByDeploymentStatus = (status: DeploymentStatus) => { if ( @@ -89,7 +91,7 @@ const DeploymentDetailsCard = ({ const fetchDeploymentLogs = useCallback(async () => { let url = `${deployment.deployer.deployerApiUrl}/log/${deployment.applicationDeploymentRequestId}`; - const res = await fetch(url); + const res = await fetch(url, { cache: 'no-store' }); const logs = await res.text(); setDeploymentLogs(logs); handleOpenDialog(); -- 2.45.2 From 09762c811a9b9d44e6fe175dbfc60913b0592ddd Mon Sep 17 00:00:00 2001 From: IshaVenikar Date: Tue, 22 Oct 2024 11:19:02 +0530 Subject: [PATCH 10/10] Store deployers for projects after successful deployments --- packages/backend/src/database.ts | 8 +- packages/backend/src/entity/Deployer.ts | 6 +- packages/backend/src/entity/Project.ts | 9 +- packages/backend/src/service.ts | 212 ++++++++++-------- .../components/projects/create/Configure.tsx | 26 +-- .../frontend/src/pages/components/modals.tsx | 2 +- .../frontend/src/stories/MockStoriesData.ts | 2 +- 7 files changed, 146 insertions(+), 119 deletions(-) diff --git a/packages/backend/src/database.ts b/packages/backend/src/database.ts index 2798f1bc..5b681c3f 100644 --- a/packages/backend/src/database.ts +++ b/packages/backend/src/database.ts @@ -490,7 +490,13 @@ export class Database { return projectRepository.save(newProject); } - async updateProjectById( + async saveProject (project: Project): Promise { + const projectRepository = this.dataSource.getRepository(Project); + + return projectRepository.save(project); + } + + async updateProjectById ( projectId: string, data: DeepPartial ): Promise { diff --git a/packages/backend/src/entity/Deployer.ts b/packages/backend/src/entity/Deployer.ts index b37e735f..bdb920e3 100644 --- a/packages/backend/src/entity/Deployer.ts +++ b/packages/backend/src/entity/Deployer.ts @@ -1,4 +1,5 @@ -import { Entity, PrimaryColumn, Column } from 'typeorm'; +import { Entity, PrimaryColumn, Column, ManyToMany } from 'typeorm'; +import { Project } from './Project'; @Entity() export class Deployer { @@ -13,4 +14,7 @@ export class Deployer { @Column('varchar') baseDomain!: string; + + @ManyToMany(() => Project, (project) => project.deployers) + projects!: Project[]; } diff --git a/packages/backend/src/entity/Project.ts b/packages/backend/src/entity/Project.ts index 43b1f759..9edfdfd5 100644 --- a/packages/backend/src/entity/Project.ts +++ b/packages/backend/src/entity/Project.ts @@ -7,7 +7,9 @@ import { ManyToOne, JoinColumn, OneToMany, - DeleteDateColumn + DeleteDateColumn, + JoinTable, + ManyToMany } from 'typeorm'; import { User } from './User'; @@ -50,8 +52,9 @@ export class Project { @Column('varchar', { nullable: true }) auctionId!: string | null; - @OneToMany(() => Deployer, (deployer) => deployer.deployerId) - deployers!: Deployer[]; + @ManyToMany(() => Deployer, (deployer) => (deployer.projects)) + @JoinTable() + deployers!: Deployer[] @Column('boolean', { default: false, nullable: true }) fundsReleased!: boolean; diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index 111e3a20..318e0c9b 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -198,8 +198,7 @@ export class Service { if (!deployment.project) { log(`Project ${deployment.projectId} not found`); return; - } - else { + } else { deployment.applicationDeploymentRecordId = record.id; deployment.applicationDeploymentRecordData = record.attributes; deployment.url = record.attributes.url; @@ -207,11 +206,20 @@ export class Service { deployment.isCurrent = deployment.environment === Environment.Production; await this.db.updateDeploymentById(deployment.id, deployment); - } - log( - `Updated deployment ${deployment.id} with URL ${record.attributes.url}`, - ); + // Release deployer funds on successful deployment + if (!deployment.project.fundsReleased) { + const fundsReleased = await this.releaseDeployerFundsByProjectId(deployment.projectId); + + await this.db.updateProjectById(deployment.projectId, { + fundsReleased, + }); + } + + log( + `Updated deployment ${deployment.id} with URL ${record.attributes.url}`, + ); + } }); await Promise.all(deploymentUpdatePromises); @@ -295,53 +303,40 @@ export class Service { completedAuctionIds.includes(project.auctionId!) ); - for (const project of projectsToBedeployed) { - const deployers = await this.laconicRegistry.getAuctionWinningDeployerRecords(project!.auctionId!); + const deployerRecords = await this.laconicRegistry.getAuctionWinningDeployerRecords(project!.auctionId!); - if (!deployers) { + if (!deployerRecords) { log(`No winning deployer for auction ${project!.auctionId}`); } else { - // TODO:Update project with deployer LRNs - // await this.db.updateProjectById(project.id!, { - // deployers - // }); + const deployerIds = []; - const deployerRecords = await this.laconicRegistry.getAuctionWinningDeployerRecords(project!.auctionId!); + for (const record of deployerRecords) { + const deployerId = record.id; + const deployerLrn = record.names[0]; - if (!deployerRecords) { - log(`No winning deployer for auction ${project!.auctionId}`); - } else { - const deployerLrns = []; - const deployerIds = []; + deployerIds.push(deployerId); - for (const record of deployerRecords) { - const deployerId = record.id; - const deployerLrn = record.names[0]; + const deployerApiUrl = record.attributes.apiUrl; + const baseDomain = deployerApiUrl.substring(deployerApiUrl.indexOf('.') + 1); - deployerIds.push(deployerId); - deployerLrns.push(deployerLrn); + const deployerData = { + deployerId, + deployerLrn, + deployerApiUrl, + baseDomain + }; - const deployerApiUrl = record.attributes.apiUrl; - const apiURL = new URL(deployerApiUrl); - const baseDomain = apiURL.hostname.split('.').slice(-3).join('.'); + // Store the deployer in the DB + const deployer = await this.db.addDeployer(deployerData); - const deployerData = { - deployerId, - deployerLrn, - deployerApiUrl, - baseDomain - }; + // Update project with deployer + await this.updateProjectWithDeployer(project.id, deployer); + } - // Store the deployer in the DB - // TODO: Update project with deployer - await this.db.addDeployer(deployerData); - } - - for (const deployer of deployerIds) { - log(`Creating deployment for deployer LRN ${deployer}`); - await this.createDeploymentFromAuction(project, deployer); - } + for (const deployer of deployerIds) { + log(`Creating deployment for deployer LRN ${deployer}`); + await this.createDeploymentFromAuction(project, deployer); } } } @@ -617,7 +612,8 @@ export class Service { async createDeployment( userId: string, octokit: Octokit, - data: DeepPartial + data: DeepPartial, + deployerLrn?: string ): Promise { assert(data.project?.repository, 'Project repository not found'); log( @@ -646,7 +642,14 @@ export class Service { ); } - const newDeployment = await this.createDeploymentFromData(userId, data, data.deployer!.deployerId!, applicationRecordId, applicationRecordData); + let deployer; + if (deployerLrn) { + deployer = await this.createDeployerFromLRN(deployerLrn); + } else { + deployer = data.deployer; + } + + const newDeployment = await this.createDeploymentFromData(userId, data, deployer!.deployerId!, applicationRecordId, applicationRecordData); const { repo, repoUrl } = await getRepoDetails(octokit, data.project.repository, data.commitHash); const environmentVariablesObj = await this.getEnvVariables(data.project!.id!); @@ -660,7 +663,7 @@ export class Service { repository: repoUrl, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}`, - lrn: data.deployer!.deployerLrn! + lrn: deployer!.deployerLrn! }); } @@ -669,7 +672,7 @@ export class Service { deployment: newDeployment, appName: repo, repository: repoUrl, - lrn: data.deployer!.deployerLrn!, + lrn: deployer!.deployerLrn!, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}-${newDeployment.id}`, }); @@ -679,19 +682,6 @@ export class Service { applicationDeploymentRequestData, }); - // const deployerRecord = await this.laconicRegistry.getDeployerRecordsByFilter({ - // name: deployerLrn, - // }); - - // TODO: Store deployer data - // newDeployment.project.deployers.push({ - // deployerId: deployerRecord[0].id, - // deployerApiUrl: deployerRecord[0].attributes.apiUrl, - // }) - // await this.updateProject(newDeployment.project.id, { - // deployers: - // }); - return newDeployment; } @@ -804,6 +794,50 @@ export class Service { return newDeployment; } + async createDeployerFromLRN(deployerLrn: string): Promise { + const records = await this.laconicRegistry.getRecordsByName(deployerLrn); + + if (records.length === 0) { + log('No records found for deployer LRN:', deployerLrn); + return null; + } + + const deployerId = records[0].id; + const deployerApiUrl = records[0].attributes.apiUrl; + const baseDomain = deployerApiUrl.substring(deployerApiUrl.indexOf('.') + 1); + + const deployerData = { + deployerId, + deployerLrn, + deployerApiUrl, + baseDomain + }; + + const deployer = await this.db.addDeployer(deployerData); + + return deployer; + } + + async updateProjectWithDeployer( + projectId: string, + deployer: Deployer + ): Promise { + const deploymentProject = await this.db.getProjects({ + where: { id: projectId }, + relations: ['deployers'] + }); + + if (!deploymentProject[0].deployers) { + deploymentProject[0].deployers = []; + } + + deploymentProject[0].deployers.push(deployer); + + await this.db.saveProject(deploymentProject[0]); + + return deployer; + } + async addProjectFromTemplate( user: User, organizationSlug: string, @@ -867,6 +901,7 @@ export class Service { slug: organizationSlug, }, }); + if (!organization) { throw new Error('Organization does not exist'); } @@ -897,15 +932,15 @@ export class Service { domain: null, commitHash: latestCommit.sha, commitMessage: latestCommit.commit.message, - deployerLrn: lrn }; if (auctionParams) { const { applicationDeploymentAuctionId } = await this.laconicRegistry.createApplicationDeploymentAuction(repo, octokit, auctionParams!, deploymentData); await this.updateProject(project.id, { auctionId: applicationDeploymentAuctionId }); } else { - await this.createDeployment(user.id, octokit, deploymentData); - // await this.updateProject(project.id, { deployerLrns: [lrn!] }) + const newDeployment = await this.createDeployment(user.id, octokit, deploymentData, lrn); + // Update project with deployer + await this.updateProjectWithDeployer(newDeployment.projectId, newDeployment.deployer); } await this.createRepoHook(octokit, project); @@ -959,6 +994,9 @@ export class Service { ); const projects = await this.db.getProjects({ where: { repository: repository.full_name }, + relations: { + deployers: true, + } }); if (!projects.length) { @@ -975,33 +1013,29 @@ export class Service { branch, }); - // TODO: Store deployer in project - // const deployers = project.deployerLrns; - // if (!deployers) { - // log(`No deployer present for project ${project.id}`) - // return; - // } - const deployers = project.deployers; - if (!deployers) return; + if (!deployers) { + log(`No deployer present for project ${project.id}`) + return; + } - // for (const deployer of deployers) { - // Create deployment with branch and latest commit in GitHub data - await this.createDeployment(project.ownerId, octokit, - { - project, - branch, - environment: - project.prodBranch === branch - ? Environment.Production - : Environment.Preview, - domain, - commitHash: headCommit.id, - commitMessage: headCommit.message, - // deployer: deployer - }, - ); - // } + for (const deployer of deployers) { + // Create deployment with branch and latest commit in GitHub data + await this.createDeployment(project.ownerId, octokit, + { + project, + branch, + environment: + project.prodBranch === branch + ? Environment.Production + : Environment.Preview, + domain, + commitHash: headCommit.id, + commitMessage: headCommit.message, + deployer: deployer + }, + ); + } } } @@ -1038,6 +1072,7 @@ export class Service { relations: { project: true, domain: true, + deployer: true, createdBy: true, }, where: { @@ -1054,7 +1089,7 @@ export class Service { let newDeployment: Deployment; if (oldDeployment.project.auctionId) { - newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployer.deployerLrn); + newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployer.deployerId); } else { newDeployment = await this.createDeployment(user.id, octokit, { @@ -1114,6 +1149,7 @@ export class Service { }, relations: { project: true, + deployer: true, }, }); diff --git a/packages/frontend/src/components/projects/create/Configure.tsx b/packages/frontend/src/components/projects/create/Configure.tsx index ac08ae2b..09a0b6b4 100644 --- a/packages/frontend/src/components/projects/create/Configure.tsx +++ b/packages/frontend/src/components/projects/create/Configure.tsx @@ -139,30 +139,8 @@ const Configure = () => { const projectId = await createProject(createFormData, environmentVariables); - const { environmentVariables: isEnvironmentVariablesAdded } = - await client.getEnvironmentVariables(projectId); + await client.getEnvironmentVariables(projectId); - if (isEnvironmentVariablesAdded.length > 0) { - toast({ - id: - createFormData.variables.length > 1 - ? 'env_variable_added' - : 'env_variables_added', - title: - createFormData.variables.length > 1 - ? `${createFormData.variables.length} variables added` - : `Variable added`, - variant: 'success', - onDismiss: dismiss, - }); - } else { - toast({ - id: 'env_variables_not_added', - title: 'Environment variables not added', - variant: 'error', - onDismiss: dismiss, - }); - } if (templateId) { createFormData.option === 'Auction' ? navigate( @@ -308,4 +286,4 @@ const Configure = () => { ); }; -export default Configure; \ No newline at end of file +export default Configure; diff --git a/packages/frontend/src/pages/components/modals.tsx b/packages/frontend/src/pages/components/modals.tsx index f1830c02..8e333101 100644 --- a/packages/frontend/src/pages/components/modals.tsx +++ b/packages/frontend/src/pages/components/modals.tsx @@ -275,4 +275,4 @@ const ModalsPage: React.FC = () => { ); }; -export default ModalsPage; \ No newline at end of file +export default ModalsPage; diff --git a/packages/frontend/src/stories/MockStoriesData.ts b/packages/frontend/src/stories/MockStoriesData.ts index fc5e186d..3a64356f 100644 --- a/packages/frontend/src/stories/MockStoriesData.ts +++ b/packages/frontend/src/stories/MockStoriesData.ts @@ -131,4 +131,4 @@ export const project: Project = { icon: 'Icon', fundsReleased: true, baseDomains: ['baseDomain'], -}; \ No newline at end of file +}; -- 2.45.2