Skip to content

Commit

Permalink
[db/server] Link workspaces and projects
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Keromnes <[email protected]>
  • Loading branch information
AlexTugarev and jankeromnes committed Jul 16, 2021
1 parent a061798 commit 382a2d9
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 10 deletions.
3 changes: 2 additions & 1 deletion components/gitpod-db/src/project-db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { Project } from "@gitpod/gitpod-protocol";

export const ProjectDB = Symbol('ProjectDB');
export interface ProjectDB {
findProjectsByTeam(teamId: string): Promise<Project[]>;
findProjectByCloneUrl(cloneUrl: string): Promise<Project | undefined>;
findProjectByInstallationId(installationId: string): Promise<Project | undefined>;
findProjectsByTeam(teamId: string): Promise<Project[]>;
createProject(name: string, cloneUrl: string, teamId: string, appInstallationId: string): Promise<Project>;
}
6 changes: 6 additions & 0 deletions components/gitpod-db/src/typeorm/entity/db-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ export class DBWorkspace implements Workspace {
@Column("text")
contextURL: string;

@Column({
default: '',
transformer: Transformer.MAP_EMPTY_STR_TO_UNDEFINED
})
projectId?: string;

@Column()
description: string;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License-AGPL.txt in the project root for license information.
*/

import { MigrationInterface, QueryRunner } from "typeorm";
import { columnExists, tableExists } from "./helper/helper";

export class AddProjectIdToWorkspace1626422169862 implements MigrationInterface {

public async up(queryRunner: QueryRunner): Promise<any> {
if (await tableExists(queryRunner, "d_b_workspace")) {
if (!(await columnExists(queryRunner, "d_b_workspace", "projectId"))) {
await queryRunner.query("ALTER TABLE d_b_workspace ADD COLUMN `projectId` char(36)");
}
}
}

public async down(queryRunner: QueryRunner): Promise<any> {
}

}
21 changes: 14 additions & 7 deletions components/gitpod-db/src/typeorm/project-db-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,36 @@ export class ProjectDBImpl implements ProjectDB {
return (await this.getEntityManager()).getRepository<DBProject>(DBProject);
}

async findProjectByCloneUrl(cloneUrl: string): Promise<Project | undefined> {
const repo = await this.getRepo();
return repo.findOne({ cloneUrl: cloneUrl.toLowerCase() });
}

async findProjectByInstallationId(appInstallationId: string): Promise<Project | undefined> {
const repo = await this.getRepo();
return repo.findOne({ appInstallationId });
}

public async findProjectsByTeam(teamId: string): Promise<Project[]> {
const repo = await this.getRepo();
return repo.find({ teamId });
}

public async createProject(name: string, cloneUrl: string, teamId: string, appInstallationId: string): Promise<Project> {
const repo = await this.getRepo();
if (repo.findOne({ cloneUrl: cloneUrl.toLowerCase() })) {
throw new Error('A project with the same clone URL already exists');
}

const project: Project = {
id: uuidv4(),
name,
teamId,
cloneUrl,
cloneUrl: cloneUrl.toLowerCase(),
appInstallationId,
creationTime: new Date().toISOString(),
}
await repo.save(project);
return project;
}

async findProjectByInstallationId(appInstallationId: string): Promise<Project | undefined> {
const repo = await this.getRepo();
const project = await repo.findOne({ appInstallationId });
return project;
}
}
1 change: 1 addition & 0 deletions components/gitpod-protocol/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ export interface Workspace {
contextURL: string;
description: string;
ownerId: string;
projectId?: string;
context: WorkspaceContext;
config: WorkspaceConfig;

Expand Down
1 change: 1 addition & 0 deletions components/server/ee/src/workspace/workspace-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ export class WorkspaceFactoryEE extends WorkspaceFactory {
type: "regular",
creationTime: new Date().toISOString(),
contextURL: normalizedContextURL,
projectId: context.prebuiltWorkspace.projectId,
description: this.getDescription(context),
ownerId: user.id,
context: <WorkspaceContext & WithSnapshot & WithPrebuild>{
Expand Down
9 changes: 7 additions & 2 deletions components/server/src/workspace/workspace-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* See License-AGPL.txt in the project root for license information.
*/

import { DBWithTracing, TracedWorkspaceDB, WorkspaceDB } from '@gitpod/gitpod-db/lib';
import { DBWithTracing, TracedWorkspaceDB, WorkspaceDB, ProjectDB } from '@gitpod/gitpod-db/lib';
import { CommitContext, IssueContext, PullRequestContext, Repository, SnapshotContext, User, Workspace, WorkspaceConfig, WorkspaceContext, WorkspaceProbeContext } from '@gitpod/gitpod-protocol';
import { ErrorCodes } from '@gitpod/gitpod-protocol/lib/messaging/error';
import { generateWorkspaceID } from '@gitpod/gitpod-protocol/lib/util/generate-workspace-id';
Expand All @@ -19,6 +19,7 @@ import { ImageSourceProvider } from './image-source-provider';
export class WorkspaceFactory {

@inject(TracedWorkspaceDB) protected readonly db: DBWithTracing<WorkspaceDB>;
@inject(ProjectDB) protected readonly projectDB: ProjectDB;
@inject(ConfigProvider) protected configProvider: ConfigProvider;
@inject(ImageSourceProvider) protected imageSourceProvider: ImageSourceProvider;

Expand Down Expand Up @@ -135,7 +136,10 @@ export class WorkspaceFactory {
const span = TraceContext.startSpan("createForCommit", ctx);

try {
const config = await this.configProvider.fetchConfig({span}, user, context);
const [ config, project ] = await Promise.all([
this.configProvider.fetchConfig({ span }, user, context),
this.projectDB.findProjectByCloneUrl(context.repository.cloneUrl),
]);
const imageSource = await this.imageSourceProvider.getImageSource(ctx, user, context, config);

const id = await generateWorkspaceID();
Expand All @@ -144,6 +148,7 @@ export class WorkspaceFactory {
type: "regular",
creationTime: new Date().toISOString(),
contextURL: normalizedContextURL,
projectId: project?.id,
description: this.getDescription(context),
ownerId: user.id,
context,
Expand Down

0 comments on commit 382a2d9

Please sign in to comment.