Skip to content

Commit

Permalink
🌇 GitHub App in Dashboard (#19070)
Browse files Browse the repository at this point in the history
* [dashboard] compute `useIsGithubAppEnabled` on FE

* [dashboard] update Install GitHub App

* [server] make GH App methods no-op (compat)
  • Loading branch information
AlexTugarev authored Nov 16, 2023
1 parent 0907ff5 commit feb9fa2
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { useCurrentUser } from "../../user-context";

export const useIsGithubAppEnabled = () => {
return useQuery(["github-app-enabled"], async () => {
return await getGitpodService().server.isGitHubAppEnabled();
// similar to `isGitpodio`, but the GH App is only configured on Cloud.
return window.location.hostname === "gitpod.io" || window.location.hostname === "gitpod-staging.com";
});
};

Expand Down
100 changes: 5 additions & 95 deletions components/dashboard/src/projects/InstallGitHubApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,118 +4,28 @@
* See License.AGPL.txt in the project root for license information.
*/

import { useLocation } from "react-router";
import InfoBox from "../components/InfoBox";
import Modal from "../components/Modal";
import { Deferred } from "@gitpod/gitpod-protocol/lib/util/deferred";
import { getGitpodService, gitpodHostUrl } from "../service/service";
import { useState } from "react";
import { openAuthorizeWindow } from "../provider-utils";

async function registerApp(installationId: string, setModal: (modal: "done" | string | undefined) => void) {
try {
await getGitpodService().server.registerGithubApp(installationId);

const result = new Deferred<void>(1000 * 60 * 10 /* 10 min */);

openAuthorizeWindow({
host: "github.com",
scopes: ["repo"],
onSuccess: () => {
setModal("done");
result.resolve();
},
onError: (payload) => {
let errorMessage: string;
if (typeof payload === "string") {
errorMessage = payload;
} else {
errorMessage = payload.description ? payload.description : `Error: ${payload.error}`;
}
setModal(errorMessage);
},
});

return result.promise;
} catch (e) {
setModal(e.message);
}
}
import { gitpodHostUrl } from "../service/service";

export default function InstallGitHubApp() {
const location = useLocation();
const [modal, setModal] = useState<"done" | string | undefined>();
const params = new URLSearchParams(location.search);
const installationId = params.get("installation_id") || undefined;
if (!installationId) {
return (
<div className="app-container flex flex-col space-y-2">
<div className="px-6 py-3 flex justify-between space-x-2 text-gray-400 border-t border-gray-200 dark:border-gray-800 h-96">
<div className="flex flex-col items-center w-96 m-auto">
<h3 className="text-center pb-3 text-gray-500 dark:text-gray-400">No Installation ID Found</h3>
<div className="text-center pb-6 text-gray-500">
Did you come here from the GitHub app's page?
</div>
</div>
</div>
</div>
);
}

const goToApp = () => (window.location.href = gitpodHostUrl.toString());

return (
<>
<div className="app-container flex flex-col space-y-2">
<div className="px-6 py-3 flex justify-between space-x-2 text-gray-400">
<div className="flex flex-col items-center m-auto max-w-lg mt-40">
<h3 className="text-center pb-3 text-gray-500">Install GitHub App</h3>
<h3 className="text-center pb-3 text-gray-500">GitHub App 🌅</h3>
<div className="text-center pb-6 text-gray-500">
You are about to install the GitHub app for Gitpod.
You likely tried to install the GitHub App for Gitpod.
</div>
<InfoBox>
This action will also allow Gitpod to access private repositories. You can edit Git provider
permissions later in user settings.
</InfoBox>
<InfoBox>Gitpod no longer requires to install the GitHub App on repositories.</InfoBox>
<div className="mt-6">
<button className="secondary">Cancel</button>
<button className="ml-2" onClick={() => registerApp(installationId, setModal)}>
Install App
</button>
<button onClick={goToApp}>Go to Dashboard</button>
</div>
</div>
</div>
</div>
<Modal
title="Installation Successful"
visible={modal === "done"}
onClose={goToApp}
buttons={<button onClick={goToApp}>Go to Dashboard</button>}
>
<div className="pb-6 text-gray-500">
The GitHub app was installed successfully. Have a look at the{" "}
<a className="text-blue-500" href="https://www.gitpod.io/docs/prebuilds/" rel="noopener">
documentation
</a>{" "}
to find out how to configure it.
</div>
</Modal>
<Modal
title="Failed to Install"
visible={!!modal && modal !== "done"}
onClose={goToApp}
buttons={[
<button className="secondary" onClick={goToApp}>
Cancel
</button>,
<button className="" onClick={() => registerApp(installationId, setModal)}>
Try Again
</button>,
]}
>
<div className="pb-6 text-gray-500">Could not install the GitHub app.</div>
<InfoBox>{modal}</InfoBox>
</Modal>
</>
);
}
2 changes: 2 additions & 0 deletions components/gitpod-protocol/src/gitpod-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
deleteGitpodToken(tokenHash: string): Promise<void>;

// misc
/** @deprecated always returns false */
isGitHubAppEnabled(): Promise<boolean>;
/** @deprecated this is a no-op */
registerGithubApp(installationId: string): Promise<void>;

/**
Expand Down
21 changes: 2 additions & 19 deletions components/server/src/workspace/gitpod-server-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import {
AppInstallationDB,
UserDB,
WorkspaceDB,
DBWithTracing,
Expand Down Expand Up @@ -223,8 +222,6 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {

@inject(LinkedInService) private readonly linkedInService: LinkedInService,

@inject(AppInstallationDB) private readonly appInstallationDB: AppInstallationDB,

@inject(AuthProviderService) private readonly authProviderService: AuthProviderService,

@inject(GitTokenScopeGuesser) private readonly gitTokenScopeGuesser: GitTokenScopeGuesser,
Expand Down Expand Up @@ -1725,24 +1722,10 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
}

async isGitHubAppEnabled(ctx: TraceContext): Promise<boolean> {
await this.checkAndBlockUser();
return !!this.config.githubApp?.enabled;
return false;
}

async registerGithubApp(ctx: TraceContext, installationId: string): Promise<void> {
traceAPIParams(ctx, { installationId });

const user = await this.checkAndBlockUser();

if (!this.config.githubApp?.enabled) {
throw new ApplicationError(
ErrorCodes.NOT_FOUND,
"No GitHub app enabled for this installation. Please talk to your administrator.",
);
}

await this.appInstallationDB.recordNewInstallation("github", "user", installationId, user.id);
}
async registerGithubApp(ctx: TraceContext, installationId: string): Promise<void> {}

async takeSnapshot(ctx: TraceContext, options: GitpodServer.TakeSnapshotOptions): Promise<string> {
traceAPIParams(ctx, { options });
Expand Down

0 comments on commit feb9fa2

Please sign in to comment.