@@ -19,6 +19,9 @@ pub struct DeployOpts<'a> {
1919 pub filter_tags : Option < HashMap < String , String > > ,
2020 pub build_tags : Option < HashMap < String , String > > ,
2121 pub version : Option < String > ,
22+ pub skip_route_creation : Option < bool > ,
23+ pub keep_existing_routes : Option < bool > ,
24+ pub non_interactive : bool ,
2225}
2326
2427pub async fn deploy ( opts : DeployOpts < ' _ > ) -> Result < Vec < Uuid > > {
@@ -65,7 +68,16 @@ pub async fn deploy(opts: DeployOpts<'_>) -> Result<Vec<Uuid>> {
6568 . await ?;
6669
6770 // Setup function routes
68- setup_function_routes ( opts. ctx , environment, & config, & opts. filter_tags ) . await ?;
71+ setup_function_routes (
72+ opts. ctx ,
73+ environment,
74+ & config,
75+ & opts. filter_tags ,
76+ opts. skip_route_creation ,
77+ opts. keep_existing_routes ,
78+ opts. non_interactive ,
79+ )
80+ . await ?;
6981
7082 // Print summary
7183 print_summary ( opts. ctx , environment) ;
@@ -78,20 +90,23 @@ async fn setup_function_routes(
7890 environment : & toolchain:: project:: environment:: TEMPEnvironment ,
7991 config : & config:: Config ,
8092 filter_tags : & Option < HashMap < String , String > > ,
93+ skip_route_creation : Option < bool > ,
94+ keep_existing_routes : Option < bool > ,
95+ non_interactive : bool ,
8196) -> Result < ( ) > {
82- // Determine default hostname based on project & env
83- let default_hostname = format ! (
84- "{}-{}.{}" ,
85- ctx. project. name_id,
86- environment. slug,
87- ctx. bootstrap
88- . domains
89- . job
90- . as_ref( )
91- . context( "bootstrap.domains.job" ) ?
92- ) ;
93-
9497 for ( fn_name, function) in & config. functions {
98+ // Determine default hostname based on project & env
99+ let default_hostname = format ! (
100+ "{}-{}-{fn_name}.{}" ,
101+ ctx. project. name_id,
102+ environment. slug,
103+ ctx. bootstrap
104+ . domains
105+ . job
106+ . as_ref( )
107+ . context( "bootstrap.domains.job" ) ?
108+ ) ;
109+
95110 // TODO: Convert this in to a shared fn
96111 // Filter out builds that match the tags
97112 if let Some ( filter) = & filter_tags {
@@ -190,19 +205,40 @@ async fn setup_function_routes(
190205 ] ;
191206
192207 println ! ( ) ;
193- let choice = block_in_place ( || {
194- Select :: new (
195- & format ! (
196- "Route configuration for '{fn_name}' has changed{}" ,
197- changes_text
198- ) ,
199- options. to_vec ( ) ,
200- )
201- . with_starting_cursor ( 0 )
202- . prompt ( )
203- } ) ?;
204208
205- match choice. index {
209+ let choice_index = if non_interactive {
210+ // In non-interactive mode, use auto_sync_routes if provided, otherwise sync by default
211+ match keep_existing_routes {
212+ Some ( true ) => {
213+ println ! ( "Skipping route sync for '{fn_name}' (non-interactive mode)" ) ;
214+ 1 // Keep existing route
215+ }
216+ Some ( false ) => {
217+ println ! ( "Auto-syncing route configuration for '{fn_name}' (non-interactive mode)" ) ;
218+ 0 // Sync route with config
219+ }
220+ None => {
221+ println ! ( "Auto-syncing route configuration for '{fn_name}' (non-interactive mode)" ) ;
222+ 0 // Default to sync in non-interactive mode
223+ }
224+ }
225+ } else {
226+ // Interactive mode - prompt the user
227+ let choice = block_in_place ( || {
228+ Select :: new (
229+ & format ! (
230+ "Route configuration for '{fn_name}' has changed{}" ,
231+ changes_text
232+ ) ,
233+ options. to_vec ( ) ,
234+ )
235+ . with_starting_cursor ( 0 )
236+ . prompt ( )
237+ } ) ?;
238+ choice. index
239+ } ;
240+
241+ match choice_index {
206242 0 => {
207243 // Update first matching route to match config
208244 let mut update_route_body = models:: RoutesUpdateRouteBody {
@@ -268,17 +304,42 @@ async fn setup_function_routes(
268304 ] ;
269305
270306 println ! ( ) ;
271- let choice = block_in_place ( || {
272- Select :: new (
273- & format ! ( "Set up routing for function '{}':" , fn_name) ,
274- options. to_vec ( ) ,
275- )
276- . with_help_message ( "Routes can be manually created in the Rivet dashboard" )
277- . with_starting_cursor ( 0 )
278- . prompt ( )
279- } ) ?;
280-
281- match choice. index {
307+
308+ let choice_index = if non_interactive {
309+ // In non-interactive mode, use auto_create_routes if provided, otherwise create by default
310+ match skip_route_creation {
311+ Some ( true ) => {
312+ println ! ( "Skipping route creation for '{fn_name}' (non-interactive mode)" ) ;
313+ 1 // Skip route creation
314+ }
315+ Some ( false ) => {
316+ println ! (
317+ "Auto-creating route for function '{fn_name}' (non-interactive mode)"
318+ ) ;
319+ 0 // Create default route
320+ }
321+ None => {
322+ println ! (
323+ "Auto-creating route for function '{fn_name}' (non-interactive mode)"
324+ ) ;
325+ 0 // Default to create in non-interactive mode
326+ }
327+ }
328+ } else {
329+ // Interactive mode - prompt the user
330+ let choice = block_in_place ( || {
331+ Select :: new (
332+ & format ! ( "Set up routing for function '{}':" , fn_name) ,
333+ options. to_vec ( ) ,
334+ )
335+ . with_help_message ( "Routes can be manually created in the Rivet dashboard" )
336+ . with_starting_cursor ( 0 )
337+ . prompt ( )
338+ } ) ?;
339+ choice. index
340+ } ;
341+
342+ match choice_index {
282343 0 => {
283344 // Create route with default settings
284345 create_function_route (
0 commit comments