Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
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";
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files2
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";
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files8import { 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";
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files11
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
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files23/**
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.
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files32 */
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 });
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files42 // 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 });
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files49 }
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.");
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files52 }
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." };
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files94 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}`);
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files97}
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 }
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files147 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"}
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files154 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
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files157 </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 )}
An unknown behind count reads ?, not 0+; Code pages leave the description and topics to Files171 </AuthCard>
172 );
173}

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