@@ -7,6 +7,7 @@ import { FlagInput, Flags, cliux as ux } from '@contentstack/cli-utilities';
77
88import { BaseCommand } from '../../base-command' ;
99import {
10+ deploymentQuery ,
1011 environmentsQuery ,
1112 latestLiveDeploymentQuery ,
1213 rollbackDeploymentMutation ,
@@ -104,8 +105,9 @@ export default class Rollback extends BaseCommand<typeof Rollback> {
104105 return ;
105106 }
106107
107- await this . apolloClient
108- . mutate ( {
108+ let rolledBack : any ;
109+ try {
110+ const { data } = await this . apolloClient . mutate ( {
109111 mutation : rollbackDeploymentMutation ,
110112 variables : {
111113 input : {
@@ -114,18 +116,75 @@ export default class Rollback extends BaseCommand<typeof Rollback> {
114116 ...( reason ? { reason } : { } ) ,
115117 } ,
116118 } ,
117- } )
118- . then ( ( { data : { deployment : rolledBack } } ) => {
119- ux . print ( '' ) ;
120- ux . print ( chalk . green ( '✔ Instant rollback to a previous deployment is successful.' ) ) ;
121- ux . print ( ` New deployment: ${ chalk . cyan ( rolledBack . uid ) } status: ${ chalk . cyan ( rolledBack . status ) } ` ) ;
122- ux . print ( '' ) ;
123- } )
124- . catch ( ( error ) => {
125- const code = error ?. graphQLErrors ?. [ 0 ] ?. extensions ?. exception ?. name || error ?. message ;
126- this . log ( `Rollback failed. Please try again. (${ code } )` , 'error' ) ;
127- process . exit ( 1 ) ;
128119 } ) ;
120+ rolledBack = data ?. deployment ;
121+ } catch ( error : any ) {
122+ const code = error ?. graphQLErrors ?. [ 0 ] ?. extensions ?. exception ?. name || error ?. message ;
123+ this . log ( `Rollback failed. Please try again. (${ code } )` , 'error' ) ;
124+ process . exit ( 1 ) ;
125+ }
126+
127+ ux . print ( '' ) ;
128+ ux . print (
129+ `Promoting deployment ${ chalk . cyan ( `#${ rolledBack . deploymentNumber } ` ) } `
130+ + chalk . dim ( `(${ rolledBack . uid } )` ) + '…' ,
131+ ) ;
132+
133+ const finalStatus = await this . pollDeploymentStatus ( environment . uid , target . uid ) ;
134+
135+ ux . print ( '' ) ;
136+ if ( finalStatus === 'LIVE' ) {
137+ ux . print ( chalk . green ( '✔ Instant rollback to a previous deployment is successful.' ) ) ;
138+ const label = `${ chalk . cyan ( `#${ rolledBack . deploymentNumber } ` ) } ${ chalk . dim ( `(${ rolledBack . uid } )` ) } ` ;
139+ ux . print ( ` Deployment ${ label } is now ${ chalk . green ( 'LIVE' ) } .` ) ;
140+ } else if ( finalStatus === 'FAILED' || finalStatus === 'CANCELLED' ) {
141+ ux . print ( chalk . red ( `✘ Rollback ended with status: ${ finalStatus } .` ) ) ;
142+ process . exit ( 1 ) ;
143+ } else {
144+ ux . print ( chalk . yellow ( `Rollback is still in progress (status: ${ finalStatus } ).` ) ) ;
145+ ux . print ( chalk . dim ( ' Check the Launch dashboard for the final status.' ) ) ;
146+ }
147+ ux . print ( '' ) ;
148+ }
149+
150+ /**
151+ * @method pollDeploymentStatus - poll the target deployment until it goes LIVE or terminal/timeout
152+ *
153+ * @memberof Rollback
154+ */
155+ async pollDeploymentStatus ( environmentUid : string , deploymentUid : string ) : Promise < string > {
156+ const intervalMs = 3000 ;
157+ const timeoutMs = 90000 ;
158+ const start = Date . now ( ) ;
159+ const terminal = new Set ( [ 'LIVE' , 'FAILED' , 'CANCELLED' ] ) ;
160+
161+ while ( Date . now ( ) - start < timeoutMs ) {
162+ try {
163+ const { data } = await this . apolloClient . query ( {
164+ query : deploymentQuery ,
165+ variables : { query : { environment : environmentUid , uid : deploymentUid } } ,
166+ fetchPolicy : 'no-cache' ,
167+ } ) ;
168+ const status = data ?. Deployment ?. status ;
169+ if ( status && terminal . has ( status ) ) {
170+ return status ;
171+ }
172+ } catch ( error : any ) {
173+ this . log ( `Failed to fetch deployment status: ${ error ?. message } ` , 'warn' ) ;
174+ }
175+ await new Promise ( ( resolve ) => setTimeout ( resolve , intervalMs ) ) ;
176+ }
177+
178+ try {
179+ const { data } = await this . apolloClient . query ( {
180+ query : deploymentQuery ,
181+ variables : { query : { environment : environmentUid , uid : deploymentUid } } ,
182+ fetchPolicy : 'no-cache' ,
183+ } ) ;
184+ return data ?. Deployment ?. status || 'UNKNOWN' ;
185+ } catch {
186+ return 'UNKNOWN' ;
187+ }
129188 }
130189
131190 /**
0 commit comments