Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gitea support #8131

Draft
wants to merge 23 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'upstream/main' into gitea
  • Loading branch information
anbraten committed Mar 17, 2022
commit b093367a244fdf27aa72f136db91fd5c23e07335
12 changes: 6 additions & 6 deletions components/dashboard/src/App.tsx
Original file line number Diff line number Diff line change
@@ -473,12 +473,12 @@ function App() {
toRender = <CreateWorkspace contextUrl={hash} />;
} else if (isWsStart) {
toRender = <StartWorkspace {...parseProps(hash, window.location.search)} />;
} else if (/^(github|gitlab|gitea)\.com\/.+?/i.test(window.location.pathname)) {
let url = new URL(window.location.href)
url.hash = url.pathname
url.pathname = '/'
window.location.replace(url)
return <div></div>
} else if (/^(github|gitlab)\.com\/.+?/i.test(window.location.pathname)) {
let url = new URL(window.location.href);
url.hash = url.pathname;
url.pathname = "/";
window.location.replace(url);
return <div></div>;
}

return <Suspense fallback={<Loading />}>{toRender}</Suspense>;
146 changes: 88 additions & 58 deletions components/dashboard/src/settings/Integrations.tsx
Original file line number Diff line number Diff line change
@@ -440,46 +440,10 @@ function GitIntegrations() {
/>
)}

{modal?.mode === "new" && (
<GitIntegrationModal mode={modal.mode} userId={user?.id || "no-user"} onClose={() => setModal(undefined)} onUpdate={updateOwnAuthProviders} />
)}
{modal?.mode === "edit" && (
<GitIntegrationModal mode={modal.mode} userId={user?.id || "no-user"} provider={modal.provider} onClose={() => setModal(undefined)} onUpdate={updateOwnAuthProviders} />
)}
{modal?.mode === "delete" && (
<ConfirmationModal
title="Remove Integration"
areYouSureText="Are you sure you want to remove the following Git integration?"
children={{
name: modal.provider.type,
description: modal.provider.host,
}}
buttonText="Remove Integration"
onClose={() => setModal(undefined)}
onConfirm={() => deleteProvider(modal.provider)}
/>

)}

<div className="flex items-start sm:justify-between mb-2">
<div>
<h3>Git Integrations</h3>
<h2>Manage Git integrations for GitLab, GitHub or Gitea self-hosted instances.</h2>
</div>
{providers.length !== 0
?
<div className="mt-3 flex mt-0">
<button onClick={() => setModal({ mode: "new" })} className="ml-2">New Integration</button>
</div>
: null}
</div>

{providers && providers.length === 0 && (
<div className="w-full flex h-80 mt-2 rounded-xl bg-gray-100 dark:bg-gray-900">
<div className="m-auto text-center">
<h3 className="self-center text-gray-500 dark:text-gray-400 mb-4">No Git Integrations</h3>
<div className="text-gray-500 mb-6">In addition to the default Git Providers you can authorize<br /> with a self-hosted instance of a provider.</div>
<button className="self-center" onClick={() => setModal({ mode: "new" })}>New Integration</button>
<div className="flex items-start sm:justify-between mb-2">
<div>
<h3>Git Integrations</h3>
<h2>Manage Git integrations for GitLab, GitHub or Gitea self-hosted instances.</h2>
</div>
{providers.length !== 0 ? (
<div className="mt-3 flex mt-0">
@@ -713,7 +677,8 @@ export function GitIntegrationModal(
case "Gitea":
settingsUrl = `${host}/user/settings/applications`;
break;
default: return undefined;
default:
return undefined;
}
let docsUrl = ``;
switch (type) {
@@ -726,7 +691,8 @@ export function GitIntegrationModal(
case "Gitea":
docsUrl = `https://www.gitpod.io/docs/gitea-integration/#oauth-application`;
break;
default: return undefined;
default:
return undefined;
}

return (
@@ -767,15 +733,19 @@ export function GitIntegrationModal(
}
};

return (<Modal visible={!!props} onClose={onClose} closeable={props.closeable}>
<h3 className="pb-2">{mode === "new" ? "New Git Integration" : "Git Integration"}</h3>
<div className="space-y-4 border-t border-b border-gray-200 dark:border-gray-800 mt-2 -mx-6 px-6 py-4">
{mode === "edit" && providerEntry?.status !== "verified" && (
<AlertBox>You need to activate this integration.</AlertBox>
)}
<div className="flex flex-col">
<span className="text-gray-500">{props.headerText || "Configure a Git integration with a GitLab, GitHub or Gitea self-hosted instance."}</span>
</div>
return (
<Modal visible={!!props} onClose={onClose} closeable={props.closeable}>
<h3 className="pb-2">{mode === "new" ? "New Git Integration" : "Git Integration"}</h3>
<div className="space-y-4 border-t border-b border-gray-200 dark:border-gray-800 mt-2 -mx-6 px-6 py-4">
{mode === "edit" && providerEntry?.status !== "verified" && (
<AlertBox>You need to activate this integration.</AlertBox>
)}
<div className="flex flex-col">
<span className="text-gray-500">
{props.headerText ||
"Configure a Git integration with a GitLab, GitHub or Gitea self-hosted instance."}
</span>
</div>

<div className="overscroll-contain max-h-96 overflow-y-auto pr-2">
{mode === "new" && (
@@ -792,17 +762,77 @@ export function GitIntegrationModal(
>
<option value="GitHub">GitHub</option>
<option value="GitLab">GitLab</option>
<option value="Gitea">Gitea</option>
</select>
</div>
)}
<div className="flex flex-col space-y-2">
<label htmlFor="type" className="font-medium">Provider Type</label>
<select name="type" value={type} disabled={mode !== "new"} className="w-full"
onChange={(e) => setType(e.target.value)}>
<option value="GitHub">GitHub</option>
<option value="GitLab">GitLab</option>
<option value="Gitea">Gitea</option>
</select>
<label htmlFor="hostName" className="font-medium">
Provider Host Name
</label>
<input
name="hostName"
disabled={mode === "edit"}
type="text"
placeholder={getPlaceholderForIntegrationType(type)}
value={host}
className="w-full"
onChange={(e) => updateHostValue(e.target.value)}
/>
</div>
<div className="flex flex-col space-y-2">
<label htmlFor="redirectURL" className="font-medium">
Redirect URL
</label>
<div className="w-full relative">
<input
name="redirectURL"
disabled={true}
readOnly={true}
type="text"
value={redirectURL}
className="w-full pr-8"
/>
<div className="cursor-pointer" onClick={() => copyRedirectUrl()}>
<img
src={copy}
title="Copy the Redirect URL to clipboard"
className="absolute top-1/3 right-3"
/>
</div>
</div>
<span className="text-gray-500 text-sm">{getRedirectUrlDescription(type, host)}</span>
</div>
<div className="flex flex-col space-y-2">
<label htmlFor="clientId" className="font-medium">{`${
type === "GitLab" ? "Application ID" : "Client ID"
}`}</label>
<input
name="clientId"
type="text"
value={clientId}
className="w-full"
onChange={(e) => updateClientId(e.target.value)}
/>
</div>
<div className="flex flex-col space-y-2">
<label htmlFor="clientSecret" className="font-medium">{`${
type === "GitLab" ? "Secret" : "Client Secret"
}`}</label>
<input
name="clientSecret"
type="password"
value={clientSecret}
className="w-full"
onChange={(e) => updateClientSecret(e.target.value)}
/>
</div>
</div>

{(errorMessage || validationError) && (
<div className="flex rounded-md bg-red-600 p-3">
<img className="w-4 h-4 mx-2 my-auto filter-brightness-10" src={exclamation} />
<span className="text-white">{errorMessage || validationError}</span>
</div>
)}
</div>
12 changes: 6 additions & 6 deletions components/server/ee/src/auth/host-container-mapping.ts
Original file line number Diff line number Diff line change
@@ -24,12 +24,12 @@ export class HostContainerMappingEE extends HostContainerMapping {
// case "BitbucketServer":
// FIXME
// return (modules || []).concat([bitbucketContainerModuleEE]);
case "GitHub":
return (modules || []).concat([gitHubContainerModuleEE]);
case "Gitea":
return (modules || []).concat([giteaContainerModuleEE]);
default:
return modules;
case "GitHub":
return (modules || []).concat([gitHubContainerModuleEE]);
case "Gitea":
return (modules || []).concat([giteaContainerModuleEE]);
default:
return modules;
}
}
}
1 change: 1 addition & 0 deletions components/server/ee/src/container-module.ts
Original file line number Diff line number Diff line change
@@ -59,6 +59,7 @@ import { SnapshotService } from "./workspace/snapshot-service";
import { BitbucketAppSupport } from "./bitbucket/bitbucket-app-support";
import { GiteaAppSupport } from "./gitea/gitea-app-support";
import { GiteaApp } from "./prebuilds/gitea-app";
import { UserCounter } from "./user/user-counter";

export const productionEEContainerModule = new ContainerModule((bind, unbind, isBound, rebind) => {
rebind(Server).to(ServerEE).inSingletonScope();
14 changes: 7 additions & 7 deletions components/server/ee/src/server.ts
Original file line number Diff line number Diff line change
@@ -7,14 +7,14 @@
import * as express from "express";
import { Server } from "../../src/server";
import { inject } from "inversify";
import { GitpodClient, GitpodServer } from '@gitpod/gitpod-protocol';
import { log } from '@gitpod/gitpod-protocol/lib/util/logging';
import { GitLabApp } from './prebuilds/gitlab-app';
import { BitbucketApp } from './prebuilds/bitbucket-app';
import { GithubApp } from './prebuilds/github-app';
import { GitpodClient, GitpodServer } from "@gitpod/gitpod-protocol";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import { GitLabApp } from "./prebuilds/gitlab-app";
import { BitbucketApp } from "./prebuilds/bitbucket-app";
import { GithubApp } from "./prebuilds/github-app";
import { GiteaApp } from './prebuilds/gitea-app';
import { SnapshotService } from './workspace/snapshot-service';
import { GitHubEnterpriseApp } from './prebuilds/github-enterprise-app';
import { SnapshotService } from "./workspace/snapshot-service";
import { GitHubEnterpriseApp } from "./prebuilds/github-enterprise-app";

export class ServerEE<C extends GitpodClient, S extends GitpodServer> extends Server<C, S> {
@inject(GithubApp) protected readonly githubApp: GithubApp;
34 changes: 17 additions & 17 deletions components/server/src/auth/host-container-mapping.ts
Original file line number Diff line number Diff line change
@@ -14,22 +14,22 @@ import { bitbucketServerContainerModule } from "../bitbucket-server/bitbucket-se

@injectable()
export class HostContainerMapping {
public get(type: string): interfaces.ContainerModule[] | undefined {
switch (type) {
case "GitHub":
return [githubContainerModule];
case "GitLab":
return [gitlabContainerModule];
case "OAuth":
return [genericAuthContainerModule];
case "Bitbucket":
return [bitbucketContainerModule];
case "Gitea":
return [giteaContainerModule];
case "BitbucketServer":
return [bitbucketServerContainerModule];
default:
return undefined;
public get(type: string): interfaces.ContainerModule[] | undefined {
switch (type) {
case "GitHub":
return [githubContainerModule];
case "GitLab":
return [gitlabContainerModule];
case "Gitea":
return [giteaContainerModule];
case "OAuth":
return [genericAuthContainerModule];
case "Bitbucket":
return [bitbucketContainerModule];
case "BitbucketServer":
return [bitbucketServerContainerModule];
default:
return undefined;
}
}
}
}
5 changes: 3 additions & 2 deletions components/server/src/projects/projects-service.ts
Original file line number Diff line number Diff line change
@@ -148,9 +148,10 @@ export class ProjectsService {
let { userId, teamId, cloneUrl } = project;
const parsedUrl = RepoURL.parseRepoUrl(project.cloneUrl);
const hostContext = parsedUrl?.host ? this.hostContextProvider.get(parsedUrl?.host) : undefined;
const type = hostContext && hostContext.authProvider.info.authProviderType;
const authProvider = hostContext && hostContext.authProvider.info;
const type = authProvider && authProvider.authProviderType;
// TODO: handle gitea
if (type === "GitLab" || type === "Bitbucket") {
if (type === "GitLab" || type === "Bitbucket" || AuthProviderInfo.isGitHubEnterprise(authProvider)) {
const repositoryService = hostContext?.services?.repositoryService;
if (repositoryService) {
// Note: For GitLab, we expect .canInstallAutomatedPrebuilds() to always return true, because earlier
You are viewing a condensed version of this merge commit. You can view the full changes here.