@@ -58,6 +58,7 @@ const GithubProviderSchema = z.object({
5858 branch : z . string ( ) . min ( 1 , "Branch is required" ) ,
5959 githubId : z . string ( ) . min ( 1 , "Github Provider is required" ) ,
6060 watchPaths : z . array ( z . string ( ) ) . optional ( ) ,
61+ triggerType : z . enum ( [ "push" , "tag" ] ) . default ( "push" ) ,
6162 enableSubmodules : z . boolean ( ) . default ( false ) ,
6263} ) ;
6364
@@ -83,13 +84,15 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
8384 } ,
8485 githubId : "" ,
8586 branch : "" ,
87+ triggerType : "push" ,
8688 enableSubmodules : false ,
8789 } ,
8890 resolver : zodResolver ( GithubProviderSchema ) ,
8991 } ) ;
9092
9193 const repository = form . watch ( "repository" ) ;
9294 const githubId = form . watch ( "githubId" ) ;
95+ const triggerType = form . watch ( "triggerType" ) ;
9396
9497 const { data : repositories , isLoading : isLoadingRepositories } =
9598 api . github . getGithubRepositories . useQuery (
@@ -127,6 +130,7 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
127130 buildPath : data . buildPath || "/" ,
128131 githubId : data . githubId || "" ,
129132 watchPaths : data . watchPaths || [ ] ,
133+ triggerType : data . triggerType || "push" ,
130134 enableSubmodules : data . enableSubmodules ?? false ,
131135 } ) ;
132136 }
@@ -141,6 +145,7 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
141145 buildPath : data . buildPath ,
142146 githubId : data . githubId ,
143147 watchPaths : data . watchPaths || [ ] ,
148+ triggerType : data . triggerType ,
144149 enableSubmodules : data . enableSubmodules ,
145150 } )
146151 . then ( async ( ) => {
@@ -386,83 +391,126 @@ export const SaveGithubProvider = ({ applicationId }: Props) => {
386391 />
387392 < FormField
388393 control = { form . control }
389- name = "watchPaths "
394+ name = "triggerType "
390395 render = { ( { field } ) => (
391396 < FormItem className = "md:col-span-2" >
392- < div className = "flex items-center gap-2" >
393- < FormLabel > Watch Paths </ FormLabel >
397+ < div className = "flex items-center gap-2 " >
398+ < FormLabel > Trigger Type </ FormLabel >
394399 < TooltipProvider >
395400 < Tooltip >
396401 < TooltipTrigger asChild >
397402 < HelpCircle className = "size-4 text-muted-foreground hover:text-foreground transition-colors cursor-pointer" />
398403 </ TooltipTrigger >
399404 < TooltipContent >
400405 < p >
401- Add paths to watch for changes. When files in these
402- paths change, a new deployment will be triggered .
406+ Choose when to trigger deployments: on push to the
407+ selected branch or when a new tag is created .
403408 </ p >
404409 </ TooltipContent >
405410 </ Tooltip >
406411 </ TooltipProvider >
407412 </ div >
408- < div className = "flex flex-wrap gap-2 mb-2" >
409- { field . value ?. map ( ( path , index ) => (
410- < Badge
411- key = { index }
412- variant = "secondary"
413- className = "flex items-center gap-1"
414- >
415- { path }
416- < X
417- className = "size-3 cursor-pointer hover:text-destructive"
418- onClick = { ( ) => {
419- const newPaths = [ ...( field . value || [ ] ) ] ;
420- newPaths . splice ( index , 1 ) ;
421- field . onChange ( newPaths ) ;
422- } }
423- />
424- </ Badge >
425- ) ) }
426- </ div >
427- < div className = "flex gap-2" >
413+ < Select
414+ onValueChange = { field . onChange }
415+ defaultValue = { field . value }
416+ value = { field . value }
417+ >
428418 < FormControl >
429- < Input
430- placeholder = "Enter a path to watch (e.g., src/*, dist/*)"
431- onKeyDown = { ( e ) => {
432- if ( e . key === "Enter" ) {
433- e . preventDefault ( ) ;
434- const input = e . currentTarget ;
435- const path = input . value . trim ( ) ;
436- if ( path ) {
437- field . onChange ( [ ...( field . value || [ ] ) , path ] ) ;
438- input . value = "" ;
439- }
440- }
441- } }
442- />
419+ < SelectTrigger >
420+ < SelectValue placeholder = "Select a trigger type" />
421+ </ SelectTrigger >
443422 </ FormControl >
444- < Button
445- type = "button"
446- variant = "outline"
447- size = "icon"
448- onClick = { ( ) => {
449- const input = document . querySelector (
450- 'input[placeholder*="Enter a path"]' ,
451- ) as HTMLInputElement ;
452- const path = input . value . trim ( ) ;
453- if ( path ) {
454- field . onChange ( [ ...( field . value || [ ] ) , path ] ) ;
455- input . value = "" ;
456- }
457- } }
458- >
459- < Plus className = "size-4" />
460- </ Button >
461- </ div >
423+ < SelectContent >
424+ < SelectItem value = "push" > On Push</ SelectItem >
425+ < SelectItem value = "tag" > On Tag</ SelectItem >
426+ </ SelectContent >
427+ </ Select >
462428 < FormMessage />
463429 </ FormItem >
464430 ) }
465431 />
432+ { triggerType === "push" && (
433+ < FormField
434+ control = { form . control }
435+ name = "watchPaths"
436+ render = { ( { field } ) => (
437+ < FormItem className = "md:col-span-2" >
438+ < div className = "flex items-center gap-2" >
439+ < FormLabel > Watch Paths</ FormLabel >
440+ < TooltipProvider >
441+ < Tooltip >
442+ < TooltipTrigger asChild >
443+ < HelpCircle className = "size-4 text-muted-foreground hover:text-foreground transition-colors cursor-pointer" />
444+ </ TooltipTrigger >
445+ < TooltipContent >
446+ < p >
447+ Add paths to watch for changes. When files in
448+ these paths change, a new deployment will be
449+ triggered.
450+ </ p >
451+ </ TooltipContent >
452+ </ Tooltip >
453+ </ TooltipProvider >
454+ </ div >
455+ < div className = "flex flex-wrap gap-2 mb-2" >
456+ { field . value ?. map ( ( path , index ) => (
457+ < Badge
458+ key = { index }
459+ variant = "secondary"
460+ className = "flex items-center gap-1"
461+ >
462+ { path }
463+ < X
464+ className = "size-3 cursor-pointer hover:text-destructive"
465+ onClick = { ( ) => {
466+ const newPaths = [ ...( field . value || [ ] ) ] ;
467+ newPaths . splice ( index , 1 ) ;
468+ field . onChange ( newPaths ) ;
469+ } }
470+ />
471+ </ Badge >
472+ ) ) }
473+ </ div >
474+ < div className = "flex gap-2" >
475+ < FormControl >
476+ < Input
477+ placeholder = "Enter a path to watch (e.g., src/*, dist/*)"
478+ onKeyDown = { ( e ) => {
479+ if ( e . key === "Enter" ) {
480+ e . preventDefault ( ) ;
481+ const input = e . currentTarget ;
482+ const path = input . value . trim ( ) ;
483+ if ( path ) {
484+ field . onChange ( [ ...( field . value || [ ] ) , path ] ) ;
485+ input . value = "" ;
486+ }
487+ }
488+ } }
489+ />
490+ </ FormControl >
491+ < Button
492+ type = "button"
493+ variant = "outline"
494+ size = "icon"
495+ onClick = { ( ) => {
496+ const input = document . querySelector (
497+ 'input[placeholder*="Enter a path"]' ,
498+ ) as HTMLInputElement ;
499+ const path = input . value . trim ( ) ;
500+ if ( path ) {
501+ field . onChange ( [ ...( field . value || [ ] ) , path ] ) ;
502+ input . value = "" ;
503+ }
504+ } }
505+ >
506+ < Plus className = "size-4" />
507+ </ Button >
508+ </ div >
509+ < FormMessage />
510+ </ FormItem >
511+ ) }
512+ />
513+ ) }
466514
467515 < FormField
468516 control = { form . control }
0 commit comments