diff --git a/packages/@aws-cdk/core/lib/asset-staging.ts b/packages/@aws-cdk/core/lib/asset-staging.ts index 09820293b63ec..44ab0de0bdd5d 100644 --- a/packages/@aws-cdk/core/lib/asset-staging.ts +++ b/packages/@aws-cdk/core/lib/asset-staging.ts @@ -336,6 +336,15 @@ export class AssetStaging extends CoreConstruct { const stagedPath = path.resolve(this.assetOutdir, renderAssetFilename(assetHash, bundledAsset.extension)); 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 + // is skipped because the bundling directory already exists we can still determine + // the correct packaging type. + if (bundledAsset.packaging === FileAssetPackaging.FILE) { + fs.closeSync(fs.openSync(bundledAsset.path, 'w')); + } + return { assetHash, stagedPath, diff --git a/packages/@aws-cdk/core/test/staging.test.ts b/packages/@aws-cdk/core/test/staging.test.ts index ee87780a0957e..e492f0a2dce88 100644 --- a/packages/@aws-cdk/core/test/staging.test.ts +++ b/packages/@aws-cdk/core/test/staging.test.ts @@ -887,20 +887,70 @@ nodeunitShim({ // THEN const assembly = app.synth(); test.deepEqual(fs.readdirSync(assembly.directory), [ - 'asset.f43148c61174f444925231b5849b468f21e93b5d1469cd07c53625ffd039ef48', // this is the bundle dir but it's empty + 'asset.f43148c61174f444925231b5849b468f21e93b5d1469cd07c53625ffd039ef48', // this is the bundle dir 'asset.f43148c61174f444925231b5849b468f21e93b5d1469cd07c53625ffd039ef48.zip', 'cdk.out', 'manifest.json', 'stack.template.json', 'tree.json', ]); - test.equal(fs.readdirSync(path.join(assembly.directory, 'asset.f43148c61174f444925231b5849b468f21e93b5d1469cd07c53625ffd039ef48')).length, 0); // empty bundle dir + test.deepEqual(fs.readdirSync(path.join(assembly.directory, 'asset.f43148c61174f444925231b5849b468f21e93b5d1469cd07c53625ffd039ef48')), [ + 'test.zip', // bundle dir with "touched" bundled output file + ]); test.deepEqual(staging.packaging, FileAssetPackaging.FILE); test.deepEqual(staging.isArchive, true); test.done(); }, + 'bundling that produces a single archive file with disk cache'(test: Test) { + // GIVEN + const TEST_OUTDIR = path.join(__dirname, 'cdk.out'); + if (fs.existsSync(TEST_OUTDIR)) { + fs.removeSync(TEST_OUTDIR); + } + + const directory = path.join(__dirname, 'fs', 'fixtures', 'test1'); + + const app1 = new App({ outdir: TEST_OUTDIR }); + const stack1 = new Stack(app1, 'Stack'); + + const app2 = new App({ outdir: TEST_OUTDIR }); // same OUTDIR + const stack2 = new Stack(app2, 'stack'); + + // WHEN + const staging1 = new AssetStaging(stack1, 'Asset', { + sourcePath: directory, + bundling: { + image: BundlingDockerImage.fromRegistry('alpine'), + command: [DockerStubCommand.SINGLE_ARCHIVE], + outputType: BundlingOutput.ARCHIVED, + }, + }); + + // Now clear asset hash cache to show that during the second staging + // even though bundling is skipped it will correctly be considered + // as a FileAssetPackaging.FILE. + AssetStaging.clearAssetHashCache(); + + const staging2 = new AssetStaging(stack2, 'Asset', { + sourcePath: directory, + bundling: { + image: BundlingDockerImage.fromRegistry('alpine'), + command: [DockerStubCommand.SINGLE_ARCHIVE], + outputType: BundlingOutput.ARCHIVED, + }, + }); + + // THEN + test.deepEqual(staging1.packaging, FileAssetPackaging.FILE); + test.deepEqual(staging1.isArchive, true); + test.deepEqual(staging2.packaging, staging1.packaging); + test.deepEqual(staging2.isArchive, staging1.isArchive); + + test.done(); + }, + 'bundling that produces a single archive file with NOT_ARCHIVED'(test: Test) { // GIVEN const app = new App();