Skip to content

Commit 56de5e1

Browse files
authored
feat(cli): control progress output style with --progress=bar|events (#9623)
Since the new deployment monitoring has been problematic on environments such as CI, adding a switch called `progress` to allow users to set their deploy output display preference. Supported values are `bar` and `events`. The default deployment display mode includes the progress bar. The workaround of adding `-v` to display the stack event history includes a lot of undesired output and users have expressed that it includes a lot of noise. If the key `progress` exists in user settings (`~/.cdk.json`) or project settings (`cdk.json`), users will not need to specify it on every deploy and can set their desired default once. closes #8696 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 2cd3ea2 commit 56de5e1

File tree

7 files changed

+89
-3
lines changed

7 files changed

+89
-3
lines changed

packages/aws-cdk/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,33 @@ Example `outputs.json` after deployment of multiple stacks
227227
}
228228
```
229229

230+
##### Deployment Progress
231+
232+
By default, stack deployment events are displayed as a progress bar with the events for the resource
233+
currently being deployed.
234+
235+
Set the `--progress` flag to request the complete history which includes all CloudFormation events
236+
```console
237+
$ cdk deploy --progress events
238+
```
239+
240+
Alternatively, the `progress` key can be specified in the project config (`cdk.json`).
241+
242+
The following shows a sample `cdk.json` where the `progress` key is set to *events*.
243+
When `cdk deploy` is executed, deployment events will include the complete history.
244+
```
245+
{
246+
"app": "npx ts-node bin/myproject.ts",
247+
"context": {
248+
"@aws-cdk/core:enableStackNameDuplicates": "true",
249+
"aws-cdk:enableDiffNoFail": "true",
250+
"@aws-cdk/core:stackRelativeExports": "true"
251+
},
252+
"progress": "events"
253+
}
254+
```
255+
The `progress` key can also be specified as a user setting (`~/.cdk.json`)
256+
230257
#### `cdk destroy`
231258
Deletes a stack from it's environment. This will cause the resources in the stack to be destroyed (unless they were
232259
configured with a `DeletionPolicy` of `Retain`). During the stack destruction, the command will output progress

packages/aws-cdk/bin/cdk.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { SdkProvider } from '../lib/api/aws-auth';
1010
import { CloudFormationDeployments } from '../lib/api/cloudformation-deployments';
1111
import { CloudExecutable } from '../lib/api/cxapp/cloud-executable';
1212
import { execProgram } from '../lib/api/cxapp/exec';
13+
import { StackActivityProgress } from '../lib/api/util/cloudformation/stack-activity-monitor';
1314
import { CdkToolkit } from '../lib/cdk-toolkit';
1415
import { RequireApproval } from '../lib/diff';
1516
import { availableInitLanguages, cliInit, printAvailableTemplates } from '../lib/init';
@@ -89,7 +90,8 @@ async function parseCommandLineArguments() {
8990
.option('force', { alias: 'f', type: 'boolean', desc: 'Always deploy stack even if templates are identical', default: false })
9091
.option('parameters', { type: 'array', desc: 'Additional parameters passed to CloudFormation at deploy time (STACK:KEY=VALUE)', nargs: 1, requiresArg: true, default: {} })
9192
.option('outputs-file', { type: 'string', alias: 'O', desc: 'Path to file where stack outputs will be written as JSON', requiresArg: true })
92-
.option('previous-parameters', { type: 'boolean', default: true, desc: 'Use previous values for existing parameters (you must specify all parameters on every deployment if this is disabled)' }),
93+
.option('previous-parameters', { type: 'boolean', default: true, desc: 'Use previous values for existing parameters (you must specify all parameters on every deployment if this is disabled)' })
94+
.option('progress', { type: 'string', choices: [StackActivityProgress.BAR, StackActivityProgress.EVENTS], desc: 'Display mode for stack activity events.' }),
9395
)
9496
.command('destroy [STACKS..]', 'Destroy the stack(s) named STACKS', yargs => yargs
9597
.option('exclusively', { type: 'boolean', alias: 'e', desc: 'Only destroy requested stacks, don\'t include dependees' })
@@ -279,6 +281,7 @@ async function initCommandLine() {
279281
parameters: parameterMap,
280282
usePreviousParameters: args['previous-parameters'],
281283
outputsFile: args.outputsFile,
284+
progress: configuration.settings.get(['progress']),
282285
ci: args.ci,
283286
});
284287

packages/aws-cdk/lib/api/cloudformation-deployments.ts

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Mode, SdkProvider } from './aws-auth';
77
import { deployStack, DeployStackResult, destroyStack } from './deploy-stack';
88
import { ToolkitInfo } from './toolkit-info';
99
import { CloudFormationStack, Template } from './util/cloudformation';
10+
import { StackActivityProgress } from './util/cloudformation/stack-activity-monitor';
1011

1112
export interface DeployStackOptions {
1213
/**
@@ -89,6 +90,14 @@ export interface DeployStackOptions {
8990
*/
9091
usePreviousParameters?: boolean;
9192

93+
/**
94+
* Display mode for stack deployment progress.
95+
*
96+
* @default - StackActivityProgress.Bar - stack events will be displayed for
97+
* the resource currently being deployed.
98+
*/
99+
progress?: StackActivityProgress;
100+
92101
/**
93102
* Whether we are on a CI system
94103
*
@@ -163,6 +172,7 @@ export class CloudFormationDeployments {
163172
force: options.force,
164173
parameters: options.parameters,
165174
usePreviousParameters: options.usePreviousParameters,
175+
progress: options.progress,
166176
ci: options.ci,
167177
});
168178
}

packages/aws-cdk/lib/api/deploy-stack.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { contentHash } from '../util/content-hash';
1111
import { ISDK, SdkProvider } from './aws-auth';
1212
import { ToolkitInfo } from './toolkit-info';
1313
import { changeSetHasNoChanges, CloudFormationStack, StackParameters, TemplateParameters, waitForChangeSet, waitForStackDeploy, waitForStackDelete } from './util/cloudformation';
14-
import { StackActivityMonitor } from './util/cloudformation/stack-activity-monitor';
14+
import { StackActivityMonitor, StackActivityProgress } from './util/cloudformation/stack-activity-monitor';
1515

1616
// We need to map regions to domain suffixes, and the SDK already has a function to do this.
1717
// It's not part of the public API, but it's also unlikely to go away.
@@ -153,6 +153,14 @@ export interface DeployStackOptions {
153153
*/
154154
usePreviousParameters?: boolean;
155155

156+
/**
157+
* Display mode for stack deployment progress.
158+
*
159+
* @default StackActivityProgress.Bar stack events will be displayed for
160+
* the resource currently being deployed.
161+
*/
162+
progress?: StackActivityProgress;
163+
156164
/**
157165
* Deploy even if the deployed template is identical to the one we are about to deploy.
158166
* @default false
@@ -267,6 +275,7 @@ export async function deployStack(options: DeployStackOptions): Promise<DeploySt
267275
// eslint-disable-next-line max-len
268276
const monitor = options.quiet ? undefined : StackActivityMonitor.withDefaultPrinter(cfn, deployName, stackArtifact, {
269277
resourcesTotal: (changeSetDescription.Changes ?? []).length,
278+
progress: options.progress,
270279
changeSetCreationTime: changeSetDescription.CreationTime,
271280
}).start();
272281
debug('Execution of changeset %s on stack %s has started; waiting for the update to complete...', changeSetName, deployName);

packages/aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.ts

+27-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@ export interface ResourceMetadata {
1616
constructPath: string;
1717
}
1818

19+
/**
20+
* Supported display modes for stack deployment activity
21+
*/
22+
export enum StackActivityProgress {
23+
/**
24+
* Displays a progress bar with only the events for the resource currently being deployed
25+
*/
26+
BAR = 'bar',
27+
28+
/**
29+
* Displays complete history with all CloudFormation stack events
30+
*/
31+
EVENTS = 'events',
32+
}
33+
1934
export interface WithDefaultPrinterProps {
2035
/**
2136
* Total number of resources to update
@@ -35,6 +50,16 @@ export interface WithDefaultPrinterProps {
3550
*/
3651
readonly logLevel?: LogLevel;
3752

53+
/**
54+
* Whether to display all stack events or to display only the events for the
55+
* resource currently being deployed
56+
*
57+
* If not set, the stack history with all stack events will be displayed
58+
*
59+
* @default false
60+
*/
61+
progress?: StackActivityProgress;
62+
3863
/**
3964
* Whether we are on a CI system
4065
*
@@ -81,8 +106,9 @@ export class StackActivityMonitor {
81106
// need an individual check for whether we're running on CI.
82107
// see: https://discuss.circleci.com/t/circleci-terminal-is-a-tty-but-term-is-not-set/9965
83108
const fancyOutputAvailable = !isWindows && stream.isTTY && !options.ci;
109+
const progress = options.progress ?? StackActivityProgress.BAR;
84110

85-
const printer = fancyOutputAvailable && !verbose
111+
const printer = fancyOutputAvailable && !verbose && (progress === StackActivityProgress.BAR)
86112
? new CurrentActivityPrinter(props)
87113
: new HistoryActivityPrinter(props);
88114

packages/aws-cdk/lib/cdk-toolkit.ts

+10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { bootstrapEnvironment2, BootstrappingParameters } from './api/bootstrap'
1212
import { CloudFormationDeployments } from './api/cloudformation-deployments';
1313
import { CloudAssembly, DefaultSelection, ExtendedStackSelection, StackCollection } from './api/cxapp/cloud-assembly';
1414
import { CloudExecutable } from './api/cxapp/cloud-executable';
15+
import { StackActivityProgress } from './api/util/cloudformation/stack-activity-monitor';
1516
import { printSecurityDiff, printStackDiff, RequireApproval } from './diff';
1617
import { data, error, highlight, print, success, warning } from './logging';
1718
import { deserializeStructure } from './serialize';
@@ -190,6 +191,7 @@ export class CdkToolkit {
190191
force: options.force,
191192
parameters: Object.assign({}, parameterMap['*'], parameterMap[stack.stackName]),
192193
usePreviousParameters: options.usePreviousParameters,
194+
progress: options.progress,
193195
ci: options.ci,
194196
});
195197

@@ -579,6 +581,14 @@ export interface DeployOptions {
579581
*/
580582
usePreviousParameters?: boolean;
581583

584+
/**
585+
* Display mode for stack deployment progress.
586+
*
587+
* @default - StackActivityProgress.Bar - stack events will be displayed for
588+
* the resource currently being deployed.
589+
*/
590+
progress?: StackActivityProgress;
591+
582592
/**
583593
* Path to file where stack outputs will be written after a successful deploy as JSON
584594
* @default - Outputs are not written to any file

packages/aws-cdk/lib/settings.ts

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export class Settings {
204204
versionReporting: argv.versionReporting,
205205
staging: argv.staging,
206206
output: argv.output,
207+
progress: argv.progress,
207208
});
208209
}
209210

0 commit comments

Comments
 (0)