forked from cerc-io/snowballtools-base
Create new deployment on changing preview deployment to production (#61)
* Create new deployment when changing to production * Remove unnecessary todos * Move deployment id and url creation in database method * Display correct details in deployment dialog box * Rename relativeTime function to relativeTimeISO * Refactor resolver methods to service class * Refactor to move github app to service class --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
@@ -2,6 +2,8 @@ import { DataSource, DeepPartial, FindManyOptions, FindOneOptions, FindOptionsWh
|
||||
import path from 'path';
|
||||
import debug from 'debug';
|
||||
import assert from 'assert';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import { lowercase, numbers } from 'nanoid-dictionary';
|
||||
|
||||
import { DatabaseConfig } from './config';
|
||||
import { User } from './entity/User';
|
||||
@@ -15,6 +17,8 @@ import { PROJECT_DOMAIN } from './constants';
|
||||
|
||||
const log = debug('snowball:database');
|
||||
|
||||
const nanoid = customAlphabet(lowercase + numbers, 8);
|
||||
|
||||
// TODO: Fix order of methods
|
||||
export class Database {
|
||||
private dataSource: DataSource;
|
||||
@@ -171,7 +175,16 @@ export class Database {
|
||||
|
||||
async addDeployement (data: DeepPartial<Deployment>): Promise<Deployment> {
|
||||
const deploymentRepository = this.dataSource.getRepository(Deployment);
|
||||
const deployment = await deploymentRepository.save(data);
|
||||
|
||||
const id = nanoid();
|
||||
const url = `${data.project!.name}-${id}.${PROJECT_DOMAIN}`;
|
||||
|
||||
const updatedData = {
|
||||
...data,
|
||||
id,
|
||||
url
|
||||
};
|
||||
const deployment = await deploymentRepository.save(updatedData);
|
||||
|
||||
return deployment;
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@ export const main = async (): Promise<void> => {
|
||||
// TODO: get config path using cli
|
||||
const { server, database, githubOauth } = await getConfig<Config>(DEFAULT_CONFIG_FILE_PATH);
|
||||
|
||||
const db = new Database(database);
|
||||
await db.init();
|
||||
const service = new Service(db);
|
||||
|
||||
// TODO: Move to Service class
|
||||
const app = new OAuthApp({
|
||||
clientType: 'oauth-app',
|
||||
@@ -30,8 +26,12 @@ export const main = async (): Promise<void> => {
|
||||
clientSecret: githubOauth.clientSecret
|
||||
});
|
||||
|
||||
const db = new Database(database);
|
||||
await db.init();
|
||||
const service = new Service(db, app);
|
||||
|
||||
const typeDefs = fs.readFileSync(path.join(__dirname, 'schema.gql')).toString();
|
||||
const resolvers = await createResolvers(db, app, service);
|
||||
const resolvers = await createResolvers(service);
|
||||
|
||||
await createAndStartServer(typeDefs, resolvers, server);
|
||||
};
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import debug from 'debug';
|
||||
import { DeepPartial, FindOptionsWhere } from 'typeorm';
|
||||
|
||||
import { OAuthApp } from '@octokit/oauth-app';
|
||||
|
||||
import { Service } from './service';
|
||||
import { Database } from './database';
|
||||
import { Permission } from './entity/ProjectMember';
|
||||
import { Domain } from './entity/Domain';
|
||||
import { Project } from './entity/Project';
|
||||
@@ -13,7 +10,7 @@ import { EnvironmentVariable } from './entity/EnvironmentVariable';
|
||||
const log = debug('snowball:database');
|
||||
|
||||
// TODO: Remove Database argument and refactor code to Service
|
||||
export const createResolvers = async (db: Database, app: OAuthApp, service: Service): Promise<any> => {
|
||||
export const createResolvers = async (service: Service): Promise<any> => {
|
||||
return {
|
||||
Query: {
|
||||
// TODO: add custom type for context
|
||||
@@ -121,9 +118,9 @@ export const createResolvers = async (db: Database, app: OAuthApp, service: Serv
|
||||
}
|
||||
},
|
||||
|
||||
updateDeploymentToProd: async (_: any, { deploymentId }: { deploymentId: string }) => {
|
||||
updateDeploymentToProd: async (_: any, { deploymentId }: { deploymentId: string }, context: any) => {
|
||||
try {
|
||||
return await service.updateDeploymentToProd(deploymentId);
|
||||
return Boolean(await service.updateDeploymentToProd(context.userId, deploymentId));
|
||||
} catch (err) {
|
||||
log(err);
|
||||
return false;
|
||||
@@ -201,19 +198,17 @@ export const createResolvers = async (db: Database, app: OAuthApp, service: Serv
|
||||
},
|
||||
|
||||
authenticateGitHub: async (_: any, { code }: { code: string }, context: any) => {
|
||||
// TOO: Move to Service class
|
||||
const { authentication: { token } } = await app.createToken({
|
||||
code
|
||||
});
|
||||
|
||||
await db.updateUser(context.userId, { gitHubToken: token });
|
||||
|
||||
return { token };
|
||||
try {
|
||||
return await service.authenticateGitHub(code, context.userId);
|
||||
} catch (err) {
|
||||
log(err);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
unauthenticateGitHub: async (_: any, __: object, context: any) => {
|
||||
try {
|
||||
return db.updateUser(context.userId, { gitHubToken: null });
|
||||
return service.unauthenticateGitHub(context.userId, { gitHubToken: null });
|
||||
} catch (err) {
|
||||
log(err);
|
||||
return false;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import assert from 'assert';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import { lowercase, numbers } from 'nanoid-dictionary';
|
||||
import { DeepPartial, FindOptionsWhere } from 'typeorm';
|
||||
|
||||
import { OAuthApp } from '@octokit/oauth-app';
|
||||
|
||||
import { Database } from './database';
|
||||
import { Deployment, Environment } from './entity/Deployment';
|
||||
import { Domain } from './entity/Domain';
|
||||
@@ -11,15 +11,13 @@ import { Organization } from './entity/Organization';
|
||||
import { Project } from './entity/Project';
|
||||
import { Permission, ProjectMember } from './entity/ProjectMember';
|
||||
import { User } from './entity/User';
|
||||
import { PROJECT_DOMAIN } from './constants';
|
||||
|
||||
const nanoid = customAlphabet(lowercase + numbers, 8);
|
||||
|
||||
export class Service {
|
||||
private db: Database;
|
||||
private app: OAuthApp;
|
||||
|
||||
constructor (db: Database) {
|
||||
constructor (db: Database, app: OAuthApp) {
|
||||
this.db = db;
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
async getUser (userId: string): Promise<User | null> {
|
||||
@@ -149,7 +147,7 @@ export class Service {
|
||||
return this.db.deleteEnvironmentVariable(environmentVariableId);
|
||||
}
|
||||
|
||||
async updateDeploymentToProd (deploymentId: string): Promise<boolean> {
|
||||
async updateDeploymentToProd (userId: string, deploymentId: string): Promise<Deployment> {
|
||||
const deployment = await this.db.getDeployment({ where: { id: deploymentId }, relations: { project: true } });
|
||||
|
||||
if (!deployment) {
|
||||
@@ -173,13 +171,18 @@ export class Service {
|
||||
});
|
||||
}
|
||||
|
||||
const updateResult = await this.db.updateDeploymentById(deploymentId, {
|
||||
environment: Environment.Production,
|
||||
domain: prodBranchDomains[0],
|
||||
isCurrent: true
|
||||
const { createdAt, updatedAt, ...updatedDeployment } = deployment;
|
||||
|
||||
updatedDeployment.isCurrent = true;
|
||||
updatedDeployment.environment = Environment.Production;
|
||||
updatedDeployment.domain = prodBranchDomains[0];
|
||||
updatedDeployment.createdBy = Object.assign(new User(), {
|
||||
id: userId
|
||||
});
|
||||
|
||||
return updateResult;
|
||||
const newDeployement = await this.db.addDeployement(updatedDeployment);
|
||||
|
||||
return newDeployement;
|
||||
}
|
||||
|
||||
async addProject (userId: string, organizationSlug: string, data: DeepPartial<Project>): Promise<Project | undefined> {
|
||||
@@ -243,9 +246,6 @@ export class Service {
|
||||
});
|
||||
}
|
||||
|
||||
updatedDeployment.id = nanoid();
|
||||
updatedDeployment.url = `${updatedDeployment.project.name}-${updatedDeployment.id}.${PROJECT_DOMAIN}`;
|
||||
|
||||
const oldDeployment = await this.db.updateDeploymentById(deploymentId, { domain: null, isCurrent: false });
|
||||
const newDeployement = await this.db.addDeployement(updatedDeployment);
|
||||
|
||||
@@ -360,4 +360,18 @@ export class Service {
|
||||
|
||||
return updateResult;
|
||||
}
|
||||
|
||||
async authenticateGitHub (code:string, userId: string): Promise<{token: string}> {
|
||||
const { authentication: { token } } = await this.app.createToken({
|
||||
code
|
||||
});
|
||||
|
||||
await this.db.updateUser(userId, { gitHubToken: token });
|
||||
|
||||
return { token };
|
||||
}
|
||||
|
||||
async unauthenticateGitHub (userId: string, data: DeepPartial<User>): Promise<boolean> {
|
||||
return this.db.updateUser(userId, data);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,11 +2,11 @@
|
||||
{
|
||||
"id": "2379cf1f-a232-4ad2-ae14-4d881131cc26",
|
||||
"name": "Snowball Tools",
|
||||
"slug": "snowball-tools"
|
||||
"slug": "snowball-tools-1"
|
||||
},
|
||||
{
|
||||
"id": "7eb9b3eb-eb74-4b53-b59a-69884c82a7fb",
|
||||
"name": "AirFoil",
|
||||
"slug": "airfoil"
|
||||
"slug": "airfoil-2"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user