Skip to content

Commit

Permalink
feat(lambda-nodejs): custom asset hash (#16412)
Browse files Browse the repository at this point in the history
By default the asset hash for a `NodejsFunction` is based on the
bundling output, the result of the `esbuild` bundling.

Add a `assetHash` prop to customize the asset hash and allow users to
implement their own logic. This can be useful if users want to invalidate
the asset based on specific (input) file contents or logic.


Closes #16157


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
jogold authored Nov 8, 2021
1 parent d231b9e commit 90da730
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
17 changes: 17 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,20 @@ should also have `npm`, `yarn` or `pnpm` depending on the lock file you're using

Use the [default image provided by `@aws-cdk/aws-lambda-nodejs`](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-lambda-nodejs/lib/Dockerfile)
as a source of inspiration.

## Asset hash

By default the asset hash will be calculated based on the bundled output (`AssetHashType.OUTPUT`).

Use the `assetHash` prop to pass a custom hash:

```ts
new lambda.NodejsFunction(this, 'my-handler', {
bundling: {
assetHash: 'my-custom-hash',
},
});
```

If you chose to customize the hash, you will need to make sure it is updated every time the asset
changes, or otherwise it is possible that some deployments will not be invalidated.
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ export class Bundling implements cdk.BundlingOptions {
*/
public static bundle(options: BundlingProps): AssetCode {
return Code.fromAsset(options.projectRoot, {
assetHashType: cdk.AssetHashType.OUTPUT,
assetHash: options.assetHash,
assetHashType: options.assetHash ? cdk.AssetHashType.CUSTOM : cdk.AssetHashType.OUTPUT,
bundling: new Bundling(options),
});
}
Expand Down
15 changes: 15 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,21 @@ export interface BundlingOptions {
* @default - do not run additional commands
*/
readonly commandHooks?: ICommandHooks;

/**
* Specify a custom hash for this asset. For consistency, this custom hash will
* be SHA256 hashed and encoded as hex. The resulting hash will be the 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. If you chose to customize the hash, you will
* need to make sure it is updated every time the asset changes, or otherwise it is
* possible that some deployments will not be invalidated.
*
* @default - asset hash is calculated based on the bundled output
*/
readonly assetHash?: string;
}

/**
Expand Down
18 changes: 18 additions & 0 deletions packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,3 +658,21 @@ test('esbuild bundling with pre compilations and undefined tsconfig ( Should thr
}).toThrow('Cannot find a tsconfig.json, please specify the prop: tsconfig');

});

test('with custom hash', () => {
Bundling.bundle({
entry,
projectRoot,
depsLockFilePath,
runtime: Runtime.NODEJS_14_X,
forceDockerBundling: true,
assetHash: 'custom',
architecture: Architecture.X86_64,
});

// Correctly passes asset hash options
expect(Code.fromAsset).toHaveBeenCalledWith(path.dirname(depsLockFilePath), expect.objectContaining({
assetHash: 'custom',
assetHashType: AssetHashType.CUSTOM,
}));
});

0 comments on commit 90da730

Please sign in to comment.