Skip to content
173 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.1import { Form, Link, data, redirect } from "react-router";
Usage lists Other once: kinds of work without words of their own are added into it2
3import type { Route } from "./+types/github-setup";
4import { AuthCard } from "../components/auth-card";
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.5import { GithubMark } from "../components/github";
6import { ErrorText, SubmitButton } from "../components/ui";
7import { INSTALL_COOKIE, cookie, installWorkspace, installationSummary, readCookie, setupChoices } from "../lib/github";
Usage lists Other once: kinds of work without words of their own are added into it8import { githubApp } from "../lib/github.server";
9import { page } from "../lib/meta";
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.10import { assertSameOrigin, requireUser, roleIn } from "../lib/session.server";
Usage lists Other once: kinds of work without words of their own are added into it11
12export function meta(args: Route.MetaArgs) {
13 return page(args, { title: "Connecting GitHub · g1t" });
14}
15
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.16type Problem = { kind: "error"; error: string; workspace: string | null; link: string | null };
17type Choice = {
18 kind: "choose";
19 installation: { id: number; account: string; summary: string };
20 workspaces: { slug: string; name: string; added: boolean }[];
21};
22
Usage lists Other once: kinds of work without words of their own are added into it23/**
24 * The app's Setup URL: GitHub returns here after an installation with
25 * `installation_id`, `setup_action` and the state. The installation is
26 * recorded against the workspace it was started for, after integrations
27 * checks with the person's own GitHub token that they can see it.
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.28 *
29 * Without g1t's state (the app was installed on GitHub directly, from
30 * another browser, or the cookie was lost), the person chooses which of
31 * the workspaces they own to add it to, checked the same way.
Usage lists Other once: kinds of work without words of their own are added into it32 */
33export async function loader({ request, context }: Route.LoaderArgs) {
34 const user = requireUser(context, request);
35 const url = new URL(request.url);
36 const clear = { "set-cookie": cookie(INSTALL_COOKIE, "", 0) };
37 const workspace = installWorkspace(readCookie(request.headers.get("cookie"), INSTALL_COOKIE), url.searchParams.get("state"));
38 const action = url.searchParams.get("setup_action");
39 const installation = Number(url.searchParams.get("installation_id"));
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.40 const problem = (error: string, at: string | null = workspace, link: string | null = null) =>
41 data<Problem | Choice>({ kind: "error", error, workspace: at, link }, { headers: clear });
Usage lists Other once: kinds of work without words of their own are added into it42 // Repositories chosen again on GitHub: nothing to record, the picker
43 // lists what the installation can see now.
44 if (!workspace && action === "update") throw redirect("/new/github", { headers: clear });
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.45 // An organization member asked an owner to approve: nothing to record yet.
46 if (action === "request") {
47 const back = workspace ? `/new/github?workspace=${encodeURIComponent(workspace)}&` : "/new/github?";
48 throw redirect(`${back}requested=1`, { headers: clear });
Usage lists Other once: kinds of work without words of their own are added into it49 }
50 if (!Number.isSafeInteger(installation) || installation <= 0) {
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.51 return problem("GitHub did not say which installation was made.");
Usage lists Other once: kinds of work without words of their own are added into it52 }
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.53 if (workspace) {
54 const added = await githubApp.addInstallation(user, workspace, installation);
55 if (!added.ok) return problem(added.error.message);
56 throw redirect(`/new/github?workspace=${encodeURIComponent(workspace)}&installation=${installation}`, { headers: clear });
57 }
58 const owned = (user.workspaces ?? []).filter((membership) => membership.role === "owner");
59 if (owned.length === 0) {
60 return problem("Only a workspace owner can add a GitHub account. Ask an owner of your workspace to add it from Import from GitHub.", null);
61 }
62 const visible = await githubApp.visibleInstallations(user);
63 if (!visible.ok) {
64 // GitHub not linked, or its access ended: link it and come back here.
65 const unlinked = visible.error.code === "not_found" || visible.error.code === "unauthenticated";
66 const here = `${url.pathname}${url.search}`;
67 return problem(visible.error.message, null, unlinked ? `/auth/github?link=1&next=${encodeURIComponent(here)}` : null);
68 }
69 const found = visible.value.find((item) => item.id === installation);
70 if (!found) {
71 return problem(
72 "Your GitHub account cannot see that installation. Install the app from your own GitHub account or an organization you manage.",
73 null,
74 );
75 }
76 return data<Problem | Choice>(
77 {
78 kind: "choose",
79 installation: { id: found.id, account: found.account, summary: installationSummary(found) },
80 workspaces: setupChoices(owned, found),
81 },
82 { headers: clear },
83 );
84}
85
86export async function action({ request, context }: Route.ActionArgs) {
87 assertSameOrigin(request);
88 const user = requireUser(context, request);
89 const form = await request.formData();
90 const workspace = String(form.get("workspace") ?? "").toLowerCase();
91 const installation = Number(form.get("installation"));
92 if (roleIn(user, workspace) !== "owner") return { error: "Only an owner of the workspace can add GitHub accounts to it." };
93 if (!Number.isSafeInteger(installation) || installation <= 0) return { error: "Choose an installation to add." };
Usage lists Other once: kinds of work without words of their own are added into it94 const added = await githubApp.addInstallation(user, workspace, installation);
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.95 if (!added.ok) return { error: added.error.message };
96 throw redirect(`/new/github?workspace=${encodeURIComponent(workspace)}&installation=${installation}`);
Usage lists Other once: kinds of work without words of their own are added into it97}
98
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.99export default function GithubSetup({ loaderData, actionData }: Route.ComponentProps) {
100 if (loaderData.kind === "choose") {
101 const { installation, workspaces } = loaderData;
102 return (
103 <AuthCard
104 title="Add a GitHub account"
105 subtitle={`Add the installation on ${installation.account} to which workspace?`}
106 footer={
107 <Link to="/new/github" className="text-fg underline underline-offset-4">
108 Not now
109 </Link>
110 }
111 >
112 <div className="flex items-center gap-3 rounded-md border border-line px-4 py-3">
113 <GithubMark className="size-5 shrink-0" />
114 <div className="min-w-0">
115 <p className="truncate font-mono text-sm">{installation.account}</p>
116 <p className="text-xs text-faint">{installation.summary}</p>
117 </div>
118 </div>
119 <ul className="mt-4 divide-y divide-line rounded-md border border-line">
120 {workspaces.map((option) => (
121 <li key={option.slug} className="flex items-center gap-3 px-4 py-2.5">
122 <div className="min-w-0">
123 <p className="truncate text-sm">{option.name}</p>
124 {option.name !== option.slug && <p className="truncate font-mono text-xs text-faint">{option.slug}</p>}
125 </div>
126 <span className="ml-auto shrink-0">
127 {option.added ? (
128 <Link to={`/new/github?workspace=${option.slug}&installation=${installation.id}`} className="text-sm text-muted hover:text-fg">
129 Added · Open
130 </Link>
131 ) : (
132 <Form method="post">
133 <input type="hidden" name="installation" value={installation.id} />
134 <SubmitButton name="workspace" value={option.slug} pending="Adding…">
135 Add
136 </SubmitButton>
137 </Form>
138 )}
139 </span>
140 </li>
141 ))}
142 </ul>
143 <ErrorText>{actionData?.error}</ErrorText>
144 </AuthCard>
145 );
146 }
Usage lists Other once: kinds of work without words of their own are added into it147 return (
148 <AuthCard
149 title="Connecting GitHub"
150 subtitle="That did not work"
151 footer={
152 <Link
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.153 to={loaderData.workspace ? `/new/github?workspace=${loaderData.workspace}` : "/new/github"}
Usage lists Other once: kinds of work without words of their own are added into it154 className="text-fg underline underline-offset-4"
155 >
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.156 Back to Import from GitHub
Usage lists Other once: kinds of work without words of their own are added into it157 </Link>
158 }
159 >
160 <p className="text-sm text-danger" role="alert">
161 {loaderData.error}
162 </p>
A GitHub App installed straight on GitHub can be added to a workspace: Import from GitHub lists the installations your GitHub account can see that this workspace hasn't added, each with Add for owners, and coming back from GitHub without g1t's own start asks which of your workspaces to add it to instead of stopping; the GitHub guide says how.163 {loaderData.link && (
164 <a
165 href={loaderData.link}
166 className="mt-4 inline-flex w-full items-center justify-center gap-2 rounded-md bg-fg px-3.5 py-2 text-sm font-medium text-bg hover:bg-fg-hover"
167 >
168 <GithubMark /> Link your GitHub account
169 </a>
170 )}
Usage lists Other once: kinds of work without words of their own are added into it171 </AuthCard>
172 );
173}

This file's history is long; its oldest lines are credited to the oldest commit read.