Display deployment build logs (#8)
All checks were successful
Lint / lint (20.x) (push) Successful in 4m53s
All checks were successful
Lint / lint (20.x) (push) Successful in 4m53s
Part of [Service provider auctions for web deployments](https://www.notion.so/Service-provider-auctions-for-web-deployments-104a6b22d47280dbad51d28aa3a91d75) Co-authored-by: Adw8 <adwaitgharpure@gmail.com> Co-authored-by: Neeraj <neeraj.rtly@gmail.com> Co-authored-by: IshaVenikar <ishavenikar7@gmail.com> Reviewed-on: #8
This commit is contained in:
parent
ef26f9b39e
commit
5152952a45
@ -23,6 +23,7 @@ import { EnvironmentVariable } from './entity/EnvironmentVariable';
|
|||||||
import { Domain } from './entity/Domain';
|
import { Domain } from './entity/Domain';
|
||||||
import { getEntities, loadAndSaveData } from './utils';
|
import { getEntities, loadAndSaveData } from './utils';
|
||||||
import { UserOrganization } from './entity/UserOrganization';
|
import { UserOrganization } from './entity/UserOrganization';
|
||||||
|
import { Deployer } from './entity/Deployer';
|
||||||
|
|
||||||
const ORGANIZATION_DATA_PATH = '../test/fixtures/organizations.json';
|
const ORGANIZATION_DATA_PATH = '../test/fixtures/organizations.json';
|
||||||
|
|
||||||
@ -215,7 +216,8 @@ export class Database {
|
|||||||
relations: {
|
relations: {
|
||||||
project: true,
|
project: true,
|
||||||
domain: true,
|
domain: true,
|
||||||
createdBy: true
|
createdBy: true,
|
||||||
|
deployer: true,
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
project: {
|
project: {
|
||||||
@ -488,7 +490,13 @@ export class Database {
|
|||||||
return projectRepository.save(newProject);
|
return projectRepository.save(newProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateProjectById(
|
async saveProject (project: Project): Promise<Project> {
|
||||||
|
const projectRepository = this.dataSource.getRepository(Project);
|
||||||
|
|
||||||
|
return projectRepository.save(project);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateProjectById (
|
||||||
projectId: string,
|
projectId: string,
|
||||||
data: DeepPartial<Project>
|
data: DeepPartial<Project>
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
@ -573,4 +581,19 @@ export class Database {
|
|||||||
|
|
||||||
return domains;
|
return domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
||||||
|
const deployerRepository = this.dataSource.getRepository(Deployer);
|
||||||
|
|
||||||
|
const deployer = await deployerRepository.findOne({ where: { deployerId } });
|
||||||
|
|
||||||
|
return deployer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
20
packages/backend/src/entity/Deployer.ts
Normal file
20
packages/backend/src/entity/Deployer.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { Entity, PrimaryColumn, Column, ManyToMany } from 'typeorm';
|
||||||
|
import { Project } from './Project';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
export class Deployer {
|
||||||
|
@PrimaryColumn('varchar')
|
||||||
|
deployerId!: string;
|
||||||
|
|
||||||
|
@Column('varchar')
|
||||||
|
deployerLrn!: string;
|
||||||
|
|
||||||
|
@Column('varchar')
|
||||||
|
deployerApiUrl!: string;
|
||||||
|
|
||||||
|
@Column('varchar')
|
||||||
|
baseDomain!: string;
|
||||||
|
|
||||||
|
@ManyToMany(() => Project, (project) => project.deployers)
|
||||||
|
projects!: Project[];
|
||||||
|
}
|
@ -13,6 +13,7 @@ import {
|
|||||||
import { Project } from './Project';
|
import { Project } from './Project';
|
||||||
import { Domain } from './Domain';
|
import { Domain } from './Domain';
|
||||||
import { User } from './User';
|
import { User } from './User';
|
||||||
|
import { Deployer } from './Deployer';
|
||||||
import { AppDeploymentRecordAttributes, AppDeploymentRemovalRecordAttributes } from '../types';
|
import { AppDeploymentRecordAttributes, AppDeploymentRemovalRecordAttributes } from '../types';
|
||||||
|
|
||||||
export enum Environment {
|
export enum Environment {
|
||||||
@ -127,8 +128,9 @@ export class Deployment {
|
|||||||
@Column('simple-json', { nullable: true })
|
@Column('simple-json', { nullable: true })
|
||||||
applicationDeploymentRemovalRecordData!: AppDeploymentRemovalRecordAttributes | null;
|
applicationDeploymentRemovalRecordData!: AppDeploymentRemovalRecordAttributes | null;
|
||||||
|
|
||||||
@Column('varchar')
|
@ManyToOne(() => Deployer)
|
||||||
deployerLrn!: string;
|
@JoinColumn({ name: 'deployerId' })
|
||||||
|
deployer!: Deployer;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
enum: Environment
|
enum: Environment
|
||||||
@ -138,9 +140,6 @@ export class Deployment {
|
|||||||
@Column('boolean', { default: false })
|
@Column('boolean', { default: false })
|
||||||
isCurrent!: boolean;
|
isCurrent!: boolean;
|
||||||
|
|
||||||
@Column('varchar', { nullable: true })
|
|
||||||
baseDomain!: string | null;
|
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
enum: DeploymentStatus
|
enum: DeploymentStatus
|
||||||
})
|
})
|
||||||
|
@ -7,13 +7,16 @@ import {
|
|||||||
ManyToOne,
|
ManyToOne,
|
||||||
JoinColumn,
|
JoinColumn,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
DeleteDateColumn
|
DeleteDateColumn,
|
||||||
|
JoinTable,
|
||||||
|
ManyToMany
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
|
|
||||||
import { User } from './User';
|
import { User } from './User';
|
||||||
import { Organization } from './Organization';
|
import { Organization } from './Organization';
|
||||||
import { ProjectMember } from './ProjectMember';
|
import { ProjectMember } from './ProjectMember';
|
||||||
import { Deployment } from './Deployment';
|
import { Deployment } from './Deployment';
|
||||||
|
import { Deployer } from './Deployer';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class Project {
|
export class Project {
|
||||||
@ -49,8 +52,9 @@ export class Project {
|
|||||||
@Column('varchar', { nullable: true })
|
@Column('varchar', { nullable: true })
|
||||||
auctionId!: string | null;
|
auctionId!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'simple-array', nullable: true })
|
@ManyToMany(() => Deployer, (deployer) => (deployer.projects))
|
||||||
deployerLrns!: string[] | null;
|
@JoinTable()
|
||||||
|
deployers!: Deployer[]
|
||||||
|
|
||||||
@Column('boolean', { default: false, nullable: true })
|
@Column('boolean', { default: false, nullable: true })
|
||||||
fundsReleased!: boolean;
|
fundsReleased!: boolean;
|
||||||
@ -70,9 +74,6 @@ export class Project {
|
|||||||
@Column('varchar')
|
@Column('varchar')
|
||||||
icon!: string;
|
icon!: string;
|
||||||
|
|
||||||
@Column({ type: 'simple-array', nullable: true })
|
|
||||||
baseDomains!: string[] | null;
|
|
||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import {
|
|||||||
ApplicationDeploymentRequest,
|
ApplicationDeploymentRequest,
|
||||||
ApplicationDeploymentRemovalRequest
|
ApplicationDeploymentRemovalRequest
|
||||||
} from './entity/Deployment';
|
} from './entity/Deployment';
|
||||||
import { AppDeploymentRecord, AppDeploymentRemovalRecord, AuctionParams } from './types';
|
import { AppDeploymentRecord, AppDeploymentRemovalRecord, AuctionParams, DeployerRecord } from './types';
|
||||||
import { getConfig, getRepoDetails, sleep } from './utils';
|
import { getConfig, getRepoDetails, sleep } from './utils';
|
||||||
|
|
||||||
const log = debug('snowball:registry');
|
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_REMOVAL_REQUEST_TYPE = 'ApplicationDeploymentRemovalRequest';
|
||||||
const APP_DEPLOYMENT_RECORD_TYPE = 'ApplicationDeploymentRecord';
|
const APP_DEPLOYMENT_RECORD_TYPE = 'ApplicationDeploymentRecord';
|
||||||
const APP_DEPLOYMENT_REMOVAL_RECORD_TYPE = 'ApplicationDeploymentRemovalRecord';
|
const APP_DEPLOYMENT_REMOVAL_RECORD_TYPE = 'ApplicationDeploymentRemovalRecord';
|
||||||
|
const WEBAPP_DEPLOYER_RECORD_TYPE = 'WebappDeployer'
|
||||||
const SLEEP_DURATION = 1000;
|
const SLEEP_DURATION = 1000;
|
||||||
|
|
||||||
// TODO: Move registry code to registry-sdk/watcher-ts
|
// TODO: Move registry code to registry-sdk/watcher-ts
|
||||||
@ -291,32 +292,29 @@ export class Registry {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAuctionWinningDeployers(
|
async getAuctionWinningDeployerRecords(
|
||||||
auctionId: string
|
auctionId: string
|
||||||
): Promise<string[]> {
|
): Promise<DeployerRecord[]> {
|
||||||
const records = await this.registry.getAuctionsByIds([auctionId]);
|
const records = await this.registry.getAuctionsByIds([auctionId]);
|
||||||
const auctionResult = records[0];
|
const auctionResult = records[0];
|
||||||
|
|
||||||
let deployerLrns = [];
|
let deployerRecords = [];
|
||||||
const { winnerAddresses } = auctionResult;
|
const { winnerAddresses } = auctionResult;
|
||||||
|
|
||||||
for (const auctionWinner of winnerAddresses) {
|
for (const auctionWinner of winnerAddresses) {
|
||||||
const deployerRecords = await this.registry.queryRecords(
|
const records = await this.getDeployerRecordsByFilter({
|
||||||
{
|
paymentAddress: auctionWinner,
|
||||||
paymentAddress: auctionWinner,
|
});
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const record of deployerRecords) {
|
for (const record of records) {
|
||||||
if (record.names && record.names.length > 0) {
|
if (record.id) {
|
||||||
deployerLrns.push(record.names[0]);
|
deployerRecords.push(record);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return deployerLrns;
|
return deployerRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
async releaseDeployerFunds(
|
async releaseDeployerFunds(
|
||||||
@ -359,6 +357,19 @@ export class Registry {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch WebappDeployer Records by filter
|
||||||
|
*/
|
||||||
|
async getDeployerRecordsByFilter(filter: { [key: string]: any }): Promise<DeployerRecord[]> {
|
||||||
|
return this.registry.queryRecords(
|
||||||
|
{
|
||||||
|
type: WEBAPP_DEPLOYER_RECORD_TYPE,
|
||||||
|
...filter
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch ApplicationDeploymentRecords by filter
|
* Fetch ApplicationDeploymentRecords by filter
|
||||||
*/
|
*/
|
||||||
@ -439,8 +450,8 @@ export class Registry {
|
|||||||
const auctions = await this.registry.getAuctionsByIds(auctionIds);
|
const auctions = await this.registry.getAuctionsByIds(auctionIds);
|
||||||
|
|
||||||
const completedAuctions = auctions
|
const completedAuctions = auctions
|
||||||
.filter((auction: { id: string, status: string }) => auction.status === 'completed')
|
.filter((auction: { id: string, status: string }) => auction.status === 'completed')
|
||||||
.map((auction: { id: string, status: string }) => auction.id);
|
.map((auction: { id: string, status: string }) => auction.id);
|
||||||
|
|
||||||
return completedAuctions;
|
return completedAuctions;
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,8 @@ type Deployment {
|
|||||||
commitMessage: String!
|
commitMessage: String!
|
||||||
url: String
|
url: String
|
||||||
environment: Environment!
|
environment: Environment!
|
||||||
deployerLrn: String
|
deployer: Deployer
|
||||||
|
applicationDeploymentRequestId: String
|
||||||
isCurrent: Boolean!
|
isCurrent: Boolean!
|
||||||
baseDomain: String
|
baseDomain: String
|
||||||
status: DeploymentStatus!
|
status: DeploymentStatus!
|
||||||
@ -132,6 +133,14 @@ type EnvironmentVariable {
|
|||||||
updatedAt: String!
|
updatedAt: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Deployer {
|
||||||
|
deployerId: String!
|
||||||
|
deployerLrn: String!
|
||||||
|
deployerApiUrl: String!
|
||||||
|
createdAt: String!
|
||||||
|
updatedAt: String!
|
||||||
|
}
|
||||||
|
|
||||||
type AuthResult {
|
type AuthResult {
|
||||||
token: String!
|
token: String!
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import { Project } from './entity/Project';
|
|||||||
import { Permission, ProjectMember } from './entity/ProjectMember';
|
import { Permission, ProjectMember } from './entity/ProjectMember';
|
||||||
import { User } from './entity/User';
|
import { User } from './entity/User';
|
||||||
import { Registry } from './registry';
|
import { Registry } from './registry';
|
||||||
|
import { Deployer } from './entity/Deployer';
|
||||||
import { GitHubConfig, RegistryConfig } from './config';
|
import { GitHubConfig, RegistryConfig } from './config';
|
||||||
import {
|
import {
|
||||||
AddProjectFromTemplateInput,
|
AddProjectFromTemplateInput,
|
||||||
@ -174,6 +175,7 @@ export class Service {
|
|||||||
applicationDeploymentRequestId: record.attributes.request,
|
applicationDeploymentRequestId: record.attributes.request,
|
||||||
})),
|
})),
|
||||||
relations: {
|
relations: {
|
||||||
|
deployer: true,
|
||||||
project: true,
|
project: true,
|
||||||
},
|
},
|
||||||
order: {
|
order: {
|
||||||
@ -193,37 +195,31 @@ export class Service {
|
|||||||
const deploymentUpdatePromises = records.map(async (record) => {
|
const deploymentUpdatePromises = records.map(async (record) => {
|
||||||
const deployment = recordToDeploymentsMap[record.attributes.request];
|
const deployment = recordToDeploymentsMap[record.attributes.request];
|
||||||
|
|
||||||
const parts = record.attributes.url.replace('https://', '').split('.');
|
if (!deployment.project) {
|
||||||
const baseDomain = parts.slice(1).join('.');
|
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;
|
await this.db.updateDeploymentById(deployment.id, deployment);
|
||||||
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);
|
// Release deployer funds on successful deployment
|
||||||
|
if (!deployment.project.fundsReleased) {
|
||||||
|
const fundsReleased = await this.releaseDeployerFundsByProjectId(deployment.projectId);
|
||||||
|
|
||||||
const baseDomains = deployment.project.baseDomains || [];
|
await this.db.updateProjectById(deployment.projectId, {
|
||||||
|
fundsReleased,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!baseDomains.includes(baseDomain)) {
|
log(
|
||||||
baseDomains.push(baseDomain);
|
`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, {
|
|
||||||
baseDomains,
|
|
||||||
fundsReleased,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
log(
|
|
||||||
`Updated deployment ${deployment.id} with URL ${record.attributes.url}`,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await Promise.all(deploymentUpdatePromises);
|
await Promise.all(deploymentUpdatePromises);
|
||||||
@ -235,7 +231,7 @@ export class Service {
|
|||||||
for (const deployment of prodDeployments) {
|
for (const deployment of prodDeployments) {
|
||||||
const projectDeployments = await this.db.getDeploymentsByProjectId(deployment.projectId);
|
const projectDeployments = await this.db.getDeploymentsByProjectId(deployment.projectId);
|
||||||
const oldDeployments = projectDeployments
|
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) {
|
for (const oldDeployment of oldDeployments) {
|
||||||
await this.db.updateDeployment(
|
await this.db.updateDeployment(
|
||||||
{ id: oldDeployment.id },
|
{ id: oldDeployment.id },
|
||||||
@ -308,17 +304,37 @@ export class Service {
|
|||||||
);
|
);
|
||||||
|
|
||||||
for (const project of projectsToBedeployed) {
|
for (const project of projectsToBedeployed) {
|
||||||
const deployerLrns = await this.laconicRegistry.getAuctionWinningDeployers(project.auctionId!);
|
const deployerRecords = await this.laconicRegistry.getAuctionWinningDeployerRecords(project!.auctionId!);
|
||||||
|
|
||||||
if (!deployerLrns) {
|
if (!deployerRecords) {
|
||||||
log(`No winning deployer for auction ${project!.auctionId}`);
|
log(`No winning deployer for auction ${project!.auctionId}`);
|
||||||
} else {
|
} else {
|
||||||
// Update project with deployer LRNs
|
const deployerIds = [];
|
||||||
await this.db.updateProjectById(project.id!, {
|
|
||||||
deployerLrns
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const deployer of deployerLrns) {
|
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);
|
||||||
|
|
||||||
|
// Update project with deployer
|
||||||
|
await this.updateProjectWithDeployer(project.id, deployer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const deployer of deployerIds) {
|
||||||
log(`Creating deployment for deployer LRN ${deployer}`);
|
log(`Creating deployment for deployer LRN ${deployer}`);
|
||||||
await this.createDeploymentFromAuction(project, deployer);
|
await this.createDeploymentFromAuction(project, deployer);
|
||||||
}
|
}
|
||||||
@ -587,7 +603,7 @@ export class Service {
|
|||||||
domain: prodBranchDomains[0],
|
domain: prodBranchDomains[0],
|
||||||
commitHash: oldDeployment.commitHash,
|
commitHash: oldDeployment.commitHash,
|
||||||
commitMessage: oldDeployment.commitMessage,
|
commitMessage: oldDeployment.commitMessage,
|
||||||
deployerLrn: oldDeployment.deployerLrn
|
deployer: oldDeployment.deployer
|
||||||
});
|
});
|
||||||
|
|
||||||
return newDeployment;
|
return newDeployment;
|
||||||
@ -596,7 +612,8 @@ export class Service {
|
|||||||
async createDeployment(
|
async createDeployment(
|
||||||
userId: string,
|
userId: string,
|
||||||
octokit: Octokit,
|
octokit: Octokit,
|
||||||
data: DeepPartial<Deployment>
|
data: DeepPartial<Deployment>,
|
||||||
|
deployerLrn?: string
|
||||||
): Promise<Deployment> {
|
): Promise<Deployment> {
|
||||||
assert(data.project?.repository, 'Project repository not found');
|
assert(data.project?.repository, 'Project repository not found');
|
||||||
log(
|
log(
|
||||||
@ -625,7 +642,14 @@ export class Service {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newDeployment = await this.createDeploymentFromData(userId, data, data.deployerLrn!, 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 { repo, repoUrl } = await getRepoDetails(octokit, data.project.repository, data.commitHash);
|
||||||
const environmentVariablesObj = await this.getEnvVariables(data.project!.id!);
|
const environmentVariablesObj = await this.getEnvVariables(data.project!.id!);
|
||||||
@ -639,7 +663,7 @@ export class Service {
|
|||||||
repository: repoUrl,
|
repository: repoUrl,
|
||||||
environmentVariables: environmentVariablesObj,
|
environmentVariables: environmentVariablesObj,
|
||||||
dns: `${newDeployment.project.name}`,
|
dns: `${newDeployment.project.name}`,
|
||||||
lrn: data.deployerLrn!
|
lrn: deployer!.deployerLrn!
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,7 +672,7 @@ export class Service {
|
|||||||
deployment: newDeployment,
|
deployment: newDeployment,
|
||||||
appName: repo,
|
appName: repo,
|
||||||
repository: repoUrl,
|
repository: repoUrl,
|
||||||
lrn: data.deployerLrn!,
|
lrn: deployer!.deployerLrn!,
|
||||||
environmentVariables: environmentVariablesObj,
|
environmentVariables: environmentVariablesObj,
|
||||||
dns: `${newDeployment.project.name}-${newDeployment.id}`,
|
dns: `${newDeployment.project.name}-${newDeployment.id}`,
|
||||||
});
|
});
|
||||||
@ -663,7 +687,7 @@ export class Service {
|
|||||||
|
|
||||||
async createDeploymentFromAuction(
|
async createDeploymentFromAuction(
|
||||||
project: DeepPartial<Project>,
|
project: DeepPartial<Project>,
|
||||||
deployerLrn: string
|
deployerId: string
|
||||||
): Promise<Deployment> {
|
): Promise<Deployment> {
|
||||||
const octokit = await this.getOctokit(project.ownerId!);
|
const octokit = await this.getOctokit(project.ownerId!);
|
||||||
const [owner, repo] = project.repository!.split('/');
|
const [owner, repo] = project.repository!.split('/');
|
||||||
@ -689,6 +713,9 @@ export class Service {
|
|||||||
const applicationRecordId = record.id;
|
const applicationRecordId = record.id;
|
||||||
const applicationRecordData = record.attributes;
|
const applicationRecordData = record.attributes;
|
||||||
|
|
||||||
|
const deployer = await this.db.getDeployerById(deployerId);
|
||||||
|
const deployerLrn = deployer!.deployerLrn
|
||||||
|
|
||||||
// Create deployment with prod branch and latest commit
|
// Create deployment with prod branch and latest commit
|
||||||
const deploymentData = {
|
const deploymentData = {
|
||||||
project,
|
project,
|
||||||
@ -699,7 +726,7 @@ export class Service {
|
|||||||
commitMessage: latestCommit.commit.message,
|
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!);
|
const environmentVariablesObj = await this.getEnvVariables(project!.id!);
|
||||||
// To set project DNS
|
// To set project DNS
|
||||||
@ -740,7 +767,7 @@ export class Service {
|
|||||||
async createDeploymentFromData(
|
async createDeploymentFromData(
|
||||||
userId: string,
|
userId: string,
|
||||||
data: DeepPartial<Deployment>,
|
data: DeepPartial<Deployment>,
|
||||||
deployerLrn: string,
|
deployerId: string,
|
||||||
applicationRecordId: string,
|
applicationRecordId: string,
|
||||||
applicationRecordData: ApplicationRecord,
|
applicationRecordData: ApplicationRecord,
|
||||||
): Promise<Deployment> {
|
): Promise<Deployment> {
|
||||||
@ -757,7 +784,9 @@ export class Service {
|
|||||||
createdBy: Object.assign(new User(), {
|
createdBy: Object.assign(new User(), {
|
||||||
id: userId,
|
id: userId,
|
||||||
}),
|
}),
|
||||||
deployerLrn,
|
deployer: Object.assign(new Deployer(), {
|
||||||
|
deployerId,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
log(`Created deployment ${newDeployment.id}`);
|
log(`Created deployment ${newDeployment.id}`);
|
||||||
@ -765,6 +794,50 @@ export class Service {
|
|||||||
return newDeployment;
|
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
|
||||||
|
): Promise<Deployer> {
|
||||||
|
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(
|
async addProjectFromTemplate(
|
||||||
user: User,
|
user: User,
|
||||||
organizationSlug: string,
|
organizationSlug: string,
|
||||||
@ -828,6 +901,7 @@ export class Service {
|
|||||||
slug: organizationSlug,
|
slug: organizationSlug,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!organization) {
|
if (!organization) {
|
||||||
throw new Error('Organization does not exist');
|
throw new Error('Organization does not exist');
|
||||||
}
|
}
|
||||||
@ -858,15 +932,15 @@ export class Service {
|
|||||||
domain: null,
|
domain: null,
|
||||||
commitHash: latestCommit.sha,
|
commitHash: latestCommit.sha,
|
||||||
commitMessage: latestCommit.commit.message,
|
commitMessage: latestCommit.commit.message,
|
||||||
deployerLrn: lrn
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auctionParams) {
|
if (auctionParams) {
|
||||||
const { applicationDeploymentAuctionId } = await this.laconicRegistry.createApplicationDeploymentAuction(repo, octokit, auctionParams!, deploymentData);
|
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 {
|
} else {
|
||||||
await this.createDeployment(user.id, octokit, deploymentData);
|
const newDeployment = await this.createDeployment(user.id, octokit, deploymentData, lrn);
|
||||||
await this.updateProject(project.id, { deployerLrns: [lrn!] })
|
// Update project with deployer
|
||||||
|
await this.updateProjectWithDeployer(newDeployment.projectId, newDeployment.deployer);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.createRepoHook(octokit, project);
|
await this.createRepoHook(octokit, project);
|
||||||
@ -920,6 +994,9 @@ export class Service {
|
|||||||
);
|
);
|
||||||
const projects = await this.db.getProjects({
|
const projects = await this.db.getProjects({
|
||||||
where: { repository: repository.full_name },
|
where: { repository: repository.full_name },
|
||||||
|
relations: {
|
||||||
|
deployers: true,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!projects.length) {
|
if (!projects.length) {
|
||||||
@ -936,7 +1013,7 @@ export class Service {
|
|||||||
branch,
|
branch,
|
||||||
});
|
});
|
||||||
|
|
||||||
const deployers = project.deployerLrns;
|
const deployers = project.deployers;
|
||||||
if (!deployers) {
|
if (!deployers) {
|
||||||
log(`No deployer present for project ${project.id}`)
|
log(`No deployer present for project ${project.id}`)
|
||||||
return;
|
return;
|
||||||
@ -955,7 +1032,7 @@ export class Service {
|
|||||||
domain,
|
domain,
|
||||||
commitHash: headCommit.id,
|
commitHash: headCommit.id,
|
||||||
commitMessage: headCommit.message,
|
commitMessage: headCommit.message,
|
||||||
deployerLrn: deployer
|
deployer: deployer
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -995,6 +1072,7 @@ export class Service {
|
|||||||
relations: {
|
relations: {
|
||||||
project: true,
|
project: true,
|
||||||
domain: true,
|
domain: true,
|
||||||
|
deployer: true,
|
||||||
createdBy: true,
|
createdBy: true,
|
||||||
},
|
},
|
||||||
where: {
|
where: {
|
||||||
@ -1011,8 +1089,7 @@ export class Service {
|
|||||||
let newDeployment: Deployment;
|
let newDeployment: Deployment;
|
||||||
|
|
||||||
if (oldDeployment.project.auctionId) {
|
if (oldDeployment.project.auctionId) {
|
||||||
// TODO: Discuss creating applicationRecord for redeployments
|
newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployer.deployerId);
|
||||||
newDeployment = await this.createDeploymentFromAuction(oldDeployment.project, oldDeployment.deployerLrn);
|
|
||||||
} else {
|
} else {
|
||||||
newDeployment = await this.createDeployment(user.id, octokit,
|
newDeployment = await this.createDeployment(user.id, octokit,
|
||||||
{
|
{
|
||||||
@ -1023,7 +1100,7 @@ export class Service {
|
|||||||
domain: oldDeployment.domain,
|
domain: oldDeployment.domain,
|
||||||
commitHash: oldDeployment.commitHash,
|
commitHash: oldDeployment.commitHash,
|
||||||
commitMessage: oldDeployment.commitMessage,
|
commitMessage: oldDeployment.commitMessage,
|
||||||
deployerLrn: oldDeployment.deployerLrn
|
deployer: oldDeployment.deployer
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1072,13 +1149,14 @@ export class Service {
|
|||||||
},
|
},
|
||||||
relations: {
|
relations: {
|
||||||
project: true,
|
project: true,
|
||||||
|
deployer: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (deployment && deployment.applicationDeploymentRecordId) {
|
if (deployment && deployment.applicationDeploymentRecordId) {
|
||||||
// If deployment is current, remove deployment for project subdomain as well
|
// If deployment is current, remove deployment for project subdomain as well
|
||||||
if (deployment.isCurrent) {
|
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
|
// TODO: Store the latest DNS deployment record
|
||||||
const deploymentRecords =
|
const deploymentRecords =
|
||||||
@ -1101,14 +1179,14 @@ export class Service {
|
|||||||
|
|
||||||
await this.laconicRegistry.createApplicationDeploymentRemovalRequest({
|
await this.laconicRegistry.createApplicationDeploymentRemovalRequest({
|
||||||
deploymentId: latestRecord.id,
|
deploymentId: latestRecord.id,
|
||||||
deployerLrn: deployment.deployerLrn
|
deployerLrn: deployment.deployer.deployerLrn
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const result =
|
const result =
|
||||||
await this.laconicRegistry.createApplicationDeploymentRemovalRequest({
|
await this.laconicRegistry.createApplicationDeploymentRemovalRequest({
|
||||||
deploymentId: deployment.applicationDeploymentRecordId,
|
deploymentId: deployment.applicationDeploymentRecordId,
|
||||||
deployerLrn: deployment.deployerLrn
|
deployerLrn: deployment.deployer.deployerLrn
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.db.updateDeploymentById(deployment.id, {
|
await this.db.updateDeploymentById(deployment.id, {
|
||||||
|
@ -82,3 +82,20 @@ export interface EnvironmentVariables {
|
|||||||
key: string,
|
key: string,
|
||||||
value: 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -139,30 +139,8 @@ const Configure = () => {
|
|||||||
|
|
||||||
const projectId = await createProject(createFormData, environmentVariables);
|
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) {
|
if (templateId) {
|
||||||
createFormData.option === 'Auction'
|
createFormData.option === 'Auction'
|
||||||
? navigate(
|
? navigate(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Deployment,
|
Deployment,
|
||||||
DeploymentStatus,
|
DeploymentStatus,
|
||||||
@ -6,6 +6,14 @@ import {
|
|||||||
Environment,
|
Environment,
|
||||||
Project,
|
Project,
|
||||||
} from 'gql-client';
|
} from 'gql-client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
} from '@mui/material';
|
||||||
|
|
||||||
import { Avatar } from 'components/shared/Avatar';
|
import { Avatar } from 'components/shared/Avatar';
|
||||||
import {
|
import {
|
||||||
BranchStrokeIcon,
|
BranchStrokeIcon,
|
||||||
@ -18,12 +26,23 @@ import {
|
|||||||
import { Heading } from 'components/shared/Heading';
|
import { Heading } from 'components/shared/Heading';
|
||||||
import { OverflownText } from 'components/shared/OverflownText';
|
import { OverflownText } from 'components/shared/OverflownText';
|
||||||
import { Tag, TagTheme } from 'components/shared/Tag';
|
import { Tag, TagTheme } from 'components/shared/Tag';
|
||||||
|
import { Button } from 'components/shared/Button';
|
||||||
import { getInitials } from 'utils/geInitials';
|
import { getInitials } from 'utils/geInitials';
|
||||||
import { relativeTimeMs } from 'utils/time';
|
import { relativeTimeMs } from 'utils/time';
|
||||||
import { SHORT_COMMIT_HASH_LENGTH } from '../../../../constants';
|
import { SHORT_COMMIT_HASH_LENGTH } from '../../../../constants';
|
||||||
import { formatAddress } from '../../../../utils/format';
|
import { formatAddress } from '../../../../utils/format';
|
||||||
import { DeploymentMenu } from './DeploymentMenu';
|
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 {
|
interface DeployDetailsCardProps {
|
||||||
deployment: Deployment;
|
deployment: Deployment;
|
||||||
currentDeployment: Deployment;
|
currentDeployment: Deployment;
|
||||||
@ -48,6 +67,12 @@ const DeploymentDetailsCard = ({
|
|||||||
project,
|
project,
|
||||||
prodBranchDomains,
|
prodBranchDomains,
|
||||||
}: DeployDetailsCardProps) => {
|
}: DeployDetailsCardProps) => {
|
||||||
|
const [openDialog, setOpenDialog] = useState<boolean>(false);
|
||||||
|
const [deploymentLogs, setDeploymentLogs] = useState<string>();
|
||||||
|
|
||||||
|
const handleOpenDialog = () => setOpenDialog(true);
|
||||||
|
const handleCloseDialog = () => setOpenDialog(false);
|
||||||
|
|
||||||
const getIconByDeploymentStatus = (status: DeploymentStatus) => {
|
const getIconByDeploymentStatus = (status: DeploymentStatus) => {
|
||||||
if (
|
if (
|
||||||
status === DeploymentStatus.Building ||
|
status === DeploymentStatus.Building ||
|
||||||
@ -64,6 +89,14 @@ const DeploymentDetailsCard = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchDeploymentLogs = useCallback(async () => {
|
||||||
|
let url = `${deployment.deployer.deployerApiUrl}/log/${deployment.applicationDeploymentRequestId}`;
|
||||||
|
const res = await fetch(url, { cache: 'no-store' });
|
||||||
|
const logs = await res.text();
|
||||||
|
setDeploymentLogs(logs);
|
||||||
|
handleOpenDialog();
|
||||||
|
}, [deployment.deployer.deployerApiUrl, deployment.applicationDeploymentRequestId, handleOpenDialog]);
|
||||||
|
|
||||||
const renderDeploymentStatus = useCallback(
|
const renderDeploymentStatus = useCallback(
|
||||||
(className?: string) => {
|
(className?: string) => {
|
||||||
return (
|
return (
|
||||||
@ -72,6 +105,7 @@ const DeploymentDetailsCard = ({
|
|||||||
leftIcon={getIconByDeploymentStatus(deployment.status)}
|
leftIcon={getIconByDeploymentStatus(deployment.status)}
|
||||||
size="xs"
|
size="xs"
|
||||||
type={STATUS_COLORS[deployment.status] ?? 'neutral'}
|
type={STATUS_COLORS[deployment.status] ?? 'neutral'}
|
||||||
|
onClick={fetchDeploymentLogs}
|
||||||
>
|
>
|
||||||
{deployment.status}
|
{deployment.status}
|
||||||
</Tag>
|
</Tag>
|
||||||
@ -96,9 +130,9 @@ const DeploymentDetailsCard = ({
|
|||||||
</OverflownText>
|
</OverflownText>
|
||||||
</Heading>
|
</Heading>
|
||||||
)}
|
)}
|
||||||
{deployment.deployerLrn && (
|
{deployment.deployer.deployerLrn && (
|
||||||
<span className="text-sm text-elements-low-em tracking-tight block mt-2">
|
<span className="text-sm text-elements-low-em tracking-tight block mt-2">
|
||||||
Deployer LRN: {deployment.deployerLrn}
|
Deployer LRN: {deployment.deployer.deployerLrn}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<span className="text-sm text-elements-low-em tracking-tight block">
|
<span className="text-sm text-elements-low-em tracking-tight block">
|
||||||
@ -167,6 +201,15 @@ const DeploymentDetailsCard = ({
|
|||||||
prodBranchDomains={prodBranchDomains}
|
prodBranchDomains={prodBranchDomains}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<Dialog open={openDialog} onClose={handleCloseDialog} fullWidth maxWidth="md">
|
||||||
|
<DialogTitle>Deployment logs</DialogTitle>
|
||||||
|
<DialogContent style={DEPLOYMENT_LOGS_STYLE} >
|
||||||
|
{deploymentLogs && <pre >{deploymentLogs}</pre>}
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={handleCloseDialog}>Close</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -36,7 +36,11 @@ const deployment: Deployment = {
|
|||||||
url: 'https://deploy1.example.com',
|
url: 'https://deploy1.example.com',
|
||||||
environment: Environment.Production,
|
environment: Environment.Production,
|
||||||
isCurrent: true,
|
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,
|
status: DeploymentStatus.Ready,
|
||||||
createdBy: {
|
createdBy: {
|
||||||
id: 'user1',
|
id: 'user1',
|
||||||
@ -49,6 +53,7 @@ const deployment: Deployment = {
|
|||||||
},
|
},
|
||||||
createdAt: '1677676800', // 2023-03-01T12:00:00Z
|
createdAt: '1677676800', // 2023-03-01T12:00:00Z
|
||||||
updatedAt: '1677680400', // 2023-03-01T13:00:00Z
|
updatedAt: '1677680400', // 2023-03-01T13:00:00Z
|
||||||
|
applicationDeploymentRequestId: 'bafyreiaycvq6imoppnpwdve4smj6t6ql5svt5zl3x6rimu4qwyzgjorize',
|
||||||
};
|
};
|
||||||
|
|
||||||
const domains: Domain[] = [
|
const domains: Domain[] = [
|
||||||
|
@ -102,7 +102,12 @@ export const deployment0: Deployment = {
|
|||||||
domain: domain0,
|
domain: domain0,
|
||||||
commitMessage: 'Commit Message',
|
commitMessage: 'Commit Message',
|
||||||
createdBy: user,
|
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 = {
|
export const project: Project = {
|
||||||
|
@ -136,7 +136,11 @@ query ($projectId: String!) {
|
|||||||
commitHash
|
commitHash
|
||||||
commitMessage
|
commitMessage
|
||||||
url
|
url
|
||||||
deployerLrn
|
deployer {
|
||||||
|
deployerId
|
||||||
|
deployerLrn,
|
||||||
|
deployerApiUrl,
|
||||||
|
}
|
||||||
environment
|
environment
|
||||||
isCurrent
|
isCurrent
|
||||||
baseDomain
|
baseDomain
|
||||||
@ -148,6 +152,7 @@ query ($projectId: String!) {
|
|||||||
name
|
name
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
|
applicationDeploymentRequestId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -105,7 +105,7 @@ export type Deployment = {
|
|||||||
commitHash: string;
|
commitHash: string;
|
||||||
commitMessage: string;
|
commitMessage: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
deployerLrn: string;
|
deployer: Deployer;
|
||||||
environment: Environment;
|
environment: Environment;
|
||||||
isCurrent: boolean;
|
isCurrent: boolean;
|
||||||
baseDomain?: string;
|
baseDomain?: string;
|
||||||
@ -113,8 +113,15 @@ export type Deployment = {
|
|||||||
createdBy: User;
|
createdBy: User;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
|
applicationDeploymentRequestId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type Deployer = {
|
||||||
|
deployerApiUrl: string;
|
||||||
|
deployerId: string;
|
||||||
|
deployerLrn: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type OrganizationMember = {
|
export type OrganizationMember = {
|
||||||
id: string;
|
id: string;
|
||||||
member: User;
|
member: User;
|
||||||
|
Loading…
Reference in New Issue
Block a user