List deployer LRNs in deployment configuration step (#11)

Part of [Service provider auctions for web deployments](https://www.notion.so/Service-provider-auctions-for-web-deployments-104a6b22d47280dbad51d28aa3a91d75)

- Fix request Id being set to `null` while fetching build logs
- Populate deployer LRNs dropdown with LRNs fetched from registry in configure delpoyment step

![image](/attachments/ff421bdf-6e0b-443e-9dc8-455bde481b4f)

![image](/attachments/87c9bce3-3743-4f4a-a997-a02a3504e61e)

![image](/attachments/dd442fe6-ad30-4723-a2bb-0723ad3eb3c9)

![image](/attachments/37f0da01-671f-4e3a-92e4-b34e25566a0d)

Co-authored-by: IshaVenikar <ishavenikar7@gmail.com>
Co-authored-by: Neeraj <neeraj.rtly@gmail.com>
Reviewed-on: cerc-io/snowballtools-base#11
This commit is contained in:
2024-10-23 15:36:19 +00:00
co-authored by IshaVenikar Neeraj
parent 096318cf13
commit 3d9aedeb7e
17 changed files with 273 additions and 161 deletions
+11 -9
View File
@@ -34,9 +34,8 @@ const nanoid = customAlphabet(lowercase + numbers, 8);
// TODO: Fix order of methods
export class Database {
private dataSource: DataSource;
private projectDomain: string;
constructor({ dbPath }: DatabaseConfig, { projectDomain }: MiscConfig) {
constructor({ dbPath }: DatabaseConfig) {
this.dataSource = new DataSource({
type: 'better-sqlite3',
database: dbPath,
@@ -44,8 +43,6 @@ export class Database {
synchronize: true,
logging: false
});
this.projectDomain = projectDomain;
}
async init(): Promise<void> {
@@ -491,13 +488,13 @@ export class Database {
return projectRepository.save(newProject);
}
async saveProject (project: Project): Promise<Project> {
async saveProject(project: Project): Promise<Project> {
const projectRepository = this.dataSource.getRepository(Project);
return projectRepository.save(project);
}
async updateProjectById (
async updateProjectById(
projectId: string,
data: DeepPartial<Project>
): Promise<boolean> {
@@ -583,17 +580,22 @@ export class Database {
return domains;
}
async addDeployer (data: DeepPartial<Deployer>): Promise<Deployer> {
async addDeployer(data: DeepPartial<Deployer>): Promise<Deployer> {
const deployerRepository = this.dataSource.getRepository(Deployer);
const newDomain = await deployerRepository.save(data);
return newDomain;
}
async getDeployerById (deployerId: string): Promise<Deployer | null> {
async getDeployers(): Promise<Deployer[]> {
const deployerRepository = this.dataSource.getRepository(Deployer);
const deployers = await deployerRepository.find();
return deployers;
}
const deployer = await deployerRepository.findOne({ where: { deployerId } });
async getDeployerByLRN(deployerLrn: string): Promise<Deployer | null> {
const deployerRepository = this.dataSource.getRepository(Deployer);
const deployer = await deployerRepository.findOne({ where: { deployerLrn } });
return deployer;
}
+2 -2
View File
@@ -4,10 +4,10 @@ import { Project } from './Project';
@Entity()
export class Deployer {
@PrimaryColumn('varchar')
deployerId!: string;
deployerLrn!: string;
@Column('varchar')
deployerLrn!: string;
deployerId!: string;
@Column('varchar')
deployerApiUrl!: string;
+1 -1
View File
@@ -129,7 +129,7 @@ export class Deployment {
applicationDeploymentRemovalRecordData!: AppDeploymentRemovalRecordAttributes | null;
@ManyToOne(() => Deployer)
@JoinColumn({ name: 'deployerId' })
@JoinColumn({ name: 'deployerLrn' })
deployer!: Deployer;
@Column({
+1 -1
View File
@@ -25,7 +25,7 @@ export const main = async (): Promise<void> => {
clientSecret: gitHub.oAuth.clientSecret,
});
const db = new Database(database, misc);
const db = new Database(database);
await db.init();
const registry = new Registry(registryConfig);
+1
View File
@@ -283,6 +283,7 @@ export class Registry {
this.registryConfig.privateKey,
fee
);
log(`Application deployment request record published: ${result.id}`);
log('Application deployment request data:', applicationDeploymentRequest);
+4
View File
@@ -76,6 +76,10 @@ export const createResolvers = async (service: Service): Promise<any> => {
) => {
return service.getAuctionData(auctionId);
},
deployers: async (_: any, __: any, context: any) => {
return service.getDeployers();
},
},
// TODO: Return error in GQL response
+2 -1
View File
@@ -134,8 +134,8 @@ type EnvironmentVariable {
}
type Deployer {
deployerId: String!
deployerLrn: String!
deployerId: String!
deployerApiUrl: String!
createdAt: String!
updatedAt: String!
@@ -257,6 +257,7 @@ type Query {
searchProjects(searchText: String!): [Project!]
getAuctionData(auctionId: String!): Auction!
domains(projectId: String!, filter: FilterDomainsInput): [Domain]
deployers: [Deployer]
}
type Mutation {
+58 -58
View File
@@ -21,6 +21,7 @@ import {
AppDeploymentRecord,
AppDeploymentRemovalRecord,
AuctionParams,
DeployerRecord,
EnvironmentVariables,
GitPushEventPayload,
} from './types';
@@ -309,35 +310,13 @@ export class Service {
if (!deployerRecords) {
log(`No winning deployer for auction ${project!.auctionId}`);
} else {
const deployerIds = [];
for (const record of deployerRecords) {
const deployerId = record.id;
const deployerLrn = record.names[0];
deployerIds.push(deployerId);
const deployerApiUrl = record.attributes.apiUrl;
const baseDomain = deployerApiUrl.substring(deployerApiUrl.indexOf('.') + 1);
const deployerData = {
deployerId,
deployerLrn,
deployerApiUrl,
baseDomain
};
// Store the deployer in the DB
const deployer = await this.db.addDeployer(deployerData);
const deployers = await this.saveDeployersByDeployerRecords(deployerRecords);
for (const deployer of deployers) {
log(`Creating deployment for deployer ${deployer.deployerLrn}`);
await this.createDeploymentFromAuction(project, deployer);
// Update project with deployer
await this.updateProjectWithDeployer(project.id, deployer);
}
for (const deployer of deployerIds) {
log(`Creating deployment for deployer LRN ${deployer}`);
await this.createDeploymentFromAuction(project, deployer);
}
}
}
@@ -644,12 +623,12 @@ export class Service {
let deployer;
if (deployerLrn) {
deployer = await this.createDeployerFromLRN(deployerLrn);
deployer = await this.db.getDeployerByLRN(deployerLrn);
} else {
deployer = data.deployer;
}
const newDeployment = await this.createDeploymentFromData(userId, data, deployer!.deployerId!, applicationRecordId, applicationRecordData);
const newDeployment = await this.createDeploymentFromData(userId, data, deployer!.deployerLrn!, applicationRecordId, applicationRecordData);
const { repo, repoUrl } = await getRepoDetails(octokit, data.project.repository, data.commitHash);
const environmentVariablesObj = await this.getEnvVariables(data.project!.id!);
@@ -687,7 +666,7 @@ export class Service {
async createDeploymentFromAuction(
project: DeepPartial<Project>,
deployerId: string
deployer: Deployer
): Promise<Deployment> {
const octokit = await this.getOctokit(project.ownerId!);
const [owner, repo] = project.repository!.split('/');
@@ -713,7 +692,6 @@ 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
@@ -726,7 +704,7 @@ export class Service {
commitMessage: latestCommit.commit.message,
};
const newDeployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerId, applicationRecordId, applicationRecordData);
const newDeployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerLrn, applicationRecordId, applicationRecordData);
const environmentVariablesObj = await this.getEnvVariables(project!.id!);
// To set project DNS
@@ -767,7 +745,7 @@ export class Service {
async createDeploymentFromData(
userId: string,
data: DeepPartial<Deployment>,
deployerId: string,
deployerLrn: string,
applicationRecordId: string,
applicationRecordData: ApplicationRecord,
): Promise<Deployment> {
@@ -785,7 +763,7 @@ export class Service {
id: userId,
}),
deployer: Object.assign(new Deployer(), {
deployerId,
deployerLrn,
}),
});
@@ -794,30 +772,6 @@ export class Service {
return newDeployment;
}
async createDeployerFromLRN(deployerLrn: string): Promise<Deployer | null> {
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
@@ -1089,7 +1043,7 @@ export class Service {
let newDeployment: Deployment;
if (oldDeployment.project.auctionId) {
newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployer.deployerId);
newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployer);
} else {
newDeployment = await this.createDeployment(user.id, octokit,
{
@@ -1369,4 +1323,50 @@ export class Service {
return false;
}
async getDeployers(): Promise<Deployer[]> {
const dbDeployers = await this.db.getDeployers();
if (dbDeployers.length > 0) {
// Call asynchronously to fetch the records from the registry and update the DB
this.updateDeployersFromRegistry();
return dbDeployers;
} else {
// Fetch from the registry and populate empty DB
return await this.updateDeployersFromRegistry();
}
}
async updateDeployersFromRegistry(): Promise<Deployer[]> {
const deployerRecords = await this.laconicRegistry.getDeployerRecordsByFilter({});
await this.saveDeployersByDeployerRecords(deployerRecords);
return await this.db.getDeployers();
}
async saveDeployersByDeployerRecords(deployerRecords: DeployerRecord[]): Promise<Deployer[]> {
const deployers: Deployer[] = [];
for (const record of deployerRecords) {
if (record.names.length > 0) {
const deployerId = record.id;
const deployerLrn = record.names[0];
const deployerApiUrl = record.attributes.apiUrl;
const baseDomain = deployerApiUrl.substring(deployerApiUrl.indexOf('.') + 1);
const deployerData = {
deployerLrn,
deployerId,
deployerApiUrl,
baseDomain
};
// TODO: Update deployers table in a separate job
const deployer = await this.db.addDeployer(deployerData);
deployers.push(deployer);
}
}
return deployers;
}
}
@@ -38,7 +38,7 @@ async function main() {
});
for await (const deployment of deployments) {
const url = `https://${deployment.project.name}-${deployment.id}.${misc.projectDomain}`;
const url = `https://${(deployment.project.name).toLowerCase()}-${deployment.id}.${deployment.deployer.baseDomain}`;
const applicationDeploymentRecord = {
type: 'ApplicationDeploymentRecord',
@@ -73,7 +73,7 @@ async function main() {
// Remove deployment for project subdomain if deployment is for production environment
if (deployment.environment === Environment.Production) {
applicationDeploymentRecord.url = `https://${deployment.project.name}.${deployment.baseDomain}`;
applicationDeploymentRecord.url = `https://${deployment.project.name}.${deployment.deployer.baseDomain}`;
await registry.setRecord(
{