Skip to content

Commit 9147c77

Browse files
committed
feat: app-scoped GitHub repo connections in dashboard
TRPC routes now query via app's githubRepoConnection instead of project. selectRepository accepts appId, disconnectRepo deletes by appId. Project list JOIN changed to apps.id = githubRepoConnections.appId.
1 parent 66384ed commit 9147c77

File tree

5 files changed

+53
-29
lines changed

5 files changed

+53
-29
lines changed

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/build-settings/github-settings/github-connected.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import { SelectedConfig } from "../../shared/selected-config";
44
import { GitHubSettingCard, ManageGitHubAppLink, RepoNameLabel } from "./shared";
55

66
export const GitHubConnected = ({
7-
projectId,
7+
appId,
88
installUrl,
99
repoFullName,
1010
}: {
11-
projectId: string;
11+
appId: string;
1212
installUrl: string;
1313
repoFullName: string;
1414
}) => {
@@ -47,7 +47,7 @@ export const GitHubConnected = ({
4747
className="px-3 rounded-lg"
4848
variant="primary"
4949
color="danger"
50-
onClick={() => disconnectRepoMutation.mutate({ projectId })}
50+
onClick={() => disconnectRepoMutation.mutate({ appId })}
5151
loading={disconnectRepoMutation.isLoading}
5252
>
5353
Disconnect

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/build-settings/github-settings/github-no-repo.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import { ComboboxSkeleton, GitHubSettingCard, ManageGitHubAppLink, RepoNameLabel
66

77
export const GitHubNoRepo = ({
88
projectId,
9+
appId,
910
installUrl,
1011
}: {
1112
projectId: string;
13+
appId: string;
1214
installUrl: string;
1315
}) => {
1416
const utils = trpc.useUtils();
@@ -52,6 +54,7 @@ export const GitHubNoRepo = ({
5254
}
5355
selectRepoMutation.mutate({
5456
projectId,
57+
appId,
5558
repositoryId: repo.id,
5659
repositoryFullName: repo.fullName,
5760
installationId: repo.installationId,

web/apps/dashboard/app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/settings/components/build-settings/github-settings/index.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { ComboboxSkeleton, GitHubSettingCard, ManageGitHubAppLink } from "./shar
99
type GitHubConnectionState =
1010
| { status: "loading" }
1111
| { status: "no-app"; installUrl: string }
12-
| { status: "no-repo"; installUrl: string }
13-
| { status: "connected"; repoFullName: string; repositoryId: number; installUrl: string };
12+
| { status: "no-repo"; appId: string; installUrl: string }
13+
| { status: "connected"; appId: string; repoFullName: string; repositoryId: number; installUrl: string };
1414

1515
export const GitHubSettings = () => {
1616
const { projectId } = useProjectData();
@@ -31,12 +31,16 @@ export const GitHubSettings = () => {
3131
if (!hasInstallations) {
3232
return { status: "no-app", installUrl };
3333
}
34+
const appId = data?.appId;
35+
if (!appId) {
36+
return { status: "no-app", installUrl };
37+
}
3438
const repoFullName = data?.repoConnection?.repositoryFullName;
3539
if (repoFullName) {
3640
const repositoryId = data?.repoConnection?.repositoryId ?? 0;
37-
return { status: "connected", repoFullName, repositoryId, installUrl };
41+
return { status: "connected", appId, repoFullName, repositoryId, installUrl };
3842
}
39-
return { status: "no-repo", installUrl };
43+
return { status: "no-repo", appId, installUrl };
4044
})();
4145

4246
switch (connectionState.status) {
@@ -59,11 +63,11 @@ export const GitHubSettings = () => {
5963
);
6064
// User connected to unkey, but haven't selected a repo yet
6165
case "no-repo":
62-
return <GitHubNoRepo projectId={projectId} installUrl={connectionState.installUrl} />;
66+
return <GitHubNoRepo projectId={projectId} appId={connectionState.appId} installUrl={connectionState.installUrl} />;
6367
case "connected":
6468
return (
6569
<GitHubConnected
66-
projectId={projectId}
70+
appId={connectionState.appId}
6771
installUrl={connectionState.installUrl}
6872
repoFullName={connectionState.repoFullName}
6973
/>

web/apps/dashboard/lib/trpc/routers/deploy/project/list.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Project } from "@/lib/collections/deploy/projects";
22
import { db, sql } from "@/lib/db";
33
import { ratelimit, withRatelimit, workspaceProcedure } from "@/lib/trpc/trpc";
44
import {
5+
apps,
56
deployments,
67
frontlineRoutes,
78
githubRepoConnections,
@@ -34,8 +35,8 @@ export const listProjects = workspaceProcedure
3435
${projects.slug},
3536
${projects.updatedAt},
3637
${githubRepoConnections.repositoryFullName},
37-
${projects.liveDeploymentId},
38-
${projects.isRolledBack},
38+
${apps.liveDeploymentId},
39+
${apps.isRolledBack},
3940
${deployments.gitCommitMessage},
4041
${deployments.gitBranch},
4142
${deployments.gitCommitAuthorHandle},
@@ -51,13 +52,16 @@ export const listProjects = workspaceProcedure
5152
LIMIT 1
5253
) as latest_deployment_id
5354
FROM ${projects}
55+
LEFT JOIN ${apps}
56+
ON ${apps.projectId} = ${projects.id}
57+
AND ${apps.slug} = 'default'
5458
LEFT JOIN ${deployments}
55-
ON ${projects.liveDeploymentId} = ${deployments.id}
59+
ON ${apps.liveDeploymentId} = ${deployments.id}
5660
AND ${deployments.workspaceId} = ${ctx.workspace.id}
5761
LEFT JOIN ${frontlineRoutes}
5862
ON ${projects.id} = ${frontlineRoutes.projectId}
5963
LEFT JOIN ${githubRepoConnections}
60-
ON ${projects.id} = ${githubRepoConnections.projectId}
64+
ON ${apps.id} = ${githubRepoConnections.appId}
6165
WHERE ${projects.workspaceId} = ${ctx.workspace.id}
6266
ORDER BY ${projects.updatedAt} DESC
6367
`);

web/apps/dashboard/lib/trpc/routers/github.ts

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,19 @@ const fetchGithubContext = async (workspaceId: string, projectId: string) => {
1818
id: true,
1919
},
2020
with: {
21-
githubRepoConnection: {
22-
columns: {
23-
pk: true,
24-
repositoryId: true,
25-
repositoryFullName: true,
21+
apps: {
22+
where: (table, { eq }) => eq(table.slug, "default"),
23+
columns: { id: true },
24+
with: {
25+
githubRepoConnection: {
26+
columns: {
27+
pk: true,
28+
repositoryId: true,
29+
repositoryFullName: true,
30+
},
31+
},
2632
},
33+
limit: 1,
2734
},
2835
workspace: {
2936
columns: {
@@ -51,12 +58,15 @@ const fetchGithubContext = async (workspaceId: string, projectId: string) => {
5158
return null;
5259
}
5360

61+
const defaultApp = project.apps[0] ?? null;
62+
5463
return {
55-
repoConnection: project.githubRepoConnection
64+
appId: defaultApp?.id ?? null,
65+
repoConnection: defaultApp?.githubRepoConnection
5666
? {
57-
pk: project.githubRepoConnection.pk,
58-
repositoryId: project.githubRepoConnection.repositoryId,
59-
repositoryFullName: project.githubRepoConnection.repositoryFullName,
67+
pk: defaultApp.githubRepoConnection.pk,
68+
repositoryId: defaultApp.githubRepoConnection.repositoryId,
69+
repositoryFullName: defaultApp.githubRepoConnection.repositoryFullName,
6070
}
6171
: null,
6272
installations: project.workspace?.githubAppInstallations ?? [],
@@ -200,6 +210,7 @@ export const githubRouter = t.router({
200210
}
201211

202212
return {
213+
appId: githubContext.appId,
203214
installations: githubContext.installations,
204215
repoConnection: githubContext.repoConnection,
205216
};
@@ -266,6 +277,7 @@ export const githubRouter = t.router({
266277
.input(
267278
z.object({
268279
projectId: z.string(),
280+
appId: z.string(),
269281
repositoryId: z.number().int(),
270282
repositoryFullName: z.string(),
271283
installationId: z.number().int(),
@@ -312,6 +324,7 @@ export const githubRouter = t.router({
312324
.insert(schema.githubRepoConnections)
313325
.values({
314326
projectId: input.projectId,
327+
appId: input.appId,
315328
installationId: input.installationId,
316329
repositoryId: verifiedRepo.id,
317330
repositoryFullName: verifiedRepo.full_name,
@@ -339,32 +352,32 @@ export const githubRouter = t.router({
339352
disconnectRepo: workspaceProcedure
340353
.input(
341354
z.object({
342-
projectId: z.string(),
355+
appId: z.string(),
343356
}),
344357
)
345358
.mutation(async ({ ctx, input }) => {
346-
const project = await db.query.projects
359+
const app = await db.query.apps
347360
.findFirst({
348361
where: (table, { and, eq }) =>
349-
and(eq(table.id, input.projectId), eq(table.workspaceId, ctx.workspace.id)),
362+
and(eq(table.id, input.appId), eq(table.workspaceId, ctx.workspace.id)),
350363
})
351364
.catch(() => {
352365
throw new TRPCError({
353366
code: "INTERNAL_SERVER_ERROR",
354-
message: "Failed to load project",
367+
message: "Failed to load app",
355368
});
356369
});
357370

358-
if (!project) {
371+
if (!app) {
359372
throw new TRPCError({
360373
code: "NOT_FOUND",
361-
message: "Project not found",
374+
message: "App not found",
362375
});
363376
}
364377

365378
await db
366379
.delete(schema.githubRepoConnections)
367-
.where(eq(schema.githubRepoConnections.projectId, input.projectId))
380+
.where(eq(schema.githubRepoConnections.appId, input.appId))
368381
.catch(() => {
369382
throw new TRPCError({
370383
code: "INTERNAL_SERVER_ERROR",

0 commit comments

Comments
 (0)