Skip to content

Commit

Permalink
fix(core): cannot determine packaging when bundling that produces an …
Browse files Browse the repository at this point in the history
…archive is skipped (#14372)

Bundling is skipped when the bundling directory already exists on disk
(cache). If it previously produced a single archive file that has been
moved to the staging directory the current logic either failed to
determine the correct packaging type or threw because it expected the
bundling directory to include a single archive file.

Fix it by "touching" the archive file in the bundling directory after it
has been moved to the staging directory.

Fixes #14369


----

*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 May 18, 2021
1 parent 7fe329c commit 163e812
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
9 changes: 9 additions & 0 deletions packages/@aws-cdk/core/lib/asset-staging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
54 changes: 52 additions & 2 deletions packages/@aws-cdk/core/test/staging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit 163e812

Please sign in to comment.