Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/aws-cdk-lib/core/lib/nested-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ export class NestedStack extends Stack {
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_PATH_KEY] = this.templateFile;
resource.cfnOptions.metadata[cxapi.ASSET_RESOURCE_METADATA_PROPERTY_KEY] = resourceProperty;
}

public get bundlingRequired() {
return this._parentStack.bundlingRequired;
}
}

/**
Expand Down
25 changes: 25 additions & 0 deletions packages/aws-cdk-lib/core/test/nested-stack.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from 'path';
import { Construct } from 'constructs';
import { readFileSync } from 'fs-extra';
import { toCloudFormation } from './util';
import * as cxapi from '../../cx-api';
import {
Stack, NestedStack, CfnStack, Resource, CfnResource, App, CfnOutput,
} from '../lib';
Expand Down Expand Up @@ -168,6 +169,30 @@ describe('nested-stack', () => {
expect(() => toCloudFormation(stack2)).toThrow(
/Cannot use resource 'Stack1\/MyNestedStack\/MyResource' in a cross-environment fashion/);
});

test('requires bundling when root stack has exact match in BUNDLING_STACKS', () => {
const app = new App();
const stack = new Stack(app, 'Stack');
stack.node.setContext(cxapi.BUNDLING_STACKS, ['Stack']);

const child = new NestedStack(stack, 'Child');
const child2 = new NestedStack(child, 'Child2');

expect(child.bundlingRequired).toBe(true);
expect(child2.bundlingRequired).toBe(true);
});

test('not requires bundling when root stack has no match in BUNDLING_STACKS', () => {
const app = new App();
const stack = new Stack(app, 'Stack');
stack.node.setContext(cxapi.BUNDLING_STACKS, ['Stack2']);

const child = new NestedStack(stack, 'Child');
const child2 = new NestedStack(child, 'Child2');

expect(child.bundlingRequired).toBe(false);
expect(child2.bundlingRequired).toBe(false);
});
});

class MyResource extends Resource {
Expand Down
44 changes: 43 additions & 1 deletion packages/aws-cdk-lib/core/test/staging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as fs from 'fs-extra';
import * as sinon from 'sinon';
import { FileAssetPackaging } from '../../cloud-assembly-schema';
import * as cxapi from '../../cx-api';
import { App, AssetHashType, AssetStaging, DockerImage, BundlingOptions, BundlingOutput, FileSystem, Stack, Stage, BundlingFileAccess } from '../lib';
import { App, AssetHashType, AssetStaging, DockerImage, BundlingOptions, BundlingOutput, FileSystem, Stack, NestedStack, Stage, BundlingFileAccess } from '../lib';

const STUB_INPUT_FILE = '/tmp/docker-stub.input';
const STUB_INPUT_CONCAT_FILE = '/tmp/docker-stub.input.concat';
Expand Down Expand Up @@ -1145,6 +1145,48 @@ describe('staging', () => {
expect(dockerStubInput).not.toMatch(DockerStubCommand.MULTIPLE_FILES);
});

test('correctly skips bundling with stack under stage and nested stack', () => {
// GIVEN
const app = new App();

const stage = new Stage(app, 'Stage');
stage.node.setContext(cxapi.BUNDLING_STACKS, ['Stage/Stack1']);

const stack1 = new Stack(stage, 'Stack1', { stackName: 'unrelated-stack1-name' });
const stack1Nested = new NestedStack(stack1, 'Stack1Nest');

const stack2 = new Stack(stage, 'Stack2', { stackName: 'unrelated-stack2-name' });
const stack2Nested = new NestedStack(stack2, 'Stack2Nest');

const directory = path.join(__dirname, 'fs', 'fixtures', 'test1');

// WHEN
new AssetStaging(stack1Nested, 'Asset', {
sourcePath: directory,
assetHashType: AssetHashType.OUTPUT,
bundling: {
image: DockerImage.fromRegistry('alpine'),
command: [DockerStubCommand.SUCCESS],
},
});

new AssetStaging(stack2Nested, 'Asset', {
sourcePath: directory,
assetHashType: AssetHashType.OUTPUT,
bundling: {
image: DockerImage.fromRegistry('alpine'),
command: [DockerStubCommand.MULTIPLE_FILES],
},
});

// THEN
const dockerStubInput = readDockerStubInputConcat();
// Docker ran for the asset in Stack1
expect(dockerStubInput).toMatch(DockerStubCommand.SUCCESS);
// Docker did not run for the asset in Stack2
expect(dockerStubInput).not.toMatch(DockerStubCommand.MULTIPLE_FILES);
});

test('correctly bundles with stack under stage and the default stack pattern', () => {
// GIVEN
const app = new App();
Expand Down