From 76ac13cb3de70bf1e014f721f3a7bd92a17a003a Mon Sep 17 00:00:00 2001 From: Otavio Macedo <288203+otaviomacedo@users.noreply.github.com> Date: Wed, 18 Jun 2025 18:08:33 +0100 Subject: [PATCH 1/3] fix: revert "retain type of context values and not convert them to string" (#630) Some users are relying on context values always being a string. Fixes https://github.com/aws/aws-cdk-cli/issues/629 and https://github.com/aws/aws-cdk-cli/issues/626 --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --- .../cli-integ/resources/cdk-apps/app/app.js | 6 ++---- .../aws-cdk/lib/cli/user-configuration.ts | 8 +------- .../aws-cdk/test/cli/configuration.test.ts | 20 ------------------- 3 files changed, 3 insertions(+), 31 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js index 409b1d061..8735e727c 100755 --- a/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js +++ b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js @@ -453,8 +453,7 @@ class LambdaStack extends cdk.Stack { constructor(parent, id, props) { // sometimes we need to specify the custom bootstrap bucket to use // see the 'upgrade legacy bootstrap stack' test - const useLegacy = [true, 'true'].includes(parent.node.tryGetContext('legacySynth')); - const synthesizer = useLegacy ? + const synthesizer = parent.node.tryGetContext('legacySynth') === 'true' ? new LegacyStackSynthesizer({ fileAssetsBucketName: parent.node.tryGetContext('bootstrapBucket'), }) @@ -478,8 +477,7 @@ class LambdaStack extends cdk.Stack { class DriftableStack extends cdk.Stack { constructor(parent, id, props) { - const useLegacy = [true, 'true'].includes(parent.node.tryGetContext('legacySynth')); - const synthesizer = useLegacy ? + const synthesizer = parent.node.tryGetContext('legacySynth') === 'true' ? new LegacyStackSynthesizer({ fileAssetsBucketName: parent.node.tryGetContext('bootstrapBucket'), }) diff --git a/packages/aws-cdk/lib/cli/user-configuration.ts b/packages/aws-cdk/lib/cli/user-configuration.ts index 50b6cef91..bbaff52a0 100644 --- a/packages/aws-cdk/lib/cli/user-configuration.ts +++ b/packages/aws-cdk/lib/cli/user-configuration.ts @@ -341,13 +341,7 @@ function parseStringContextListToObject(argv: Arguments): any { `User-provided context cannot use keys prefixed with 'aws:', but ${parts[0]} was provided.`, ); } - let parsedValue: any = parts[1]; - try { - parsedValue = JSON.parse(parts[1]); - } catch { - debug('Non-JSON context value for %s, leaving as string: %s', parts[0], parts[1]); - } - context[parts[0]] = parsedValue; + context[parts[0]] = parts[1]; } else { warning( 'Context argument is not an assignment (key=value): %s', diff --git a/packages/aws-cdk/test/cli/configuration.test.ts b/packages/aws-cdk/test/cli/configuration.test.ts index b2db10d60..3e8c0b361 100644 --- a/packages/aws-cdk/test/cli/configuration.test.ts +++ b/packages/aws-cdk/test/cli/configuration.test.ts @@ -116,23 +116,3 @@ test('providing a build arg', () => { // THEN expect(settings.get(['build'])).toEqual('mvn package'); }); - -test('can parse boolean context from command line arguments', () => { - // GIVEN - const settings1 = commandLineArgumentsToSettings({ context: ['foo=true'], _: [Command.DEPLOY] }); - const settings2 = commandLineArgumentsToSettings({ context: ['foo=false'], _: [Command.DEPLOY] }); - - // THEN - expect(settings1.get(['context']).foo).toEqual( true ); - expect(settings2.get(['context']).foo).toEqual( false ); -}); - -test('can parse number context from command line arguments', () => { - // GIVEN - const settings1 = commandLineArgumentsToSettings({ context: ['foo=5'], _: [Command.DEPLOY] }); - const settings2 = commandLineArgumentsToSettings({ context: ['foo=3.14'], _: [Command.DEPLOY] }); - - // THEN - expect(settings1.get(['context']).foo).toEqual( 5 ); - expect(settings2.get(['context']).foo).toEqual( 3.14 ); -}); From 0cba9767a270944c75c49b4b0d4ad47c982524c1 Mon Sep 17 00:00:00 2001 From: Cory Hall <43035978+corymhall@users.noreply.github.com> Date: Thu, 19 Jun 2025 03:48:22 -0400 Subject: [PATCH 2/3] feat(toolkit-lib): `fromAssemblyDirectory` can ignore missing context (#611) Previously `fromAssemblyDirectory` created a `ContextAwareCloudAssemblySource` with lookups disabled. This would always fail if there was any missing context in the assembly, because you can't perform lookups with just the CloudAssembly directory. This PR updates the logic to use a `CachedCloudAssembly` instead and check for missing context. The missing context check can be disabled using the new `failOnMissingContext` option (defaults to fail). Resolves #549 --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Co-authored-by: Momo Kornher Co-authored-by: Momo Kornher --- .../private/context-aware-source.ts | 9 +- .../lib/api/cloud-assembly/private/helpers.ts | 8 + .../lib/api/cloud-assembly/source-builder.ts | 56 ++-- .../StageStack130339B27.assets.json | 19 ++ .../StageStack130339B27.template.json | 314 ++++++++++++++++++ .../cdk.out/assembly-Stage/cdk.out | 1 + .../cdk.out/assembly-Stage/manifest.json | 66 ++++ .../assembly-missing-context/cdk.out/cdk.out | 1 + .../cdk.out/manifest.json | 33 ++ .../cdk.out/tree.json | 1 + .../api/cloud-assembly/source-builder.test.ts | 17 + 11 files changed, 495 insertions(+), 30 deletions(-) create mode 100644 packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.assets.json create mode 100644 packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.template.json create mode 100644 packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/cdk.out create mode 100644 packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/manifest.json create mode 100644 packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/cdk.out create mode 100644 packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/manifest.json create mode 100644 packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/tree.json diff --git a/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/context-aware-source.ts b/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/context-aware-source.ts index bcb52280c..fb2e859ae 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/context-aware-source.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/context-aware-source.ts @@ -1,4 +1,3 @@ -import type { MissingContext } from '@aws-cdk/cloud-assembly-schema'; import * as contextproviders from '../../../context-providers'; import type { ToolkitServices } from '../../../toolkit/private'; import { ToolkitError } from '../../../toolkit/toolkit-error'; @@ -6,6 +5,7 @@ import type { IoHelper } from '../../io/private'; import { IO } from '../../io/private'; import type { IContextStore } from '../context-store'; import type { ICloudAssemblySource, IReadableCloudAssembly } from '../types'; +import { missingContextKeys } from './helpers'; export interface ContextAwareCloudAssemblyProps { /** @@ -115,13 +115,6 @@ export class ContextAwareCloudAssemblySource implements ICloudAssemblySource { } } -/** - * Return all keys of missing context items - */ -function missingContextKeys(missing?: MissingContext[]): Set { - return new Set((missing || []).map(m => m.key)); -} - /** * Are two sets equal to each other */ diff --git a/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/helpers.ts b/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/helpers.ts index fccbf39c0..eab11d9d4 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/helpers.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/private/helpers.ts @@ -1,3 +1,4 @@ +import type { MissingContext } from '@aws-cdk/cloud-assembly-schema'; import { ToolkitError } from '../../../toolkit/toolkit-error'; /** @@ -42,3 +43,10 @@ function detectSynthvarConflicts(obj: A) { }, }); } + +/** + * Return all keys of missing context items + */ +export function missingContextKeys(missing?: MissingContext[]): Set { + return new Set((missing || []).map((m) => m.key)); +} diff --git a/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/source-builder.ts b/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/source-builder.ts index 81b81c512..ddabd79db 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/source-builder.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/api/cloud-assembly/source-builder.ts @@ -5,6 +5,7 @@ import * as cxapi from '@aws-cdk/cx-api'; import * as fs from 'fs-extra'; import { CdkAppMultiContext, MemoryContext, type IContextStore } from './context-store'; import { RWLock } from '../rwlock'; +import { CachedCloudAssembly } from './cached-source'; import type { ContextAwareCloudAssemblyProps } from './private/context-aware-source'; import { ContextAwareCloudAssemblySource } from './private/context-aware-source'; import { execInChildProcess } from './private/exec'; @@ -15,7 +16,7 @@ import type { ToolkitServices } from '../../toolkit/private'; import { ToolkitError, AssemblyError } from '../../toolkit/toolkit-error'; import { noUndefined } from '../../util'; import { IO } from '../io/private'; -import { temporarilyWriteEnv } from './private/helpers'; +import { missingContextKeys, temporarilyWriteEnv } from './private/helpers'; /** * Properties the builder function receives. @@ -61,6 +62,14 @@ export interface AssemblyDirectoryProps { * Options to configure loading of the assembly after it has been synthesized */ readonly loadAssemblyOptions?: LoadAssemblyOptions; + + /** + * Whether or not to fail if the synthesized assembly contains + * missing context + * + * @default true + */ + readonly failOnMissingContext?: boolean; } /** @@ -379,30 +388,33 @@ export abstract class CloudAssemblySourceBuilder { */ public async fromAssemblyDirectory(directory: string, props: AssemblyDirectoryProps = {}): Promise { const services: ToolkitServices = await this.sourceBuilderServices(); - const contextAssemblyProps: ContextAwareCloudAssemblyProps = { - services, - contextStore: new MemoryContext(), // @todo We shouldn't be using a `ContextAwareCloudAssemblySource` at all. - lookups: false, - }; - return new ContextAwareCloudAssemblySource( - { - produce: async () => { - // @todo build - await services.ioHelper.notify(IO.CDK_ASSEMBLY_I0150.msg('--app points to a cloud assembly, so we bypass synth')); - - const readLock = await new RWLock(directory).acquireRead(); - try { - const asm = await assemblyFromDirectory(directory, services.ioHelper, props.loadAssemblyOptions); - return new ReadableCloudAssembly(asm, readLock, { deleteOnDispose: false }); - } catch (e) { - await readLock.release(); - throw e; + return { + async produce() { + await services.ioHelper.notify(IO.CDK_ASSEMBLY_I0150.msg('--app points to a cloud assembly, so we bypass synth')); + const readLock = await new RWLock(directory).acquireRead(); + try { + const asm = await assemblyFromDirectory(directory, services.ioHelper, props.loadAssemblyOptions); + const assembly = new ReadableCloudAssembly(asm, readLock, { deleteOnDispose: false }); + if (assembly.cloudAssembly.manifest.missing && assembly.cloudAssembly.manifest.missing.length > 0) { + if (props.failOnMissingContext ?? true) { + const missingKeysSet = missingContextKeys(assembly.cloudAssembly.manifest.missing); + const missingKeys = Array.from(missingKeysSet); + throw AssemblyError.withCause( + 'Assembly contains missing context. ' + + "Make sure all necessary context is already in 'cdk.context.json' by running 'cdk synth' on a machine with sufficient AWS credentials and committing the result. " + + `Missing context keys: '${missingKeys.join(', ')}'`, + 'Error producing assembly', + ); + } } - }, + return new CachedCloudAssembly(assembly); + } catch (e) { + await readLock.release(); + throw e; + } }, - contextAssemblyProps, - ); + }; } /** * Use a directory containing an AWS CDK app as source. diff --git a/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.assets.json b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.assets.json new file mode 100644 index 000000000..4028f38b9 --- /dev/null +++ b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.assets.json @@ -0,0 +1,19 @@ +{ + "version": "40.0.0", + "files": { + "7f4fb64a3afca08edbdbaa369e00317cb253697278406a83c78e849e89045f9d": { + "source": { + "path": "StageStack130339B27.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "7f4fb64a3afca08edbdbaa369e00317cb253697278406a83c78e849e89045f9d.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.template.json b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.template.json new file mode 100644 index 000000000..a7668a10b --- /dev/null +++ b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/StageStack130339B27.template.json @@ -0,0 +1,314 @@ +{ + "Resources": { + "CDKMetadata": { + "Type": "AWS::CDK::Metadata", + "Properties": { + "Analytics": "v2:deflate64:H4sIAAAAAAAA/zPSM7Qw1TNQTCwv1k1OydbNyUzSCy5JTM7WyctPSdXLKtYvMzLSMzQEKskqzszULSrNK8nMTdULgtAAJ5JKTz8AAAA=" + }, + "Metadata": { + "aws:cdk:path": "Stage/Stack1/CDKMetadata/Default" + }, + "Condition": "CDKMetadataAvailable" + } + }, + "Conditions": { + "CDKMetadataAvailable": { + "Fn::Or": [ + { + "Fn::Or": [ + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "af-south-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-east-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-northeast-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-northeast-2" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-northeast-3" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-south-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-south-2" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-southeast-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-southeast-2" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-southeast-3" + ] + } + ] + }, + { + "Fn::Or": [ + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ap-southeast-4" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ca-central-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "ca-west-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "cn-north-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "cn-northwest-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-central-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-central-2" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-north-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-south-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-south-2" + ] + } + ] + }, + { + "Fn::Or": [ + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-west-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-west-2" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "eu-west-3" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "il-central-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "me-central-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "me-south-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "sa-east-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "us-east-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "us-east-2" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "us-west-1" + ] + } + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "us-west-2" + ] + } + ] + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/cdk.out b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/cdk.out new file mode 100644 index 000000000..1e02a2deb --- /dev/null +++ b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/cdk.out @@ -0,0 +1 @@ +{"version":"40.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/manifest.json b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/manifest.json new file mode 100644 index 000000000..52119eb46 --- /dev/null +++ b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/assembly-Stage/manifest.json @@ -0,0 +1,66 @@ +{ + "version": "40.0.0", + "artifacts": { + "StageStack130339B27.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "StageStack130339B27.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "StageStack130339B27": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "StageStack130339B27.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/7f4fb64a3afca08edbdbaa369e00317cb253697278406a83c78e849e89045f9d.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "StageStack130339B27.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + }, + "stackName": "Stage-Stack1" + }, + "dependencies": [ + "StageStack130339B27.assets" + ], + "metadata": { + "/Stage/Stack1/CDKMetadata/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "CDKMetadata" + } + ], + "/Stage/Stack1/CDKMetadata/Condition": [ + { + "type": "aws:cdk:logicalId", + "data": "CDKMetadataAvailable" + } + ], + "/Stage/Stack1/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/Stage/Stack1/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "Stage/Stack1" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/cdk.out b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/cdk.out new file mode 100644 index 000000000..1e02a2deb --- /dev/null +++ b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/cdk.out @@ -0,0 +1 @@ +{"version":"40.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/manifest.json b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/manifest.json new file mode 100644 index 000000000..ecbb7d770 --- /dev/null +++ b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/manifest.json @@ -0,0 +1,33 @@ +{ + "version": "40.0.0", + "artifacts": { + "assembly-Stage": { + "type": "cdk:cloud-assembly", + "properties": { + "directoryName": "assembly-Stage", + "displayName": "Stage" + } + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + }, + "missing": [ + { + "key": "vpc-provider:account=123456789012:filter.isDefault=true:region=us-east-2:returnAsymmetricSubnets=true", + "provider": "vpc-provider", + "props": { + "account": "123456789012", + "region": "us-east-2", + "filter": { + "isDefault": "true" + }, + "returnAsymmetricSubnets": true, + "lookupRoleArn": "arn:${AWS::Partition}:iam::123456789012:role/cdk-hnb659fds-lookup-role-123456789012-us-east-2" + } + } + ] +} diff --git a/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/tree.json b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/tree.json new file mode 100644 index 000000000..00871b5fa --- /dev/null +++ b/packages/@aws-cdk/toolkit-lib/test/_fixtures/assembly-missing-context/cdk.out/tree.json @@ -0,0 +1 @@ +{"version":"tree-0.1","tree":{"id":"App","path":"","children":{"Stage":{"id":"Stage","path":"Stage","children":{"Stack1":{"id":"Stack1","path":"Stage/Stack1","children":{"CDKMetadata":{"id":"CDKMetadata","path":"Stage/Stack1/CDKMetadata","children":{"Default":{"id":"Default","path":"Stage/Stack1/CDKMetadata/Default","constructInfo":{"fqn":"aws-cdk-lib.CfnResource","version":"2.185.0"}},"Condition":{"id":"Condition","path":"Stage/Stack1/CDKMetadata/Condition","constructInfo":{"fqn":"aws-cdk-lib.CfnCondition","version":"2.185.0"}}},"constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"BootstrapVersion":{"id":"BootstrapVersion","path":"Stage/Stack1/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"2.185.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"Stage/Stack1/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"2.185.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"2.185.0"}}},"constructInfo":{"fqn":"aws-cdk-lib.Stage","version":"2.185.0"}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}},"constructInfo":{"fqn":"aws-cdk-lib.App","version":"2.185.0"}}} \ No newline at end of file diff --git a/packages/@aws-cdk/toolkit-lib/test/api/cloud-assembly/source-builder.test.ts b/packages/@aws-cdk/toolkit-lib/test/api/cloud-assembly/source-builder.test.ts index 182c84ba8..010b2a52e 100644 --- a/packages/@aws-cdk/toolkit-lib/test/api/cloud-assembly/source-builder.test.ts +++ b/packages/@aws-cdk/toolkit-lib/test/api/cloud-assembly/source-builder.test.ts @@ -310,6 +310,23 @@ describe('fromAssemblyDirectory', () => { await expect(() => cx.produce()).rejects.toThrow('This AWS CDK Toolkit is not compatible with the AWS CDK library used by your application'); }); + test('fails on missing context', async () => { + // WHEN + const cx = await cdkOutFixture(toolkit, 'assembly-missing-context'); + + // THEN + await expect(() => cx.produce()).rejects.toThrow(/Assembly contains missing context./); + }); + + test('no fail on missing context', async () => { + // WHEN + const cx = await cdkOutFixture(toolkit, 'assembly-missing-context', { failOnMissingContext: false }); + + // THEN + await using assembly = await cx.produce(); + expect(assembly.cloudAssembly.manifest.missing?.length).toEqual(1); + }); + test('can disable manifest version validation', async () => { // WHEN const cx = await cdkOutFixture(toolkit, 'manifest-from-the-future', { From d758c9f08fa37c92e7b3a401e6e492bbc1740161 Mon Sep 17 00:00:00 2001 From: Rohan Gupta <44989017+rohang9000@users.noreply.github.com> Date: Thu, 19 Jun 2025 05:14:17 -0400 Subject: [PATCH 3/3] docs: add .NET installation prerequisite to CONTRIBUTING.md (#612) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **.NET is required to be installed for initializing or building CDK apps in C# (and to run associated tests in repo) or else 7 tests fail during yarn build.** **Summary of all failing tests (without .NET installed):** FAIL test/cli/cdk-toolkit.test.ts (20.959 s) ● migrate › migrate call is idempotent ToolkitError: Could not add project AutoscalingCSharp.csproj to solution AutoscalingCSharp.sln. dotnet sln /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testrevTrx/AutoscalingCSharp/src/AutoscalingCSharp.sln add /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testrevTrx/AutoscalingCSharp/src/AutoscalingCSharp/AutoscalingCSharp.csproj exited with error code 127 106 | } catch (e: any) { 107 | if (attempt === MAX_ATTEMPTS) { > 108 | throw new ToolkitError(`Could not add project ${pname}.${ext} to solution ${pname}.sln. ${formatErrorMessage(e)}`); | ^ 109 | } 110 | 111 | // Sleep for a bit then try again at dotnetAddProject (lib/commands/init/init-hooks.ts:108:15) at InitTemplate.install (lib/commands/init/init.ts:279:5) at initializeProject (lib/commands/init/init.ts:515:3) at cliInit (lib/commands/init/init.ts:172:5) at generateCdkApp (lib/commands/migrate.ts:55:5) at CdkToolkit.migrate (lib/cli/cdk-toolkit.ts:1190:7) at test/cli/cdk-toolkit.test.ts:1557:5 at withTempDir (test/cli/cdk-toolkit.test.ts:1906:5) FAIL test/commands/migrate.test.ts (34.105 s) ● Migrate Function Tests › generateCdkApp generates the expected cdk app when called for csharp ToolkitError: Could not add project GoodCSharp.csproj to solution GoodCSharp.sln. dotnet sln /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testH5lbPD/GoodCSharp/src/GoodCSharp.sln add /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testH5lbPD/GoodCSharp/src/GoodCSharp/GoodCSharp.csproj exited with error code 127 106 | } catch (e: any) { 107 | if (attempt === MAX_ATTEMPTS) { > 108 | throw new ToolkitError(`Could not add project ${pname}.${ext} to solution ${pname}.sln. ${formatErrorMessage(e)}`); | ^ 109 | } 110 | 111 | // Sleep for a bit then try again at dotnetAddProject (lib/commands/init/init-hooks.ts:108:15) at InitTemplate.install (lib/commands/init/init.ts:279:5) at initializeProject (lib/commands/init/init.ts:515:3) at cliInit (lib/commands/init/init.ts:172:5) at generateCdkApp (lib/commands/migrate.ts:55:5) at test/commands/migrate.test.ts:308:5 at withTempDir (test/commands/migrate.test.ts:381:5) FAIL test/commands/init.test.ts (52.199 s) ● constructs version › verify "future flags" are added to cdk.json ToolkitError: Could not add project AwsCdkTestZQm0Yc.csproj to solution AwsCdkTestZQm0Yc.sln. dotnet sln /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testZQm0yc/src/AwsCdkTestZQm0Yc.sln add /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testZQm0yc/src/AwsCdkTestZQm0Yc/AwsCdkTestZQm0Yc.csproj exited with error code 127 106 | } catch (e: any) { 107 | if (attempt === MAX_ATTEMPTS) { > 108 | throw new ToolkitError(`Could not add project ${pname}.${ext} to solution ${pname}.sln. ${formatErrorMessage(e)}`); | ^ 109 | } 110 | 111 | // Sleep for a bit then try again at dotnetAddProject (lib/commands/init/init-hooks.ts:108:15) at InitTemplate.install (lib/commands/init/init.ts:279:5) at initializeProject (lib/commands/init/init.ts:515:3) at cliInit (lib/commands/init/init.ts:172:5) at test/commands/init.test.ts:392:11 at withTempDir (test/commands/init.test.ts:735:5) at Object. (test/commands/init.test.ts:391:9) ● constructs version › fsharp app with spaces ToolkitError: Could not add project AwsCdkTestWithSpaceCPiYtx.fsproj to solution AwsCdkTestWithSpaceCPiYtx.sln. dotnet sln '/var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-test with-spaceCPiYtx/src/AwsCdkTestWithSpaceCPiYtx.sln' add '/var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-test with-spaceCPiYtx/src/AwsCdkTestWithSpaceCPiYtx/AwsCdkTestWithSpaceCPiYtx.fsproj' exited with error code 127 106 | } catch (e: any) { 107 | if (attempt === MAX_ATTEMPTS) { > 108 | throw new ToolkitError(`Could not add project ${pname}.${ext} to solution ${pname}.sln. ${formatErrorMessage(e)}`); | ^ 109 | } 110 | 111 | // Sleep for a bit then try again at dotnetAddProject (lib/commands/init/init-hooks.ts:108:15) at InitTemplate.install (lib/commands/init/init.ts:279:5) at initializeProject (lib/commands/init/init.ts:515:3) at cliInit (lib/commands/init/init.ts:172:5) at test/commands/init.test.ts:290:5 at withTempDirWithSpaces (test/commands/init.test.ts:748:5) ● constructs version › csharp app with spaces ToolkitError: Could not add project AwsCdkTestWithSpacezbTern.csproj to solution AwsCdkTestWithSpacezbTern.sln. dotnet sln '/var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-test with-spacezbTERN/src/AwsCdkTestWithSpacezbTern.sln' add '/var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-test with-spacezbTERN/src/AwsCdkTestWithSpacezbTern/AwsCdkTestWithSpacezbTern.csproj' exited with error code 127 106 | } catch (e: any) { 107 | if (attempt === MAX_ATTEMPTS) { > 108 | throw new ToolkitError(`Could not add project ${pname}.${ext} to solution ${pname}.sln. ${formatErrorMessage(e)}`); | ^ 109 | } 110 | 111 | // Sleep for a bit then try again at dotnetAddProject (lib/commands/init/init-hooks.ts:108:15) at InitTemplate.install (lib/commands/init/init.ts:279:5) at initializeProject (lib/commands/init/init.ts:515:3) at cliInit (lib/commands/init/init.ts:172:5) at test/commands/init.test.ts:272:5 at withTempDirWithSpaces (test/commands/init.test.ts:748:5) ● constructs version › create a .NET app project in fsharp ToolkitError: Could not add project AwsCdkTestnKihpy.fsproj to solution AwsCdkTestnKihpy.sln. dotnet sln /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testnKIHPY/src/AwsCdkTestnKihpy.sln add /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testnKIHPY/src/AwsCdkTestnKihpy/AwsCdkTestnKihpy.fsproj exited with error code 127 106 | } catch (e: any) { 107 | if (attempt === MAX_ATTEMPTS) { > 108 | throw new ToolkitError(`Could not add project ${pname}.${ext} to solution ${pname}.sln. ${formatErrorMessage(e)}`); | ^ 109 | } 110 | 111 | // Sleep for a bit then try again at dotnetAddProject (lib/commands/init/init-hooks.ts:108:15) at InitTemplate.install (lib/commands/init/init.ts:279:5) at initializeProject (lib/commands/init/init.ts:515:3) at cliInit (lib/commands/init/init.ts:172:5) at test/commands/init.test.ts:250:5 at withTempDir (test/commands/init.test.ts:735:5) ● constructs version › create a .NET app project in csharp ToolkitError: Could not add project AwsCdkTestNkkhrd.csproj to solution AwsCdkTestNkkhrd.sln. dotnet sln /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testNkkhrd/src/AwsCdkTestNkkhrd.sln add /var/folders/50/dwz_h2694y1grnyh6y3hxw_r0000gq/T/aws-cdk-testNkkhrd/src/AwsCdkTestNkkhrd/AwsCdkTestNkkhrd.csproj exited with error code 127 106 | } catch (e: any) { 107 | if (attempt === MAX_ATTEMPTS) { > 108 | throw new ToolkitError(`Could not add project ${pname}.${ext} to solution ${pname}.sln. ${formatErrorMessage(e)}`); | ^ 109 | } 110 | 111 | // Sleep for a bit then try again at dotnetAddProject (lib/commands/init/init-hooks.ts:108:15) at InitTemplate.install (lib/commands/init/init.ts:279:5) at initializeProject (lib/commands/init/init.ts:515:3) at cliInit (lib/commands/init/init.ts:172:5) at test/commands/init.test.ts:228:5 at withTempDir (test/commands/init.test.ts:735:5) Fixes # --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license Co-authored-by: Momo Kornher --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 58f61c9c4..a0411b155 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,6 +27,8 @@ contributing guide will focus on technical aspects. - [Yarn >= 1.19.1, < 2](https://yarnpkg.com/lang/en/docs/install) - [Docker >= 19.03](https://docs.docker.com/get-docker/) - the Docker daemon must also be running +- [.NET SDK >= 6.0](https://dotnet.microsoft.com/en-us/download) + - required for initializing or building CDK apps in C# (.csproj) We recommend that you use [Visual Studio Code](https://code.visualstudio.com/) to work on the CDK. We use `ESLint` to keep our code consistent in terms of