diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index f68123c4d36be..5160904878e11 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -212,7 +212,7 @@ export class Bundling { }); return lambda.Code.fromAsset(projectRoot, { - assetHashType: cdk.AssetHashType.BUNDLE, + assetHashType: cdk.AssetHashType.OUTPUT, bundling: { local: localBundler, ...dockerBundler.bundlingOptions, diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts index 40fdb21ac60a8..654e3b49f9029 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -40,7 +40,7 @@ test('Parcel bundling', () => { // Correctly bundles with parcel expect(Code.fromAsset).toHaveBeenCalledWith('/project', { - assetHashType: AssetHashType.BUNDLE, + assetHashType: AssetHashType.OUTPUT, bundling: expect.objectContaining({ local: { props: expect.objectContaining({ @@ -93,7 +93,7 @@ test('Parcel bundling with handler named index.ts', () => { // Correctly bundles with parcel expect(Code.fromAsset).toHaveBeenCalledWith('/project', { - assetHashType: AssetHashType.BUNDLE, + assetHashType: AssetHashType.OUTPUT, bundling: expect.objectContaining({ command: [ 'bash', '-c', @@ -112,7 +112,7 @@ test('Parcel bundling with tsx handler', () => { // Correctly bundles with parcel expect(Code.fromAsset).toHaveBeenCalledWith('/project', { - assetHashType: AssetHashType.BUNDLE, + assetHashType: AssetHashType.OUTPUT, bundling: expect.objectContaining({ command: [ 'bash', '-c', @@ -152,7 +152,7 @@ test('Parcel bundling with externals and dependencies', () => { // Correctly bundles with parcel expect(Code.fromAsset).toHaveBeenCalledWith('/project', { - assetHashType: AssetHashType.BUNDLE, + assetHashType: AssetHashType.OUTPUT, bundling: expect.objectContaining({ command: [ 'bash', '-c', @@ -199,7 +199,7 @@ test('Detects yarn.lock', () => { // Correctly bundles with parcel expect(Code.fromAsset).toHaveBeenCalledWith('/project', { - assetHashType: AssetHashType.BUNDLE, + assetHashType: AssetHashType.OUTPUT, bundling: expect.objectContaining({ command: expect.arrayContaining([ expect.stringMatching(/yarn\.lock.+yarn install/), @@ -316,7 +316,7 @@ test('Custom bundling docker image', () => { }); expect(Code.fromAsset).toHaveBeenCalledWith('/project', { - assetHashType: AssetHashType.BUNDLE, + assetHashType: AssetHashType.OUTPUT, bundling: expect.objectContaining({ image: { image: 'my-custom-image' }, }), diff --git a/packages/@aws-cdk/core/lib/asset-staging.ts b/packages/@aws-cdk/core/lib/asset-staging.ts index dc49750a46f2f..e5878c2a31365 100644 --- a/packages/@aws-cdk/core/lib/asset-staging.ts +++ b/packages/@aws-cdk/core/lib/asset-staging.ts @@ -113,7 +113,7 @@ export class AssetStaging extends Construct { this.relativePath = renderAssetFilename(this.assetHash); this.stagedPath = this.relativePath; } else { // Bundling is skipped - this.assetHash = props.assetHashType === AssetHashType.BUNDLE + this.assetHash = props.assetHashType === AssetHashType.BUNDLE || props.assetHashType === AssetHashType.OUTPUT ? this.calculateHash(AssetHashType.CUSTOM, this.node.path) // Use node path as dummy hash because we're not bundling : this.calculateHash(hashType, props.assetHash); this.stagedPath = this.sourcePath; @@ -295,8 +295,9 @@ export class AssetStaging extends Construct { case AssetHashType.SOURCE: return FileSystem.fingerprint(this.sourcePath, this.fingerprintOptions); case AssetHashType.BUNDLE: + case AssetHashType.OUTPUT: if (!this.bundleDir) { - throw new Error('Cannot use `AssetHashType.BUNDLE` when `bundling` is not specified.'); + throw new Error(`Cannot use \`${hashType}\` hash type when \`bundling\` is not specified.`); } return FileSystem.fingerprint(this.bundleDir, this.fingerprintOptions); default: diff --git a/packages/@aws-cdk/core/lib/assets.ts b/packages/@aws-cdk/core/lib/assets.ts index 012b7da4d489c..17d3b9d93e53f 100644 --- a/packages/@aws-cdk/core/lib/assets.ts +++ b/packages/@aws-cdk/core/lib/assets.ts @@ -60,18 +60,35 @@ export interface AssetOptions { /** * The type of asset hash + * + * NOTE: the hash is used in order to identify a specific revision of the asset, and + * used for optimizing and caching deployment activities related to this asset such as + * packaging, uploading to Amazon S3, etc. */ export enum AssetHashType { /** * Based on the content of the source path + * + * When bundling, use `SOURCE` when the content of the bundling output is not + * stable across repeated bundling operations. */ SOURCE = 'source', /** * Based on the content of the bundled path + * + * @deprecated use `OUTPUT` instead */ BUNDLE = 'bundle', + /** + * Based on the content of the bundling output + * + * Use `OUTPUT` when the source of the asset is a top level folder containing + * code and/or dependencies that are not directly linked to the asset. + */ + OUTPUT = 'output', + /** * Use a custom hash */ diff --git a/packages/@aws-cdk/core/test/test.staging.ts b/packages/@aws-cdk/core/test/test.staging.ts index ff7279172bb00..e652c884935f4 100644 --- a/packages/@aws-cdk/core/test/test.staging.ts +++ b/packages/@aws-cdk/core/test/test.staging.ts @@ -425,6 +425,28 @@ export = { test.done(); }, + 'bundling with OUTPUT asset hash type'(test: Test) { + // GIVEN + const app = new App(); + const stack = new Stack(app, 'stack'); + const directory = path.join(__dirname, 'fs', 'fixtures', 'test1'); + + // WHEN + const asset = new AssetStaging(stack, 'Asset', { + sourcePath: directory, + bundling: { + image: BundlingDockerImage.fromRegistry('alpine'), + command: [DockerStubCommand.SUCCESS], + }, + assetHashType: AssetHashType.OUTPUT, + }); + + // THEN + test.equal(asset.assetHash, '33cbf2cae5432438e0f046bc45ba8c3cef7b6afcf47b59d1c183775c1918fb1f'); + + test.done(); + }, + 'custom hash'(test: Test) { // GIVEN const app = new App(); @@ -474,7 +496,23 @@ export = { test.throws(() => new AssetStaging(stack, 'Asset', { sourcePath: directory, assetHashType: AssetHashType.BUNDLE, - }), /Cannot use `AssetHashType.BUNDLE` when `bundling` is not specified/); + }), /Cannot use `bundle` hash type when `bundling` is not specified/); + test.equal(fs.existsSync(STUB_INPUT_FILE), false); + + test.done(); + }, + + 'throws with OUTPUT hash type and no bundling'(test: Test) { + // GIVEN + const app = new App(); + const stack = new Stack(app, 'stack'); + const directory = path.join(__dirname, 'fs', 'fixtures', 'test1'); + + // THEN + test.throws(() => new AssetStaging(stack, 'Asset', { + sourcePath: directory, + assetHashType: AssetHashType.OUTPUT, + }), /Cannot use `output` hash type when `bundling` is not specified/); test.equal(fs.existsSync(STUB_INPUT_FILE), false); test.done();