Skip to content

Commit e01faff

Browse files
authored
feat(cli-lib-alpha): support hotswap deployments (#26786)
Closes #26785. Exemption Request: The `cli-lib-alpha` README does not currently specify the exhaustive list of arguments, which looks like a choice, thus I did not add the new argument. Currently, no integration tests were implemented for this lib, only unit tests which I did update/add. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent f5a5a08 commit e01faff

File tree

3 files changed

+83
-6
lines changed

3 files changed

+83
-6
lines changed

packages/@aws-cdk/cli-lib-alpha/lib/cli.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { exec as runCli } from 'aws-cdk/lib';
33
// eslint-disable-next-line import/no-extraneous-dependencies
44
import { createAssembly, prepareContext, prepareDefaultEnvironment } from 'aws-cdk/lib/api/cxapp/exec';
5-
import { SharedOptions, DeployOptions, DestroyOptions, BootstrapOptions, SynthOptions, ListOptions, StackActivityProgress } from './commands';
5+
import { SharedOptions, DeployOptions, DestroyOptions, BootstrapOptions, SynthOptions, ListOptions, StackActivityProgress, HotswapMode } from './commands';
66

77
/**
88
* AWS CDK CLI operations
@@ -211,6 +211,7 @@ export class AwsCdkCli implements IAwsCdkCli {
211211
...renderBooleanArg('asset-parallelism', options.assetParallelism),
212212
...renderBooleanArg('asset-prebuild', options.assetPrebuild),
213213
...renderNumberArg('concurrency', options.concurrency),
214+
...renderHotswapArg(options.hotswap),
214215
...options.reuseAssets ? renderArrayArg('--reuse-assets', options.reuseAssets) : [],
215216
...options.notificationArns ? renderArrayArg('--notification-arns', options.notificationArns) : [],
216217
...options.parameters ? renderMapArrayArg('--parameters', options.parameters) : [],
@@ -267,6 +268,17 @@ export class AwsCdkCli implements IAwsCdkCli {
267268
}
268269
}
269270

271+
function renderHotswapArg(hotswapMode: HotswapMode | undefined): string[] {
272+
switch (hotswapMode) {
273+
case HotswapMode.FALL_BACK:
274+
return ['--hotswap-fallback'];
275+
case HotswapMode.HOTSWAP_ONLY:
276+
return ['--hotswap'];
277+
default:
278+
return [];
279+
}
280+
}
281+
270282
function renderMapArrayArg(flag: string, parameters: { [name: string]: string | undefined }): string[] {
271283
const params: string[] = [];
272284
for (const [key, value] of Object.entries(parameters)) {

packages/@aws-cdk/cli-lib-alpha/lib/commands/deploy.ts

+26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
import { SharedOptions, RequireApproval } from './common';
22

3+
export enum HotswapMode {
4+
/**
5+
* Will fall back to CloudFormation when a non-hotswappable change is detected
6+
*/
7+
FALL_BACK = 'fall-back',
8+
9+
/**
10+
* Will not fall back to CloudFormation when a non-hotswappable change is detected
11+
*/
12+
HOTSWAP_ONLY = 'hotswap-only',
13+
14+
/**
15+
* Will not attempt to hotswap anything and instead go straight to CloudFormation
16+
*/
17+
FULL_DEPLOYMENT = 'full-deployment',
18+
}
19+
320
/**
421
* Options to use with cdk deploy
522
*/
@@ -68,6 +85,15 @@ export interface DeployOptions extends SharedOptions {
6885
*/
6986
readonly execute?: boolean;
7087

88+
/*
89+
* Whether to perform a 'hotswap' deployment.
90+
* A 'hotswap' deployment will attempt to short-circuit CloudFormation
91+
* and update the affected resources like Lambda functions directly. Do not use this in production environments
92+
*
93+
* @default - `HotswapMode.FULL_DEPLOYMENT` for regular deployments, `HotswapMode.HOTSWAP_ONLY` for 'watch' deployments
94+
*/
95+
readonly hotswap?: HotswapMode;
96+
7197
/**
7298
* Additional parameters for CloudFormation at deploy time
7399
* @default {}

packages/@aws-cdk/cli-lib-alpha/test/commands.test.ts

+44-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as core from 'aws-cdk-lib/core';
22
import * as cli from 'aws-cdk/lib';
33
import { AwsCdkCli } from '../lib';
4-
import { RequireApproval, StackActivityProgress } from '../lib/commands';
4+
import { HotswapMode, RequireApproval, StackActivityProgress } from '../lib/commands';
55

66
jest.mock('aws-cdk/lib');
77
jest.mocked(cli.exec).mockResolvedValue(0);
@@ -23,7 +23,7 @@ const cdk = AwsCdkCli.fromCloudAssemblyDirectoryProducer({
2323
describe('deploy', () => {
2424
test('default deploy', async () => {
2525
// WHEN
26-
await await cdk.deploy();
26+
await cdk.deploy();
2727

2828
// THEN
2929
expect(jest.mocked(cli.exec)).toHaveBeenCalledWith(
@@ -34,7 +34,7 @@ describe('deploy', () => {
3434

3535
test('deploy with all arguments', async () => {
3636
// WHEN
37-
await await cdk.deploy({
37+
await cdk.deploy({
3838
stacks: ['Stack1'],
3939
ci: false,
4040
json: true,
@@ -45,6 +45,7 @@ describe('deploy', () => {
4545
trace: false,
4646
strict: false,
4747
execute: true,
48+
hotswap: HotswapMode.HOTSWAP_ONLY,
4849
lookups: false,
4950
notices: true,
5051
profile: 'my-profile',
@@ -98,6 +99,7 @@ describe('deploy', () => {
9899
'--no-strict',
99100
'--no-trace',
100101
'--no-lookups',
102+
'--hotswap',
101103
'--no-ignore-errors',
102104
'--json',
103105
'--verbose',
@@ -118,9 +120,46 @@ describe('deploy', () => {
118120
);
119121
});
120122

123+
test('can parse hotswap-fallback argument', async () => {
124+
// WHEN
125+
await cdk.deploy({
126+
stacks: ['Stack1'],
127+
hotswap: HotswapMode.FALL_BACK,
128+
});
129+
130+
// THEN
131+
expect(jest.mocked(cli.exec)).toHaveBeenCalledWith(
132+
[
133+
'deploy',
134+
'--hotswap-fallback',
135+
'--progress', 'events',
136+
'Stack1',
137+
],
138+
expect.anything(),
139+
);
140+
});
141+
142+
test('skip hotswap full-deployment argument', async () => {
143+
// WHEN
144+
await cdk.deploy({
145+
stacks: ['Stack1'],
146+
hotswap: HotswapMode.FULL_DEPLOYMENT,
147+
});
148+
149+
// THEN
150+
expect(jest.mocked(cli.exec)).toHaveBeenCalledWith(
151+
[
152+
'deploy',
153+
'--progress', 'events',
154+
'Stack1',
155+
],
156+
expect.anything(),
157+
);
158+
});
159+
121160
test('can parse boolean arguments', async () => {
122161
// WHEN
123-
await await cdk.deploy({
162+
await cdk.deploy({
124163
stacks: ['Stack1'],
125164
json: true,
126165
color: false,
@@ -141,7 +180,7 @@ describe('deploy', () => {
141180

142181
test('can parse parameters', async() => {
143182
// WHEN
144-
await await cdk.deploy({
183+
await cdk.deploy({
145184
stacks: ['Stack1'],
146185
parameters: {
147186
'myparam': 'test',

0 commit comments

Comments
 (0)