-
Notifications
You must be signed in to change notification settings - Fork 0
Show install prompt when GitHub App is missing from repo pages #1308
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import Link from "next/link" | ||
|
|
||
| import { isAppInstalledForRepo } from "@/lib/github/install-check" | ||
|
|
||
| interface LayoutProps { | ||
| children: React.ReactNode | ||
| params: { | ||
| username: string | ||
| repo: string | ||
| } | ||
| } | ||
|
|
||
| export default async function RepoLayout({ children, params }: LayoutProps) { | ||
| const { username, repo } = params | ||
|
|
||
| // Build GitHub App installation URL if available | ||
| const appSlug = process.env.NEXT_PUBLIC_GITHUB_APP_SLUG | ||
| const installUrl = appSlug | ||
| ? `https://github.com/apps/${appSlug}/installations/new` | ||
| : undefined | ||
|
|
||
| const installed = await isAppInstalledForRepo({ owner: username, repo }) | ||
|
|
||
| if (!installed) { | ||
| return ( | ||
| <main className="container mx-auto p-4"> | ||
| <div className="mb-6 rounded-md border border-yellow-300 bg-yellow-50 p-4 text-yellow-900"> | ||
| <h1 className="text-xl font-semibold mb-2"> | ||
| Issue to PR GitHub App is not installed for {username}/{repo} | ||
| </h1> | ||
| <p className="mb-4"> | ||
| To use Issue to PR features on this repository, install the GitHub App. | ||
| </p> | ||
| {installUrl ? ( | ||
| <Link | ||
| href={installUrl} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="inline-flex items-center rounded-md bg-stone-900 px-4 py-2 text-white hover:bg-stone-800" | ||
| > | ||
| Install Issue to PR on GitHub | ||
| </Link> | ||
| ) : ( | ||
| <div className="text-red-700"> | ||
| The GitHub App slug is not configured. Please set NEXT_PUBLIC_GITHUB_APP_SLUG. | ||
| </div> | ||
| )} | ||
| </div> | ||
| </main> | ||
| ) | ||
| } | ||
|
|
||
| return <>{children}</> | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| import { getInstallationFromRepo } from "./repos" | ||
|
|
||
| /** | ||
| * Checks whether the Issue-to-PR GitHub App is installed for the given repository. | ||
| * Returns true when installed, false when not installed or when the check fails | ||
| * with a 404 from GitHub. Other errors are logged and treated as not installed | ||
| * to avoid breaking the UX. | ||
| */ | ||
| export async function isAppInstalledForRepo({ | ||
| owner, | ||
| repo, | ||
| }: { | ||
| owner: string | ||
| repo: string | ||
| }): Promise<boolean> { | ||
| try { | ||
| await getInstallationFromRepo({ owner, repo }) | ||
| return true | ||
| } catch (error: unknown) { | ||
| // Octokit errors expose a numeric `status` code | ||
| const status = (error as { status?: number })?.status | ||
| if (status === 404) { | ||
| return false | ||
| } | ||
| console.error( | ||
| `[github/install-check] Failed to determine installation for ${owner}/${repo}:`, | ||
| error | ||
| ) | ||
| return false | ||
|
Comment on lines
+25
to
+29
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sanitize error logging to avoid leaking sensitive details Octokit errors can include request metadata. Log only safe fields (status, name, message) instead of the whole error object. Apply this diff: - console.error(
- `[github/install-check] Failed to determine installation for ${owner}/${repo}:`,
- error
- )
+ const err = error as any
+ const message = err?.message ?? "unknown"
+ const name = err?.name ?? "Error"
+ console.error(
+ `[github/install-check] install check failed for ${owner}/${repo}: status=${status} name=${name} message=${message}`
+ )
🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Force Node runtime and dynamic rendering for Octokit call
Without fetch-based signals, Next may attempt static optimization or edge runtime, breaking Octokit or caching the install state. Explicitly pin Node and disable caching.
Apply this diff near the top-level (after imports is fine):
📝 Committable suggestion
🤖 Prompt for AI Agents