diff --git a/apps/api/prisma/migrations/20220712083523_custom_port_git_sources/migration.sql b/apps/api/prisma/migrations/20220712083523_custom_port_git_sources/migration.sql new file mode 100644 index 000000000..f702291b2 --- /dev/null +++ b/apps/api/prisma/migrations/20220712083523_custom_port_git_sources/migration.sql @@ -0,0 +1,24 @@ +-- RedefineTables +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_GitSource" ( + "id" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL, + "type" TEXT, + "apiUrl" TEXT, + "htmlUrl" TEXT, + "customPort" INTEGER NOT NULL DEFAULT 22, + "organization" TEXT, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + "githubAppId" TEXT, + "gitlabAppId" TEXT, + CONSTRAINT "GitSource_githubAppId_fkey" FOREIGN KEY ("githubAppId") REFERENCES "GithubApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE, + CONSTRAINT "GitSource_gitlabAppId_fkey" FOREIGN KEY ("gitlabAppId") REFERENCES "GitlabApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE +); +INSERT INTO "new_GitSource" ("apiUrl", "createdAt", "githubAppId", "gitlabAppId", "htmlUrl", "id", "name", "organization", "type", "updatedAt") SELECT "apiUrl", "createdAt", "githubAppId", "gitlabAppId", "htmlUrl", "id", "name", "organization", "type", "updatedAt" FROM "GitSource"; +DROP TABLE "GitSource"; +ALTER TABLE "new_GitSource" RENAME TO "GitSource"; +CREATE UNIQUE INDEX "GitSource_githubAppId_key" ON "GitSource"("githubAppId"); +CREATE UNIQUE INDEX "GitSource_gitlabAppId_key" ON "GitSource"("gitlabAppId"); +PRAGMA foreign_key_check; +PRAGMA foreign_keys=ON; diff --git a/apps/api/prisma/schema.prisma b/apps/api/prisma/schema.prisma index 7aba93db4..862c34e14 100644 --- a/apps/api/prisma/schema.prisma +++ b/apps/api/prisma/schema.prisma @@ -218,6 +218,7 @@ model GitSource { type String? apiUrl String? htmlUrl String? + customPort Int @default(22) organization String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/apps/api/src/jobs/deployApplication.ts b/apps/api/src/jobs/deployApplication.ts index ea090ebfd..d553e69c9 100644 --- a/apps/api/src/jobs/deployApplication.ts +++ b/apps/api/src/jobs/deployApplication.ts @@ -56,7 +56,7 @@ import * as buildpacks from '../lib/buildPacks'; exposePort, baseImage, baseBuildImage, - deploymentType + deploymentType, } = message let { branch, @@ -127,6 +127,7 @@ import * as buildpacks from '../lib/buildPacks'; repodir, githubAppId: gitSource.githubApp?.id, gitlabAppId: gitSource.gitlabApp?.id, + customPort: gitSource.customPort, repository, branch, buildId, diff --git a/apps/api/src/lib/importers/github.ts b/apps/api/src/lib/importers/github.ts index 76aee1398..bac460eca 100644 --- a/apps/api/src/lib/importers/github.ts +++ b/apps/api/src/lib/importers/github.ts @@ -11,7 +11,8 @@ export default async function ({ apiUrl, htmlUrl, branch, - buildId + buildId, + customPort }: { applicationId: string; workdir: string; @@ -21,6 +22,7 @@ export default async function ({ htmlUrl: string; branch: string; buildId: string; + customPort: number; }): Promise { const { default: got } = await import('got') const url = htmlUrl.replace('https://', '').replace('http://', ''); @@ -54,7 +56,7 @@ export default async function ({ applicationId }); await asyncExecShell( - `git clone -q -b ${branch} https://x-access-token:${token}@${url}/${repository}.git ${workdir}/ && cd ${workdir} && git submodule update --init --recursive && git lfs pull && cd .. ` + `git clone -q -b ${branch} https://x-access-token:${token}@${url}/${repository}.git --config core.sshCommand="ssh -p ${customPort}" ${workdir}/ && cd ${workdir} && git submodule update --init --recursive && git lfs pull && cd .. ` ); const { stdout: commit } = await asyncExecShell(`cd ${workdir}/ && git rev-parse HEAD`); return commit.replace('\n', ''); diff --git a/apps/api/src/lib/importers/gitlab.ts b/apps/api/src/lib/importers/gitlab.ts index d5366303e..b1784b6b9 100644 --- a/apps/api/src/lib/importers/gitlab.ts +++ b/apps/api/src/lib/importers/gitlab.ts @@ -9,7 +9,8 @@ export default async function ({ repository, branch, buildId, - privateSshKey + privateSshKey, + customPort }: { applicationId: string; workdir: string; @@ -19,6 +20,7 @@ export default async function ({ buildId: string; repodir: string; privateSshKey: string; + customPort: number; }): Promise { const url = htmlUrl.replace('https://', '').replace('http://', '').replace(/\/$/, ''); await saveBuildLog({ line: 'GitLab importer started.', buildId, applicationId }); @@ -32,7 +34,7 @@ export default async function ({ }); await asyncExecShell( - `git clone -q -b ${branch} git@${url}:${repository}.git --config core.sshCommand="ssh -q -i ${repodir}id.rsa -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git submodule update --init --recursive && git lfs pull && cd .. ` + `git clone -q -b ${branch} git@${url}:${repository}.git --config core.sshCommand="ssh -p ${customPort} -q -i ${repodir}id.rsa -o StrictHostKeyChecking=no" ${workdir}/ && cd ${workdir}/ && git submodule update --init --recursive && git lfs pull && cd .. ` ); const { stdout: commit } = await asyncExecShell(`cd ${workdir}/ && git rev-parse HEAD`); return commit.replace('\n', ''); diff --git a/apps/api/src/routes/api/v1/sources/handlers.ts b/apps/api/src/routes/api/v1/sources/handlers.ts index d81a27d1e..9bed930d7 100644 --- a/apps/api/src/routes/api/v1/sources/handlers.ts +++ b/apps/api/src/routes/api/v1/sources/handlers.ts @@ -20,10 +20,11 @@ export async function listSources(request: FastifyRequest) { export async function saveSource(request, reply) { try { const { id } = request.params - const { name, htmlUrl, apiUrl } = request.body + let { name, htmlUrl, apiUrl, customPort } = request.body + if (customPort) customPort = Number(customPort) await prisma.gitSource.update({ where: { id }, - data: { name, htmlUrl, apiUrl } + data: { name, htmlUrl, apiUrl, customPort } }); return reply.code(201).send() } catch ({ status, message }) { @@ -45,7 +46,8 @@ export async function getSource(request: FastifyRequest) { type: null, htmlUrl: null, apiUrl: null, - organization: null + organization: null, + customPort: 22, }, settings } @@ -58,7 +60,7 @@ export async function getSource(request: FastifyRequest) { if (!source) { throw { status: 404, message: 'Source not found.' } } - + if (source?.githubApp?.clientSecret) source.githubApp.clientSecret = decrypt(source.githubApp.clientSecret); if (source?.githubApp?.webhookSecret) @@ -97,9 +99,12 @@ export async function deleteSource(request) { } export async function saveGitHubSource(request: FastifyRequest, reply: FastifyReply) { try { - const { id } = request.params - const { name, type, htmlUrl, apiUrl, organization } = request.body const { teamId } = request.user + + const { id } = request.params + let { name, type, htmlUrl, apiUrl, organization, customPort } = request.body + + if (customPort) customPort = Number(customPort) if (id === 'new') { const newId = cuid() await prisma.gitSource.create({ @@ -109,6 +114,7 @@ export async function saveGitHubSource(request: FastifyRequest, reply: FastifyRe htmlUrl, apiUrl, organization, + customPort, type: 'github', teams: { connect: { id: teamId } } } @@ -126,15 +132,16 @@ export async function saveGitLabSource(request: FastifyRequest, reply: FastifyRe try { const { id } = request.params const { teamId } = request.user - let { type, name, htmlUrl, apiUrl, oauthId, appId, appSecret, groupName } = + let { type, name, htmlUrl, apiUrl, oauthId, appId, appSecret, groupName, customPort } = request.body - oauthId = Number(oauthId); + if (oauthId) oauthId = Number(oauthId); + if (customPort) customPort = Number(customPort) const encryptedAppSecret = encrypt(appSecret); if (id === 'new') { const newId = cuid() - await prisma.gitSource.create({ data: { id: newId, type, apiUrl, htmlUrl, name, teams: { connect: { id: teamId } } } }); + await prisma.gitSource.create({ data: { id: newId, type, apiUrl, htmlUrl, name, customPort, teams: { connect: { id: teamId } } } }); await prisma.gitlabApp.create({ data: { teams: { connect: { id: teamId } }, @@ -150,7 +157,7 @@ export async function saveGitLabSource(request: FastifyRequest, reply: FastifyRe id: newId } } else { - await prisma.gitSource.update({ where: { id }, data: { type, apiUrl, htmlUrl, name } }); + await prisma.gitSource.update({ where: { id }, data: { type, apiUrl, htmlUrl, name, customPort } }); await prisma.gitlabApp.update({ where: { id }, data: { diff --git a/apps/ui/src/routes/sources/[id]/_Github.svelte b/apps/ui/src/routes/sources/[id]/_Github.svelte index 3bd7719b7..21294fa27 100644 --- a/apps/ui/src/routes/sources/[id]/_Github.svelte +++ b/apps/ui/src/routes/sources/[id]/_Github.svelte @@ -11,7 +11,11 @@ import { dev } from '$app/env'; const { id } = $page.params; + + $: selfHosted = source.htmlUrl !== 'https://github.com'; + let loading = false; + async function handleSubmit() { loading = true; try { @@ -57,7 +61,8 @@ name: source.name, htmlUrl: source.htmlUrl.replace(/\/$/, ''), apiUrl: source.apiUrl.replace(/\/$/, ''), - organization: source.organization + organization: source.organization, + customPort: source.customPort }); const { organization, htmlUrl } = source; const { fqdn } = settings; @@ -113,8 +118,11 @@
{#if !source.githubAppId}
-
+
General
+ {#if !source.githubAppId} + + {/if}
@@ -131,6 +139,20 @@
+
+ + + +
- {#if source.apiUrl && source.htmlUrl && source.name} -
- -
- {/if} {:else if source.githubApp?.installationId}
@@ -181,11 +198,39 @@
- +
- + +
+
+ + +
@@ -207,7 +252,9 @@ {:else}
- Install Repositories
{/if} diff --git a/apps/ui/src/routes/sources/[id]/_Gitlab.svelte b/apps/ui/src/routes/sources/[id]/_Gitlab.svelte index 43ea7c871..25cb6d126 100644 --- a/apps/ui/src/routes/sources/[id]/_Gitlab.svelte +++ b/apps/ui/src/routes/sources/[id]/_Gitlab.svelte @@ -12,8 +12,8 @@ import { t } from '$lib/translations'; import { errorNotification } from '$lib/common'; import { appSession } from '$lib/store'; - import { goto } from '$app/navigation'; const { id } = $page.params; + let url = settings.fqdn ? settings.fqdn : window.location.origin; if (dev) { @@ -31,6 +31,8 @@ appSecret: null }; } + $: selfHosted = source.htmlUrl !== 'https://gitlab.com' ; + onMount(() => { oauthIdEl && oauthIdEl.focus(); }); @@ -49,7 +51,8 @@ oauthId: source.gitlabApp.oauthId, appId: source.gitlabApp.appId, appSecret: source.gitlabApp.appSecret, - groupName: source.gitlabApp.groupName + groupName: source.gitlabApp.groupName, + customPort: source.customPort }); const from = $page.url.searchParams.get('from'); if (from) { @@ -67,7 +70,8 @@ await post(`/sources/${id}`, { name: source.name, htmlUrl: source.htmlUrl.replace(/\/$/, ''), - apiUrl: source.apiUrl.replace(/\/$/, '') + apiUrl: source.apiUrl.replace(/\/$/, ''), + customPort: source.customPort }); toast.push('Configuration saved.'); } catch (error) { @@ -119,6 +123,10 @@ window.open(`${source.htmlUrl}/-/profile/applications`); break; case 'group': + if (!source.gitlabApp.groupName) { + toast.push('Please enter a group name first.'); + return; + } window.open( `${source.htmlUrl}/groups/${source.gitlabApp.groupName}/-/settings/applications` ); @@ -146,6 +154,8 @@ + {:else} + {/if} {/if}
@@ -204,7 +214,7 @@ required disabled={source.gitlabAppId} readonly={source.gitlabAppId} - value={source.htmlUrl} + bind:value={source.htmlUrl} />
@@ -218,6 +228,20 @@ value={source.apiUrl} />
+
+ + + +