Skip to content

Commit 6023ff7

Browse files
CL-1753 | enhance rollback command with deployment status polling and improved error handling
1 parent 343aafd commit 6023ff7

1 file changed

Lines changed: 72 additions & 13 deletions

File tree

src/commands/launch/rollback.ts

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { FlagInput, Flags, cliux as ux } from '@contentstack/cli-utilities';
77

88
import { BaseCommand } from '../../base-command';
99
import {
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

Comments
 (0)