Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): missing context in Stages is not filled by CLI #11461

Merged
merged 2 commits into from
Nov 16, 2020
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
35 changes: 35 additions & 0 deletions packages/@aws-cdk/core/test/stage.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as cxschema from '@aws-cdk/cloud-assembly-schema';
import * as cxapi from '@aws-cdk/cx-api';
import { nodeunitShim, Test } from 'nodeunit-shim';
import { App, CfnResource, Construct, IAspect, IConstruct, Stack, Stage, Aspects } from '../lib';
Expand Down Expand Up @@ -311,6 +312,40 @@ nodeunitShim({
},
});

test('missing context in Stages is propagated up to root assembly', () => {
// GIVEN
const app = new App();
const stage = new Stage(app, 'Stage', {
env: { account: 'account', region: 'region' },
});
const stack = new Stack(stage, 'Stack');
new CfnResource(stack, 'Resource', { type: 'Something' });

// WHEN
stack.reportMissingContext({
key: 'missing-context-key',
provider: cxschema.ContextProvider.AVAILABILITY_ZONE_PROVIDER,
props: {
account: 'account',
region: 'region',
},
});

// THEN
const assembly = app.synth();

expect(assembly.manifest.missing).toEqual([
{
key: 'missing-context-key',
provider: cxschema.ContextProvider.AVAILABILITY_ZONE_PROVIDER,
props: {
account: 'account',
region: 'region',
},
},
]);
});

class TouchingAspect implements IAspect {
public readonly visits = new Array<IConstruct>();
public visit(node: IConstruct): void {
Expand Down
12 changes: 12 additions & 0 deletions packages/@aws-cdk/cx-api/lib/cloud-assembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ export interface CloudAssemblyBuilderProps {
* @default - Same as the manifest outdir
*/
readonly assetOutdir?: string;

/**
* If this builder is for a nested assembly, the parent assembly builder
*
* @default - This is a root assembly
*/
readonly parentBuilder?: CloudAssemblyBuilder;
}

/**
Expand All @@ -237,6 +244,7 @@ export class CloudAssemblyBuilder {

private readonly artifacts: { [id: string]: cxschema.ArtifactManifest } = { };
private readonly missing = new Array<cxschema.MissingContext>();
private readonly parentBuilder?: CloudAssemblyBuilder;

/**
* Initializes a cloud assembly builder.
Expand All @@ -245,6 +253,7 @@ export class CloudAssemblyBuilder {
constructor(outdir?: string, props: CloudAssemblyBuilderProps = {}) {
this.outdir = determineOutputDirectory(outdir);
this.assetOutdir = props.assetOutdir ?? this.outdir;
this.parentBuilder = props.parentBuilder;

// we leverage the fact that outdir is long-lived to avoid staging assets into it
// that were already staged (copying can be expensive). this is achieved by the fact
Expand All @@ -270,6 +279,8 @@ export class CloudAssemblyBuilder {
if (this.missing.every(m => m.key !== missing.key)) {
this.missing.push(missing);
}
// Also report in parent
this.parentBuilder?.addMissing(missing);
}

/**
Expand Down Expand Up @@ -320,6 +331,7 @@ export class CloudAssemblyBuilder {
return new CloudAssemblyBuilder(innerAsmDir, {
// Reuse the same asset output directory as the current Casm builder
assetOutdir: this.assetOutdir,
parentBuilder: this,
});
}
}
Expand Down
22 changes: 22 additions & 0 deletions packages/@aws-cdk/cx-api/test/cloud-assembly-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,28 @@ test('write and read nested cloud assembly artifact', () => {
expect(nested?.artifacts.length).toEqual(0);
});

test('missing values are reported to top-level asm', () => {
// GIVEN
const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'cloud-assembly-builder-tests'));
const session = new cxapi.CloudAssemblyBuilder(outdir);

const innerAsm = session.createNestedAssembly('hello', 'hello');

// WHEN
const props: cxschema.ContextQueryProperties = {
account: '1234',
region: 'asdf',
filter: { a: 'a' },
};

innerAsm.addMissing({ key: 'foo', provider: cxschema.ContextProvider.VPC_PROVIDER, props });

// THEN
const assembly = session.buildAssembly();

expect(assembly.manifest.missing?.length).toEqual(1);
});

test('artifcats are written in topological order', () => {
// GIVEN
const outdir = fs.mkdtempSync(path.join(os.tmpdir(), 'cloud-assembly-builder-tests'));
Expand Down