diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md index 73260afd299d6..d6e29a2e3e5dc 100644 --- a/packages/aws-cdk/README.md +++ b/packages/aws-cdk/README.md @@ -458,6 +458,15 @@ locally to your terminal. To disable this feature you can pass the `--no-logs` o $ cdk watch --no-logs ``` +You can increase the concurrency by which `watch` will deploy and hotswap +your stacks by specifying `--concurrency N`. `--concurrency` for `watch` +acts the same as `--concurrency` for `deploy`, in that it will deploy or +hotswap your stacks while respecting inter-stack dependencies. + +```console +$ cdk watch --concurrency 5 +``` + **Note**: This command is considered experimental, and might have breaking changes in the future. The same limitations apply to to `watch` deployments as do to `--hotswap` deployments. See the *Hotswap deployments for faster development* section for more information. diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts index fe16041bd979f..93518b4bf6394 100644 --- a/packages/aws-cdk/lib/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cdk-toolkit.ts @@ -737,6 +737,7 @@ export class CdkToolkit { cacheCloudAssembly: false, hotswap: hotswap, extraUserAgent: `cdk-watch/hotswap-${hotswap ? 'on' : 'off'}`, + concurrency: options.concurrency, }; try { @@ -900,6 +901,14 @@ interface WatchOptions extends Omit { * @default - false */ readonly traceLogs?: boolean; + + /** + * Maximum number of simulatenous deployments (dependency permitting) to execute. + * The default is '1', which executes all deployments serially. + * + * @default 1 + */ + readonly concurrency?: number; } export interface DeployOptions extends CfnDeployOptions, WatchOptions { diff --git a/packages/aws-cdk/lib/cli.ts b/packages/aws-cdk/lib/cli.ts index fcb3412a2717f..0de38a1a9b5e0 100644 --- a/packages/aws-cdk/lib/cli.ts +++ b/packages/aws-cdk/lib/cli.ts @@ -216,7 +216,8 @@ async function parseCommandLineArguments() { default: true, desc: 'Show CloudWatch log events from all resources in the selected Stacks in the terminal. ' + "'true' by default, use --no-logs to turn off", - }), + }) + .option('concurrency', { type: 'number', desc: 'Maximum number of simulatenous deployments (dependency permitting) to execute.', default: 1, requiresArg: true }), ) .command('destroy [STACKS..]', 'Destroy the stack(s) named STACKS', (yargs: Argv) => yargs .option('all', { type: 'boolean', default: false, desc: 'Destroy all available stacks' }) @@ -516,6 +517,7 @@ async function initCommandLine() { rollback: configuration.settings.get(['rollback']), hotswap: args.hotswap, traceLogs: args.logs, + concurrency: args.concurrency, }); case 'destroy': diff --git a/packages/aws-cdk/test/cdk-toolkit.test.ts b/packages/aws-cdk/test/cdk-toolkit.test.ts index 341775b08b38a..b0359fbb6dbc7 100644 --- a/packages/aws-cdk/test/cdk-toolkit.test.ts +++ b/packages/aws-cdk/test/cdk-toolkit.test.ts @@ -657,6 +657,18 @@ describe('watch', () => { expect(excludeArgs[1]).toBe('**/my-dir2'); }); + test('allows watching with deploy concurrency', async () => { + cloudExecutable.configuration.settings.set(['watch'], {}); + const toolkit = defaultToolkitSetup(); + const cdkDeployMock = jest.fn(); + toolkit.deploy = cdkDeployMock; + + await toolkit.watch({ selector: { patterns: [] }, concurrency: 3 }); + fakeChokidarWatcherOn.readyCallback(); + + expect(cdkDeployMock).toBeCalledWith(expect.objectContaining({ concurrency: 3 })); + }); + describe('with file change events', () => { let toolkit: CdkToolkit; let cdkDeployMock: jest.Mock;