Auto-restart after GitHub App setup instead of requiring manual restart

Set env vars on process.env at runtime after writing .env, then redirect
to /auth/login. Removes the success UI telling users to restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-03-02 20:03:18 -05:00
parent 67652ad480
commit 4d362f320c

View file

@ -1,6 +1,7 @@
import { readFile, writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { randomBytes } from "node:crypto";
import { redirect } from "react-router";
import type { Route } from "./+types/setup-callback";
const ENV_PATH = resolve(import.meta.dirname, "../../../../.env");
@ -9,7 +10,7 @@ export async function loader({ request }: Route.LoaderArgs) {
const url = new URL(request.url);
const code = url.searchParams.get("code");
if (!code) {
return { success: false, error: "Missing code parameter" };
return { error: "Missing code parameter" };
}
const response = await fetch(
@ -19,10 +20,7 @@ export async function loader({ request }: Route.LoaderArgs) {
if (!response.ok) {
const body = await response.text();
return {
success: false,
error: `GitHub API error: ${response.status} ${body}`,
};
return { error: `GitHub API error: ${response.status} ${body}` };
}
const data = (await response.json()) as {
@ -54,33 +52,42 @@ export async function loader({ request }: Route.LoaderArgs) {
const envContent = existing ? `${existing.trimEnd()}\n\n${newVars}\n` : `${newVars}\n`;
await writeFile(ENV_PATH, envContent, "utf-8");
return { success: true, error: null };
process.env.SESSION_SECRET = sessionSecret;
process.env.GITHUB_APP_ID = String(data.id);
process.env.GITHUB_APP_CLIENT_ID = data.client_id;
process.env.GITHUB_APP_CLIENT_SECRET = data.client_secret;
process.env.GITHUB_APP_WEBHOOK_SECRET = data.webhook_secret;
process.env.GITHUB_APP_PRIVATE_KEY = data.pem;
throw redirect("/auth/login");
}
export default function SetupCallback({ loaderData }: Route.ComponentProps) {
const { success, error } = loaderData;
const { error } = loaderData;
return (
<div className="flex min-h-screen items-center justify-center bg-page">
<div className="w-full max-w-md rounded-lg border border-line-strong bg-panel p-8 shadow-sm">
{success ? (
<>
<h1 className="text-xl font-semibold text-fg">
GitHub App registered
</h1>
<p className="mt-2 text-sm text-fg-muted">
Credentials have been written to <code>.env</code>. Restart the
app to pick up the new configuration.
</p>
</>
) : (
<>
<h1 className="text-xl font-semibold text-red-500">
Setup failed
</h1>
<p className="mt-2 text-sm text-fg-muted">{error}</p>
</>
)}
<div className="flex min-h-screen flex-col items-center justify-center bg-atmosphere px-4">
<div className="w-full max-w-sm">
<div className="mb-8 flex justify-center">
<img src="/logo.svg" alt="Arc" className="h-12 w-12" draggable={false} />
</div>
<div className="rounded-xl border border-line bg-panel/80 p-8 shadow-lg backdrop-blur-sm">
<div className="mx-auto mb-4 flex h-10 w-10 items-center justify-center rounded-full bg-coral/10">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" className="text-coral">
<path d="M7 7L13 13M13 7L7 13" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
</svg>
</div>
<h1 className="text-center text-lg font-semibold text-fg">
Setup failed
</h1>
<p className="mt-2 text-center text-sm text-fg-3">{error}</p>
<a
href="/setup"
className="mt-6 flex w-full items-center justify-center rounded-lg border border-line-strong px-4 py-2.5 text-sm font-medium text-fg-2 transition-colors hover:bg-overlay-strong"
>
Try again
</a>
</div>
</div>
</div>
);