feat(providers): add gitlab bitbucket and github providers

This commit is contained in:
Mauricio Siu
2024-08-31 22:57:41 -06:00
parent 28d8fa9834
commit 6d945371c9
58 changed files with 46852 additions and 311 deletions

View File

@@ -85,6 +85,7 @@ export const apiTraefikConfig = z.object({
export const apiGetBranches = z.object({
repo: z.string().min(1),
owner: z.string().min(1),
githubProviderId: z.string().optional(),
});
export const apiModifyTraefikConfig = z.object({
path: z.string().min(1),

View File

@@ -22,11 +22,18 @@ import { security } from "./security";
import { applicationStatus } from "./shared";
import { sshKeys } from "./ssh-key";
import { generateAppName } from "./utils";
import {
bitbucketProvider,
githubProvider,
gitlabProvider,
} from "./git-provider";
export const sourceType = pgEnum("sourceType", [
"docker",
"git",
"github",
"gitlab",
"bitbucket",
"drop",
]);
@@ -126,6 +133,16 @@ export const applications = pgTable("application", {
branch: text("branch"),
buildPath: text("buildPath").default("/"),
autoDeploy: boolean("autoDeploy").$defaultFn(() => true),
// Gitlab
gitlabRepository: text("gitlabRepository"),
gitlabOwner: text("gitlabOwner"),
gitlabBranch: text("gitlabBranch"),
gitlabBuildPath: text("gitlabBuildPath").default("/"),
// Bitbucket
bitbucketRepository: text("bitbucketRepository"),
bitbucketOwner: text("bitbucketOwner"),
bitbucketBranch: text("bitbucketBranch"),
bitbucketBuildPath: text("bitbucketBuildPath").default("/"),
// Docker
username: text("username"),
password: text("password"),
@@ -169,6 +186,24 @@ export const applications = pgTable("application", {
projectId: text("projectId")
.notNull()
.references(() => projects.projectId, { onDelete: "cascade" }),
githubProviderId: text("githubProviderId").references(
() => githubProvider.githubProviderId,
{
onDelete: "set null",
},
),
gitlabProviderId: text("gitlabProviderId").references(
() => gitlabProvider.gitlabProviderId,
{
onDelete: "set null",
},
),
bitbucketProviderId: text("bitbucketProviderId").references(
() => bitbucketProvider.bitbucketProviderId,
{
onDelete: "set null",
},
),
});
export const applicationsRelations = relations(
@@ -192,6 +227,18 @@ export const applicationsRelations = relations(
fields: [applications.registryId],
references: [registry.registryId],
}),
githubProvider: one(githubProvider, {
fields: [applications.githubProviderId],
references: [githubProvider.githubProviderId],
}),
gitlabProvider: one(gitlabProvider, {
fields: [applications.gitlabProviderId],
references: [gitlabProvider.gitlabProviderId],
}),
bitbucketProvider: one(bitbucketProvider, {
fields: [applications.bitbucketProviderId],
references: [bitbucketProvider.bitbucketProviderId],
}),
}),
);
@@ -369,6 +416,29 @@ export const apiSaveGithubProvider = createSchema
branch: true,
owner: true,
buildPath: true,
githubProviderId: true,
})
.required();
export const apiSaveGitlabProvider = createSchema
.pick({
applicationId: true,
gitlabBranch: true,
gitlabBuildPath: true,
gitlabOwner: true,
gitlabRepository: true,
gitlabProviderId: true,
})
.required();
export const apiSaveBitbucketProvider = createSchema
.pick({
bitbucketBranch: true,
bitbucketBuildPath: true,
bitbucketOwner: true,
bitbucketRepository: true,
bitbucketProviderId: true,
applicationId: true,
})
.required();

View File

@@ -0,0 +1,150 @@
import { relations } from "drizzle-orm";
import { pgTable, text, pgEnum, integer } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { nanoid } from "nanoid";
import { z } from "zod";
import { auth } from "./auth";
export const gitProviderType = pgEnum("gitProviderType", [
"github",
"gitlab",
"bitbucket",
]);
export const gitProvider = pgTable("git_provider", {
gitProviderId: text("gitProviderId")
.notNull()
.primaryKey()
.$defaultFn(() => nanoid()),
name: text("name").notNull(),
providerType: gitProviderType("providerType").notNull().default("github"),
createdAt: text("createdAt")
.notNull()
.$defaultFn(() => new Date().toISOString()),
authId: text("authId")
.notNull()
.references(() => auth.id, { onDelete: "cascade" }),
});
export const gitProviderRelations = relations(gitProvider, ({ one, many }) => ({
githubProvider: one(githubProvider, {
fields: [gitProvider.gitProviderId],
references: [githubProvider.gitProviderId],
}),
gitlabProvider: one(gitlabProvider, {
fields: [gitProvider.gitProviderId],
references: [gitlabProvider.gitProviderId],
}),
bitbucketProvider: one(bitbucketProvider, {
fields: [gitProvider.gitProviderId],
references: [bitbucketProvider.gitProviderId],
}),
auth: one(auth, {
fields: [gitProvider.authId],
references: [auth.id],
}),
}));
export const githubProvider = pgTable("github_provider", {
githubProviderId: text("githubProviderId")
.notNull()
.primaryKey()
.$defaultFn(() => nanoid()),
githubAppName: text("githubAppName"),
githubAppId: integer("githubAppId"),
githubClientId: text("githubClientId"),
githubClientSecret: text("githubClientSecret"),
githubInstallationId: text("githubInstallationId"),
githubPrivateKey: text("githubPrivateKey"),
githubWebhookSecret: text("githubWebhookSecret"),
gitProviderId: text("gitProviderId")
.notNull()
.references(() => gitProvider.gitProviderId, { onDelete: "cascade" }),
});
export const githubProviderRelations = relations(
githubProvider,
({ one, many }) => ({
gitProvider: one(gitProvider, {
fields: [githubProvider.gitProviderId],
references: [gitProvider.gitProviderId],
}),
}),
);
export const gitlabProvider = pgTable("gitlab_provider", {
gitlabProviderId: text("gitlabProviderId")
.notNull()
.primaryKey()
.$defaultFn(() => nanoid()),
applicationId: text("application_id"),
redirectUri: text("redirect_uri"),
secret: text("secret"),
accessToken: text("access_token"),
refreshToken: text("refresh_token"),
groupName: text("group_name"),
gitProviderId: text("gitProviderId")
.notNull()
.references(() => gitProvider.gitProviderId, { onDelete: "cascade" }),
});
export const gitlabProviderRelations = relations(
gitlabProvider,
({ one, many }) => ({
gitProvider: one(gitProvider, {
fields: [gitlabProvider.gitProviderId],
references: [gitProvider.gitProviderId],
}),
}),
);
export const bitbucketProvider = pgTable("bitbucket_provider", {
bitbucketProviderId: text("bitbucketProviderId")
.notNull()
.primaryKey()
.$defaultFn(() => nanoid()),
bitbucketUsername: text("bitbucketUsername"),
appPassword: text("appPassword"),
bitbucketWorkspaceName: text("bitbucketWorkspaceName"),
gitProviderId: text("gitProviderId")
.notNull()
.references(() => gitProvider.gitProviderId, { onDelete: "cascade" }),
});
export const bitbucketProviderRelations = relations(
bitbucketProvider,
({ one, many }) => ({
gitProvider: one(gitProvider, {
fields: [bitbucketProvider.gitProviderId],
references: [gitProvider.gitProviderId],
}),
}),
);
const createSchema = createInsertSchema(gitProvider);
export const apiCreateGithubProvider = createSchema.extend({
githubAppName: z.string().optional(),
githubAppId: z.number().optional(),
githubClientId: z.string().optional(),
githubClientSecret: z.string().optional(),
githubInstallationId: z.string().optional(),
githubPrivateKey: z.string().optional(),
githubWebhookSecret: z.string().nullable(),
gitProviderId: z.string().optional(),
});
export const apiCreateGitlabProvider = createSchema.extend({
applicationId: z.string().optional(),
secret: z.string().optional(),
groupName: z.string().optional(),
gitProviderId: z.string().optional(),
redirectUri: z.string().optional(),
});
export const apiCreateBitbucketProvider = createSchema.extend({
bitbucketUsername: z.string().optional(),
appPassword: z.string().optional(),
bitbucketWorkspaceName: z.string().optional(),
gitProviderId: z.string().optional(),
});

View File

@@ -23,3 +23,4 @@ export * from "./compose";
export * from "./registry";
export * from "./notification";
export * from "./ssh-key";
export * from "./git-provider";