From a74aacfb362fac08ced4ebc3e176f89a71b57dd7 Mon Sep 17 00:00:00 2001 From: Thorsten Hoeger Date: Thu, 4 Jan 2024 02:51:39 +0100 Subject: [PATCH] fix(core): single-file bundling breaks due to left over temp dir (#28566) This change fixes a bad behavior of the asset bundling if we use the SINGLE_FILE asset type with the OUTPUT hash type. Because only the created file is moved and the temporary bundle dir is left over, subsequent bundling runs fail and create empty asset files. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cdk-lib/core/lib/asset-staging.ts | 9 ++++-- .../aws-cdk-lib/core/test/staging.test.ts | 31 +++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk-lib/core/lib/asset-staging.ts b/packages/aws-cdk-lib/core/lib/asset-staging.ts index 91ec93914a2f0..8991dfbe18634 100644 --- a/packages/aws-cdk-lib/core/lib/asset-staging.ts +++ b/packages/aws-cdk-lib/core/lib/asset-staging.ts @@ -343,11 +343,16 @@ export class AssetStaging extends Construct { this.stageAsset(bundledAsset.path, stagedPath, 'move'); // If bundling produced a single archive file we "touch" this file in the bundling - // directory after it has been moved to the staging directory. This way if bundling + // directory after it has been moved to the staging directory if the hash is known before bundling. This way if bundling // is skipped because the bundling directory already exists we can still determine // the correct packaging type. + // If the hash is calculated after bundling we remove the temporary directory now. if (bundledAsset.packaging === FileAssetPackaging.FILE) { - fs.closeSync(fs.openSync(bundledAsset.path, 'w')); + if (this.hashType === AssetHashType.OUTPUT || this.hashType === AssetHashType.BUNDLE) { + fs.removeSync(path.dirname(bundledAsset.path)); + } else { + fs.closeSync(fs.openSync(bundledAsset.path, 'w')); + } } return { diff --git a/packages/aws-cdk-lib/core/test/staging.test.ts b/packages/aws-cdk-lib/core/test/staging.test.ts index 6f3d904b4ed6e..dff63c09a76f8 100644 --- a/packages/aws-cdk-lib/core/test/staging.test.ts +++ b/packages/aws-cdk-lib/core/test/staging.test.ts @@ -1419,6 +1419,37 @@ describe('staging', () => { expect(staging.isArchive).toEqual(false); }); + test('bundling that produces a single file with SINGLE_FILE and hash type OUTPUT', () => { + // GIVEN + const app = new App({ context: { [cxapi.NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: false } }); + const stack = new Stack(app, 'stack'); + const directory = path.join(__dirname, 'fs', 'fixtures', 'test1', 'subdir'); + + // WHEN + const staging = new AssetStaging(stack, 'Asset', { + sourcePath: directory, + assetHashType: AssetHashType.OUTPUT, + bundling: { + image: DockerImage.fromRegistry('alpine'), + command: [DockerStubCommand.SINGLE_FILE], + outputType: BundlingOutput.SINGLE_FILE, + }, + }); + + // THEN + const assembly = app.synth(); + expect(fs.readdirSync(assembly.directory)).toEqual([ + // 'bundling-temp-0e346bd27baa32f4f2d15d1d73c8972db3293080f6c2836328b7bf77747683db', this directory gets removed and does no longer exist + 'asset.95c924c84f5d023be4edee540cb2cb401a49f115d01ed403b288f6cb412771df.txt', + 'cdk.out', + 'manifest.json', + 'stack.template.json', + 'tree.json', + ]); + expect(staging.packaging).toEqual(FileAssetPackaging.FILE); + expect(staging.isArchive).toEqual(false); + }); + }); describe('staging with docker cp', () => {