@@ -28,6 +28,7 @@ export type BuildCommandArgs = {
2828 path ?: string ;
2929 alias ?: string ;
3030 ports ?: number [ ] ;
31+ ci : boolean ;
3132 fromSandbox ?: string ;
3233 skipFiles ?: boolean ;
3334 vmTier ?: VmUpdateSpecsRequest [ "tier" ] ;
@@ -71,6 +72,11 @@ export const buildCommand: yargs.CommandModule<
7172 "Alias that should point to the created template. Alias namespace defaults to template directory, but you can explicitly pass `namespace@alias`" ,
7273 type : "string" ,
7374 } )
75+ . option ( "ci" , {
76+ describe : "CI mode, will exit process if any error occurs" ,
77+ default : false ,
78+ type : "boolean" ,
79+ } )
7480 . positional ( "directory" , {
7581 describe : "Path to the project that we'll create a snapshot from" ,
7682 type : "string" ,
@@ -166,8 +172,8 @@ export const buildCommand: yargs.CommandModule<
166172 } )
167173 ) ;
168174
169- const results = await Promise . allSettled (
170- sandboxes . map ( async ( { sandboxId, filePaths, cluster } , index ) => {
175+ const tasks = sandboxes . map (
176+ async ( { sandboxId, filePaths, cluster } , index ) => {
171177 const clusterApiClient : Client = createClient (
172178 createConfig ( {
173179 baseUrl : BASE_URL ,
@@ -199,14 +205,18 @@ export const buildCommand: yargs.CommandModule<
199205 `${ baseUrl } /api/v1/cluster/${ sandboxId } ?preferredManager=${ cluster } `
200206 ) . then ( ( res ) => res . json ( ) ) ;
201207
202- const startResponse = await startVm ( clusterApiClient , sandboxId , {
203- vmTier : VMTier . fromName ( "Micro" ) ,
204- } ) ;
208+ const startResponse = await withCustomError (
209+ startVm ( clusterApiClient , sandboxId , {
210+ vmTier : VMTier . fromName ( "Micro" ) ,
211+ } ) ,
212+ "Failed to start sandbox"
213+ ) ;
205214 let sandbox = new Sandbox (
206215 sandboxId ,
207216 clusterApiClient ,
208217 startResponse
209218 ) ;
219+
210220 let session = await sandbox . connect ( ) ;
211221
212222 spinner . start (
@@ -216,29 +226,39 @@ export const buildCommand: yargs.CommandModule<
216226 sandboxId
217227 )
218228 ) ;
219- let i = 0 ;
220- for ( const filePath of filePaths ) {
221- i ++ ;
222- const fullPath = path . join ( argv . directory , filePath ) ;
223- const content = await fs . readFile ( fullPath ) ;
224- const dirname = path . dirname ( filePath ) ;
225- await session . fs . mkdir ( dirname , true ) ;
226- await session . fs . writeFile ( filePath , content , {
227- create : true ,
228- overwrite : true ,
229- } ) ;
229+ try {
230+ let i = 0 ;
231+ for ( const filePath of filePaths ) {
232+ i ++ ;
233+ const fullPath = path . join ( argv . directory , filePath ) ;
234+ const content = await fs . readFile ( fullPath ) ;
235+ const dirname = path . dirname ( filePath ) ;
236+ await session . fs . mkdir ( dirname , true ) ;
237+ await session . fs . writeFile ( filePath , content , {
238+ create : true ,
239+ overwrite : true ,
240+ } ) ;
241+ }
242+ } catch ( error ) {
243+ throw new Error ( `Failed to write files to sandbox: ${ error } ` ) ;
230244 }
231245
232246 spinner . start (
233247 updateSpinnerMessage ( index , "Restarting sandbox..." , sandboxId )
234248 ) ;
235- sandbox = await sdk . sandboxes . restart ( sandbox . id , {
236- vmTier : argv . vmTier
237- ? VMTier . fromName ( argv . vmTier )
238- : VMTier . fromName ( "Micro" ) ,
239- } ) ;
249+ sandbox = await withCustomError (
250+ sdk . sandboxes . restart ( sandbox . id , {
251+ vmTier : argv . vmTier
252+ ? VMTier . fromName ( argv . vmTier )
253+ : VMTier . fromName ( "Micro" ) ,
254+ } ) ,
255+ "Failed to restart sandbox"
256+ ) ;
240257
241- session = await sandbox . connect ( ) ;
258+ session = await withCustomError (
259+ sandbox . connect ( ) ,
260+ "Failed to connect to sandbox"
261+ ) ;
242262
243263 const disposableStore = new DisposableStore ( ) ;
244264
@@ -326,7 +346,10 @@ export const buildCommand: yargs.CommandModule<
326346 spinner . start (
327347 updateSpinnerMessage ( index , "Creating snapshot..." , sandboxId )
328348 ) ;
329- await sdk . sandboxes . hibernate ( sandbox . id ) ;
349+ await withCustomError (
350+ sdk . sandboxes . hibernate ( sandbox . id ) ,
351+ "Failed to hibernate"
352+ ) ;
330353 spinner . start (
331354 updateSpinnerMessage ( index , "Snapshot created" , sandboxId )
332355 ) ;
@@ -337,64 +360,73 @@ export const buildCommand: yargs.CommandModule<
337360 updateSpinnerMessage (
338361 index ,
339362 "Failed, please manually verify at https://codesandbox.io/s/" +
340- sandboxId ,
363+ sandboxId +
364+ " - " +
365+ String ( error ) ,
341366 sandboxId
342367 )
343368 ) ;
344369
345370 throw error ;
346371 }
347- } )
348- ) ;
349-
350- const failedSandboxes = sandboxes . filter (
351- ( _ , index ) => results [ index ] . status === "rejected"
372+ }
352373 ) ;
353374
354- if ( failedSandboxes . length > 0 ) {
355- spinner . info ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
375+ if ( argv . ci ) {
376+ await Promise . all ( tasks ) ;
377+ spinner . succeed ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
378+ } else {
379+ const results = await Promise . allSettled ( tasks ) ;
356380
357- await waitForEnter (
358- `\nThere was an issue preparing the sandboxes. Verify ${ failedSandboxes
359- . map ( ( sandbox ) => sandbox . sandboxId )
360- . join ( ", " ) } and press ENTER to create snapshot...\n`
381+ const failedSandboxes = sandboxes . filter (
382+ ( _ , index ) => results [ index ] . status === "rejected"
361383 ) ;
362384
363- failedSandboxes . forEach ( ( { sandboxId } ) => {
364- updateSpinnerMessage (
365- sandboxes . findIndex ( ( sandbox ) => sandbox . sandboxId === sandboxId ) ,
366- "Creating snapshot..." ,
367- sandboxId
385+ if ( failedSandboxes . length > 0 ) {
386+ spinner . info ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
387+
388+ await waitForEnter (
389+ `\nThere was an issue preparing the sandboxes. Verify ${ failedSandboxes
390+ . map ( ( sandbox ) => sandbox . sandboxId )
391+ . join ( ", " ) } and press ENTER to create snapshot...\n`
368392 ) ;
369- } ) ;
370393
371- spinner . start ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
394+ failedSandboxes . forEach ( ( { sandboxId } ) => {
395+ updateSpinnerMessage (
396+ sandboxes . findIndex ( ( sandbox ) => sandbox . sandboxId === sandboxId ) ,
397+ "Creating snapshot..." ,
398+ sandboxId
399+ ) ;
400+ } ) ;
372401
373- await Promise . all (
374- failedSandboxes . map ( async ( { sandboxId, cluster } ) => {
375- const sdk = new CodeSandbox ( API_KEY , {
376- baseUrl : BASE_URL ,
377- headers : {
378- "x-pitcher-manager-url" : `https://${ cluster } /api/v1` ,
379- } ,
380- } ) ;
402+ spinner . start ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
381403
382- await sdk . sandboxes . hibernate ( sandboxId ) ;
404+ await Promise . all (
405+ failedSandboxes . map ( async ( { sandboxId, cluster } ) => {
406+ const sdk = new CodeSandbox ( API_KEY , {
407+ baseUrl : BASE_URL ,
408+ headers : {
409+ "x-pitcher-manager-url" : `https://${ cluster } /api/v1` ,
410+ } ,
411+ } ) ;
383412
384- spinner . start (
385- updateSpinnerMessage (
386- sandboxes . findIndex (
387- ( sandbox ) => sandbox . sandboxId === sandboxId
388- ) ,
389- "Snapshot created" ,
390- sandboxId
391- )
392- ) ;
393- } )
394- ) ;
395- spinner . succeed ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
396- } else {
397- spinner . succeed ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
413+ await sdk . sandboxes . hibernate ( sandboxId ) ;
414+
415+ spinner . start (
416+ updateSpinnerMessage (
417+ sandboxes . findIndex (
418+ ( sandbox ) => sandbox . sandboxId === sandboxId
419+ ) ,
420+ "Snapshot created" ,
421+ sandboxId
422+ )
423+ ) ;
424+ } )
425+ ) ;
426+ spinner . succeed ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
427+ } else {
428+ spinner . succeed ( `\n${ spinnerMessages . join ( "\n" ) } ` ) ;
429+ }
398430 }
399431
400432 const data = handleResponse (
@@ -444,6 +476,12 @@ type CreateSandboxParams = {
444476 ipcountry ?: string ;
445477} ;
446478
479+ function withCustomError < T extends Promise < any > > ( promise : T , message : string ) {
480+ return promise . catch ( ( error ) => {
481+ throw new Error ( message + ": " + error . message ) ;
482+ } ) ;
483+ }
484+
447485function waitForEnter ( message : string ) {
448486 const rl = readline . createInterface ( {
449487 input : process . stdin ,
0 commit comments