Skip to content

Commit

Permalink
fix(core): missing context in Stages is not filled by CLI (#11461)
Browse files Browse the repository at this point in the history
Missing context in Stages was reported at the inner-assembly
level. Since the CLI only inspects the top-level assembly for
missing context, it would never detect this and not query for it.

Propagate the missing context up to the top-level assembly.

Fixes #9226.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
rix0rrr committed Nov 16, 2020
1 parent 4768c44 commit a4a555a
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
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

0 comments on commit a4a555a

Please sign in to comment.