@@ -75,7 +75,9 @@ import {
75
75
import { GitBranchIcon } from "lucide-react" ;
76
76
import { env } from "~/env.server" ;
77
77
import { useEnvironment } from "~/hooks/useEnvironment" ;
78
- import { DateTime , DateTimeShort } from "~/components/primitives/DateTime" ;
78
+ import { DateTime } from "~/components/primitives/DateTime" ;
79
+ import { checkGitHubBranchExists } from "~/services/gitHub.server" ;
80
+ import { tryCatch } from "@trigger.dev/core" ;
79
81
80
82
export const meta : MetaFunction = ( ) => {
81
83
return [
@@ -163,7 +165,7 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
163
165
// Most installations will only have a couple of repos so loading them here should be fine.
164
166
// However, there might be outlier organizations so it's best to expose the installation repos
165
167
// via a resource endpoint and filter on user input.
166
- take : 100 ,
168
+ take : 200 ,
167
169
} ,
168
170
} ,
169
171
take : 20 ,
@@ -187,8 +189,8 @@ const ConnectGitHubRepoFormSchema = z.object({
187
189
188
190
const UpdateGitSettingsFormSchema = z . object ( {
189
191
action : z . literal ( "update-git-settings" ) ,
190
- productionBranch : z . string ( ) . optional ( ) ,
191
- stagingBranch : z . string ( ) . optional ( ) ,
192
+ productionBranch : z . string ( ) . trim ( ) . optional ( ) ,
193
+ stagingBranch : z . string ( ) . trim ( ) . optional ( ) ,
192
194
previewDeploymentsEnabled : z
193
195
. string ( )
194
196
. optional ( )
@@ -333,12 +335,57 @@ export const action: ActionFunction = async ({ request, params }) => {
333
335
where : {
334
336
projectId : project . id ,
335
337
} ,
338
+ include : {
339
+ repository : {
340
+ include : {
341
+ installation : true ,
342
+ } ,
343
+ } ,
344
+ } ,
336
345
} ) ;
337
346
338
347
if ( ! existingConnection ) {
339
348
return redirectBackWithErrorMessage ( request , "No connected GitHub repository found" ) ;
340
349
}
341
350
351
+ const [ owner , repo ] = existingConnection . repository . fullName . split ( "/" ) ;
352
+ const installationId = Number ( existingConnection . repository . installation . appInstallationId ) ;
353
+
354
+ const existingBranchTracking = BranchTrackingConfigSchema . safeParse (
355
+ existingConnection . branchTracking
356
+ ) ;
357
+
358
+ const [ error , branchValidationsOrFail ] = await tryCatch (
359
+ Promise . all ( [
360
+ productionBranch && existingBranchTracking . data ?. production ?. branch !== productionBranch
361
+ ? checkGitHubBranchExists ( installationId , owner , repo , productionBranch )
362
+ : Promise . resolve ( true ) ,
363
+ stagingBranch && existingBranchTracking . data ?. staging ?. branch !== stagingBranch
364
+ ? checkGitHubBranchExists ( installationId , owner , repo , stagingBranch )
365
+ : Promise . resolve ( true ) ,
366
+ ] )
367
+ ) ;
368
+
369
+ if ( error ) {
370
+ return redirectBackWithErrorMessage ( request , "Failed to validate tracking branches" ) ;
371
+ }
372
+
373
+ const [ productionBranchExists , stagingBranchExists ] = branchValidationsOrFail ;
374
+
375
+ if ( productionBranch && ! productionBranchExists ) {
376
+ return redirectBackWithErrorMessage (
377
+ request ,
378
+ `Production tracking branch '${ productionBranch } ' does not exist in the repository`
379
+ ) ;
380
+ }
381
+
382
+ if ( stagingBranch && ! stagingBranchExists ) {
383
+ return redirectBackWithErrorMessage (
384
+ request ,
385
+ `Staging tracking branch '${ stagingBranch } ' does not exist in the repository`
386
+ ) ;
387
+ }
388
+
342
389
await prisma . connectedGithubRepository . update ( {
343
390
where : {
344
391
projectId : project . id ,
0 commit comments