Skip to content

Commit ca391b5

Browse files
author
Niranjan Jayakar
authored
chore(lambda-nodejs): prepare code to reduce merge conflicts when deprecated APIs are stripped (#13738)
BUNDLING - The `BundlingDockerImage` class is deprecated, replaced by `DockerImage`. Remove all uses of this class across modules in a backwards compatible way. ECR ASSET - Change the way symbols are imported from '@aws-cdk/assets' so that they can be in-place replaced with their replacements from '@aws-cdk/core' module. The `IAsset` interface from the core module introduces the property `assetHash` instead of `sourceHash`. This change makes the code forwards compatible so as to be supportive on v2. Other small backwards compatible changes. BREAKING CHANGE: The type of `image` property in the `Bundling` class is changed from `BundlingDockerImage` to `DockerImage`. * **lambda-nodejs**: The type of `dockerImage` property in `BundlingOptions` is changed from `BundlingDockerImage` to `DockerImage`. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 54dcea2 commit ca391b5

File tree

13 files changed

+118
-59
lines changed

13 files changed

+118
-59
lines changed

packages/@aws-cdk/aws-ecr-assets/lib/image-asset.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
3-
import * as assets from '@aws-cdk/assets';
43
import * as ecr from '@aws-cdk/aws-ecr';
54
import { Annotations, FeatureFlags, IgnoreMode, Stack, Token } from '@aws-cdk/core';
65
import * as cxapi from '@aws-cdk/cx-api';
76
import { Construct } from 'constructs';
87

8+
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
9+
// eslint-disable-next-line
10+
import { FingerprintOptions, IAsset, Staging } from '@aws-cdk/assets';
911
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
1012
// eslint-disable-next-line no-duplicate-imports, import/order
1113
import { Construct as CoreConstruct } from '@aws-cdk/core';
1214

1315
/**
1416
* Options for DockerImageAsset
1517
*/
16-
export interface DockerImageAssetOptions extends assets.FingerprintOptions {
18+
export interface DockerImageAssetOptions extends FingerprintOptions {
1719
/**
1820
* ECR repository name
1921
*
@@ -69,7 +71,7 @@ export interface DockerImageAssetProps extends DockerImageAssetOptions {
6971
*
7072
* The image will be created in build time and uploaded to an ECR repository.
7173
*/
72-
export class DockerImageAsset extends CoreConstruct implements assets.IAsset {
74+
export class DockerImageAsset extends CoreConstruct implements IAsset {
7375
/**
7476
* The full URI of the image (including a tag). Use this reference to pull
7577
* the asset.
@@ -81,8 +83,21 @@ export class DockerImageAsset extends CoreConstruct implements assets.IAsset {
8183
*/
8284
public repository: ecr.IRepository;
8385

86+
/**
87+
* A hash of the source of this asset, which is available at construction time. As this is a plain
88+
* string, it can be used in construct IDs in order to enforce creation of a new resource when
89+
* the content hash has changed.
90+
* @deprecated use assetHash
91+
*/
8492
public readonly sourceHash: string;
8593

94+
/**
95+
* A hash of this asset, which is available at construction time. As this is a plain string, it
96+
* can be used in construct IDs in order to enforce creation of a new resource when the content
97+
* hash has changed.
98+
*/
99+
public readonly assetHash: string;
100+
86101
constructor(scope: Construct, id: string, props: DockerImageAssetProps) {
87102
super(scope, id);
88103

@@ -141,7 +156,7 @@ export class DockerImageAsset extends CoreConstruct implements assets.IAsset {
141156
// deletion of the ECR repository the app used).
142157
extraHash.version = '1.21.0';
143158

144-
const staging = new assets.Staging(this, 'Staging', {
159+
const staging = new Staging(this, 'Staging', {
145160
...props,
146161
exclude,
147162
ignoreMode,
@@ -151,16 +166,16 @@ export class DockerImageAsset extends CoreConstruct implements assets.IAsset {
151166
: JSON.stringify(extraHash),
152167
});
153168

154-
this.sourceHash = staging.sourceHash;
169+
this.sourceHash = staging.assetHash;
170+
this.assetHash = staging.assetHash;
155171

156172
const stack = Stack.of(this);
157173
const location = stack.synthesizer.addDockerImageAsset({
158174
directoryName: staging.relativeStagedPath(stack),
159175
dockerBuildArgs: props.buildArgs,
160176
dockerBuildTarget: props.target,
161177
dockerFile: props.file,
162-
repositoryName: props.repositoryName,
163-
sourceHash: staging.sourceHash,
178+
sourceHash: staging.assetHash,
164179
});
165180

166181
this.repository = ecr.Repository.fromRepositoryName(this, 'Repository', location.repositoryName);

packages/@aws-cdk/aws-ecr-assets/test/image-asset.test.ts

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ describe('image asset', () => {
192192

193193
const session = app.synth();
194194

195-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
196-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();
195+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'Dockerfile'))).toBeDefined();
196+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'index.py'))).toBeDefined();
197197

198198
});
199199

@@ -214,16 +214,16 @@ describe('image asset', () => {
214214
const session = app.synth();
215215

216216
// Only the files exempted above should be included.
217-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore'))).toBeDefined();
218-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
219-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();
220-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt'))).toBeDefined();
221-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory'))).toBeDefined();
222-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();
223-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules'))).toBeDefined();
224-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'one'))).toBeDefined();
225-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'some_dep'))).toBeDefined();
226-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'node_modules', 'some_dep', 'file'))).toBeDefined();
217+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, '.dockerignore'))).toBeDefined();
218+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'Dockerfile'))).toBeDefined();
219+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'index.py'))).toBeDefined();
220+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'foobar.txt'))).toBeDefined();
221+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'subdirectory'))).toBeDefined();
222+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();
223+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'node_modules'))).toBeDefined();
224+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'node_modules', 'one'))).toBeDefined();
225+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'node_modules', 'some_dep'))).toBeDefined();
226+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'node_modules', 'some_dep', 'file'))).toBeDefined();
227227

228228

229229
});
@@ -283,13 +283,13 @@ describe('image asset', () => {
283283
const asset6 = new DockerImageAsset(stack, 'Asset6', { directory, extraHash: 'random-extra' });
284284
const asset7 = new DockerImageAsset(stack, 'Asset7', { directory, repositoryName: 'foo' });
285285

286-
expect(asset1.sourceHash).toEqual('ab01ecd4419f59e1ec0ac9e57a60dbb653be68a29af0223fa8cb24b4b747bc73');
287-
expect(asset2.sourceHash).toEqual('7fb12f6148098e3f5c56c788a865d2af689125ead403b795fe6a262ec34384b3');
288-
expect(asset3.sourceHash).toEqual('fc3b6d802ba198ba2ee55079dbef27682bcd1288d5849eb5bbd5cd69038359b3');
289-
expect(asset4.sourceHash).toEqual('30439ea6dfeb4ddfd9175097286895c78393ef52a78c68f92db08abc4513cad6');
290-
expect(asset5.sourceHash).toEqual('5775170880e26ba31799745241b90d4340c674bb3b1c01d758e416ee3f1c386f');
291-
expect(asset6.sourceHash).toEqual('ba82fd351a4d3e3f5c5d948b9948e7e829badc3da90f97e00bb7724afbeacfd4');
292-
expect(asset7.sourceHash).toEqual('26ec194928431cab6ec5af24ea9f01af2cf7b20e361128b07b2a7405d2951f95');
286+
expect(asset1.assetHash).toEqual('ab01ecd4419f59e1ec0ac9e57a60dbb653be68a29af0223fa8cb24b4b747bc73');
287+
expect(asset2.assetHash).toEqual('7fb12f6148098e3f5c56c788a865d2af689125ead403b795fe6a262ec34384b3');
288+
expect(asset3.assetHash).toEqual('fc3b6d802ba198ba2ee55079dbef27682bcd1288d5849eb5bbd5cd69038359b3');
289+
expect(asset4.assetHash).toEqual('30439ea6dfeb4ddfd9175097286895c78393ef52a78c68f92db08abc4513cad6');
290+
expect(asset5.assetHash).toEqual('5775170880e26ba31799745241b90d4340c674bb3b1c01d758e416ee3f1c386f');
291+
expect(asset6.assetHash).toEqual('ba82fd351a4d3e3f5c5d948b9948e7e829badc3da90f97e00bb7724afbeacfd4');
292+
expect(asset7.assetHash).toEqual('26ec194928431cab6ec5af24ea9f01af2cf7b20e361128b07b2a7405d2951f95');
293293

294294
});
295295
});
@@ -304,12 +304,12 @@ function testDockerDirectoryIsStagedWithoutFilesSpecifiedInDockerignore(app: App
304304
const session = app.synth();
305305

306306
// .dockerignore itself should be included in output to be processed during docker build
307-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore'))).toBeDefined();
308-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
309-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();
310-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt'))).toBeDefined();
311-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory'))).toBeDefined();
312-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();
307+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, '.dockerignore'))).toBeDefined();
308+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'Dockerfile'))).toBeDefined();
309+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'index.py'))).toBeDefined();
310+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'foobar.txt'))).toBeDefined();
311+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'subdirectory'))).toBeDefined();
312+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();
313313

314314

315315
}
@@ -324,12 +324,12 @@ function testDockerDirectoryIsStagedWithoutFilesSpecifiedInExcludeOption(app: Ap
324324

325325
const session = app.synth();
326326

327-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, '.dockerignore'))).toBeDefined();
328-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'Dockerfile'))).toBeDefined();
329-
expect(fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'index.py'))).toBeDefined();
330-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'foobar.txt'))).toBeDefined();
331-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory'))).toBeDefined();
332-
expect(!fs.existsSync(path.join(session.directory, `asset.${image.sourceHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();
327+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, '.dockerignore'))).toBeDefined();
328+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'Dockerfile'))).toBeDefined();
329+
expect(fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'index.py'))).toBeDefined();
330+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'foobar.txt'))).toBeDefined();
331+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'subdirectory'))).toBeDefined();
332+
expect(!fs.existsSync(path.join(session.directory, `asset.${image.assetHash}`, 'subdirectory', 'baz.txt'))).toBeDefined();
333333

334334

335335
}

packages/@aws-cdk/aws-events-targets/lib/event-bus.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,12 @@ export class EventBus implements events.IRuleTarget {
2424
this.role = props.role;
2525
}
2626

27-
bind(rule: events.IRule, id?: string): events.RuleTargetConfig {
27+
bind(rule: events.IRule, _id?: string): events.RuleTargetConfig {
2828
if (this.role) {
2929
this.role.addToPrincipalPolicy(this.putEventStatement());
3030
}
3131
const role = this.role ?? singletonEventRole(rule, [this.putEventStatement()]);
3232
return {
33-
id: id ?? '',
3433
arn: this.eventBus.eventBusArn,
3534
role,
3635
};

packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class Bundling implements cdk.BundlingOptions {
4848
private static runsLocally?: boolean;
4949

5050
// Core bundling options
51-
public readonly image: cdk.BundlingDockerImage;
51+
public readonly image: cdk.DockerImage;
5252
public readonly command: string[];
5353
public readonly environment?: { [key: string]: string };
5454
public readonly workingDirectory: string;
@@ -78,14 +78,14 @@ export class Bundling implements cdk.BundlingOptions {
7878
// Docker bundling
7979
const shouldBuildImage = props.forceDockerBundling || !Bundling.runsLocally;
8080
this.image = shouldBuildImage
81-
? props.dockerImage ?? cdk.BundlingDockerImage.fromAsset(path.join(__dirname, '../lib'), {
81+
? props.dockerImage ?? cdk.DockerImage.fromBuild(path.join(__dirname, '../lib'), {
8282
buildArgs: {
8383
...props.buildArgs ?? {},
8484
IMAGE: props.runtime.bundlingDockerImage.image,
8585
ESBUILD_VERSION: props.esbuildVersion ?? ESBUILD_VERSION,
8686
},
8787
})
88-
: cdk.BundlingDockerImage.fromRegistry('dummy'); // Do not build if we don't need to
88+
: cdk.DockerImage.fromRegistry('dummy'); // Do not build if we don't need to
8989

9090
const bundlingCommand = this.createBundlingCommand(cdk.AssetStaging.BUNDLING_INPUT_DIR, cdk.AssetStaging.BUNDLING_OUTPUT_DIR);
9191
this.command = ['bash', '-c', bundlingCommand];

packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BundlingDockerImage } from '@aws-cdk/core';
1+
import { DockerImage } from '@aws-cdk/core';
22

33
/**
44
* Bundling options
@@ -200,7 +200,7 @@ export interface BundlingOptions {
200200
*
201201
* @default - use the Docker image provided by @aws-cdk/aws-lambda-nodejs
202202
*/
203-
readonly dockerImage?: BundlingDockerImage;
203+
readonly dockerImage?: DockerImage;
204204

205205
/**
206206
* Command hooks

packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as child_process from 'child_process';
22
import * as os from 'os';
33
import * as path from 'path';
44
import { Code, Runtime } from '@aws-cdk/aws-lambda';
5-
import { AssetHashType, BundlingDockerImage } from '@aws-cdk/core';
5+
import { AssetHashType, DockerImage } from '@aws-cdk/core';
66
import { version as delayVersion } from 'delay/package.json';
77
import { Bundling } from '../lib/bundling';
88
import { LogLevel } from '../lib/types';
@@ -11,7 +11,7 @@ import * as util from '../lib/util';
1111
jest.mock('@aws-cdk/aws-lambda');
1212

1313
// Mock BundlingDockerImage.fromAsset() to avoid building the image
14-
let fromAssetMock = jest.spyOn(BundlingDockerImage, 'fromAsset');
14+
let fromAssetMock = jest.spyOn(DockerImage, 'fromBuild');
1515
let getEsBuildVersionMock = jest.spyOn(util, 'getEsBuildVersion');
1616
beforeEach(() => {
1717
jest.clearAllMocks();
@@ -290,7 +290,7 @@ test('Custom bundling docker image', () => {
290290
entry,
291291
depsLockFilePath,
292292
runtime: Runtime.NODEJS_12_X,
293-
dockerImage: BundlingDockerImage.fromRegistry('my-custom-image'),
293+
dockerImage: DockerImage.fromRegistry('my-custom-image'),
294294
forceDockerBundling: true,
295295
});
296296

packages/@aws-cdk/aws-lambda-python/lib/bundling.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export function bundle(options: BundlingOptions): lambda.Code {
9898
// copy Dockerfile to workdir
9999
fs.copyFileSync(path.join(__dirname, dockerfile), path.join(stagedir, dockerfile));
100100

101-
const image = cdk.BundlingDockerImage.fromAsset(stagedir, {
101+
const image = cdk.DockerImage.fromBuild(stagedir, {
102102
buildArgs: {
103103
IMAGE: runtime.bundlingDockerImage.image,
104104
},

packages/@aws-cdk/aws-lambda/lib/runtime.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BundlingDockerImage } from '@aws-cdk/core';
1+
import { BundlingDockerImage, DockerImage } from '@aws-cdk/core';
22

33
export interface LambdaRuntimeProps {
44
/**
@@ -218,7 +218,7 @@ export class Runtime {
218218
this.supportsInlineCode = !!props.supportsInlineCode;
219219
this.family = family;
220220
const imageName = props.bundlingDockerImage ?? `amazon/aws-sam-cli-build-image-${name}`;
221-
this.bundlingDockerImage = BundlingDockerImage.fromRegistry(imageName);
221+
this.bundlingDockerImage = DockerImage.fromRegistry(imageName);
222222
this.supportsCodeGuruProfiling = props.supportsCodeGuruProfiling ?? false;
223223

224224
Runtime.ALL.push(this);

packages/@aws-cdk/aws-s3-assets/lib/asset.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as path from 'path';
2-
import * as assets from '@aws-cdk/assets';
32
import * as iam from '@aws-cdk/aws-iam';
43
import * as kms from '@aws-cdk/aws-kms';
54
import * as s3 from '@aws-cdk/aws-s3';
@@ -8,11 +7,14 @@ import * as cxapi from '@aws-cdk/cx-api';
87
import { Construct } from 'constructs';
98
import { toSymlinkFollow } from './compat';
109

10+
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
11+
// eslint-disable-next-line no-duplicate-imports, import/order
12+
import { CopyOptions } from '@aws-cdk/assets';
1113
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
1214
// eslint-disable-next-line no-duplicate-imports, import/order
1315
import { Construct as CoreConstruct } from '@aws-cdk/core';
1416

15-
export interface AssetOptions extends assets.CopyOptions, cdk.AssetOptions {
17+
export interface AssetOptions extends CopyOptions, cdk.AssetOptions {
1618
/**
1719
* A list of principals that should be able to read this asset from S3.
1820
* You can use `asset.grantRead(principal)` to grant read permissions later.

packages/@aws-cdk/aws-s3-assets/test/integ.assets.bundling.lit.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as path from 'path';
22
import * as iam from '@aws-cdk/aws-iam';
3-
import { App, BundlingDockerImage, Stack, StackProps } from '@aws-cdk/core';
3+
import { App, DockerImage, Stack, StackProps } from '@aws-cdk/core';
44
import { Construct } from 'constructs';
55
import * as assets from '../lib';
66

@@ -12,7 +12,7 @@ class TestStack extends Stack {
1212
const asset = new assets.Asset(this, 'BundledAsset', {
1313
path: path.join(__dirname, 'markdown-asset'), // /asset-input and working directory in the container
1414
bundling: {
15-
image: BundlingDockerImage.fromAsset(path.join(__dirname, 'alpine-markdown')), // Build an image
15+
image: DockerImage.fromBuild(path.join(__dirname, 'alpine-markdown')), // Build an image
1616
command: [
1717
'sh', '-c', `
1818
markdown index.md > /asset-output/index.html

0 commit comments

Comments
 (0)