Skip to content

Commit

Permalink
chore(toolkit): synth action with tests (#32971)
Browse files Browse the repository at this point in the history
### Issue 

Closes #32940 

### Description of changes

Define the API for the synth action. Includes DX improvements for some other APIs.

### Describe any new or updated permissions being added

n/a

### Description of how you validated changes

These are the tests!

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
mrgrain authored Jan 17, 2025
1 parent 2afdf25 commit 63b0936
Show file tree
Hide file tree
Showing 42 changed files with 1,989 additions and 211 deletions.
1 change: 1 addition & 0 deletions aws-cdk.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"name": "aws-custom-resource-sdk-adapter",
"rootPath": "packages/@aws-cdk/aws-custom-resource-sdk-adapter"
},
{ "name": "toolkit", "rootPath": "packages/@aws-cdk/toolkit" },
{ "name": "user-input-gen", "rootPath": "tools/@aws-cdk/user-input-gen" }
]
},
Expand Down
4 changes: 4 additions & 0 deletions packages/@aws-cdk/toolkit/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ build-info.json
lib/**/*.wasm
lib/**/*.yaml

# Include test resources
!test/_fixtures/**/app.js
!test/_fixtures/**/cdk.out

# Include config files
!.eslintrc.js
!jest.config.js
4 changes: 3 additions & 1 deletion packages/@aws-cdk/toolkit/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module.exports = {
...baseConfig,
coverageThreshold: {
global: {
...baseConfig.coverageThreshold.global,
// this is very sad but we will get better
branches: 27,
statements: 53,
},
},
};
2 changes: 1 addition & 1 deletion packages/@aws-cdk/toolkit/lib/actions/synth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export interface SynthOptions {
/**
* Select the stacks
*/
readonly stacks: StackSelector;
readonly stacks?: StackSelector;

/**
* After synthesis, validate stacks with the "validateOnSynth" attribute set (can also be controlled with CDK_VALIDATION)
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/toolkit/lib/actions/watch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ export interface WatchOptions extends BaseDeployOptions {
readonly watchDir?: string;

/**
* The output to write CloudFormation template to
* The output directory to write CloudFormation template to
*
* @deprecated this should be grabbed from the cloud assembly itself
*/
readonly output?: string;
readonly outdir?: string;
}

export function patternsArrayForWatch(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './context-aware-source';
export * from './exec';
export * from './prepare-source';
export * from './source-builder';
export * from './stack-selectors';
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,24 @@ import * as cxschema from '@aws-cdk/cloud-assembly-schema';
import * as cxapi from '@aws-cdk/cx-api';
import * as fs from 'fs-extra';
import { lte } from 'semver';
import type { AppSynthOptions } from './source-builder';
import { prepareDefaultEnvironment as oldPrepare, prepareContext, spaceAvailableForContext, Settings, loadTree, some, splitBySize, versionNumber } from '../../../api/aws-cdk';
import { ToolkitServices } from '../../../toolkit/private';
import { ToolkitError } from '../../errors';
import { ActionAwareIoHost, asLogger, error } from '../../io/private';
import type { AppSynthOptions } from '../source-builder';

export { guessExecutable } from '../../../api/aws-cdk';

type Env = { [key: string]: string };
type Context = { [key: string]: any };

/**
* Turn the given optional output directory into a fixed output directory
*/
export function determineOutputDirectory(outdir?: string) {
return outdir ?? fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'cdk.out'));
}

/**
* If we don't have region/account defined in context, we fall back to the default SDK behavior
* where region is retrieved from ~/.aws/config and account is based on default credentials provider
Expand Down
Original file line number Diff line number Diff line change
@@ -1,47 +1,13 @@
import * as cxapi from '@aws-cdk/cx-api';

import * as fs from 'fs-extra';
import type { ICloudAssemblySource } from '../';
import { ContextAwareCloudAssembly, ContextAwareCloudAssemblyProps } from './context-aware-source';
import { execInChildProcess } from './exec';
import { assemblyFromDirectory, changeDir, guessExecutable, prepareDefaultEnvironment, withContext, withEnv } from './prepare-source';
import { assemblyFromDirectory, changeDir, determineOutputDirectory, guessExecutable, prepareDefaultEnvironment, withContext, withEnv } from './prepare-source';
import { ToolkitServices } from '../../../toolkit/private';
import { Context, ILock, RWLock } from '../../aws-cdk';
import { ToolkitError } from '../../errors';
import { debug } from '../../io/private';

/**
* Configuration for creating a CLI from an AWS CDK App directory
*/
export interface CdkAppSourceProps {
/**
* @default - current working directory
*/
readonly workingDirectory?: string;

/**
* Emits the synthesized cloud assembly into a directory
*
* @default cdk.out
*/
readonly output?: string;

/**
* Perform context lookups.
*
* Synthesis fails if this is disabled and context lookups need to be performed.
*
* @default true
*/
readonly lookups?: boolean;

/**
* Options that are passed through the context to a CDK app on synth
*/
readonly synthOptions?: AppSynthOptions;
}

export type AssemblyBuilder = (context: Record<string, any>) => Promise<cxapi.CloudAssembly>;
import { AssemblyBuilder, CdkAppSourceProps } from '../source-builder';

export abstract class CloudAssemblySourceBuilder {

Expand Down Expand Up @@ -69,10 +35,14 @@ export abstract class CloudAssemblySourceBuilder {
return new ContextAwareCloudAssembly(
{
produce: async () => {
const env = await prepareDefaultEnvironment(services, { outdir: props.output });
const outdir = determineOutputDirectory(props.outdir);
const env = await prepareDefaultEnvironment(services, { outdir });
return changeDir(async () =>
withContext(context.all, env, props.synthOptions ?? {}, async (envWithContext, ctx) =>
withEnv(envWithContext, () => builder(ctx)),
withEnv(envWithContext, () => builder({
outdir,
context: ctx,
})),
), props.workingDirectory);
},
},
Expand Down Expand Up @@ -133,7 +103,7 @@ export abstract class CloudAssemblySourceBuilder {
// }

const commandLine = await guessExecutable(app);
const outdir = props.output ?? 'cdk.out';
const outdir = props.outdir ?? 'cdk.out';

try {
fs.mkdirpSync(outdir);
Expand All @@ -158,65 +128,3 @@ export abstract class CloudAssemblySourceBuilder {
}
}

/**
* Settings that are passed to a CDK app via the context
*/
export interface AppSynthOptions {
/**
* Debug the CDK app.
* Logs additional information during synthesis, such as creation stack traces of tokens.
* This also sets the `CDK_DEBUG` env variable and will slow down synthesis.
*
* @default false
*/
readonly debug?: boolean;

/**
* Enables the embedding of the "aws:cdk:path" in CloudFormation template metadata.
*
* @default true
*/
readonly pathMetadata?: boolean;

/**
* Enable the collection and reporting of version information.
*
* @default true
*/
readonly versionReporting?: boolean;

/**
* Whe enabled, `aws:asset:xxx` metadata entries are added to the template.
*
* Disabling this can be useful in certain cases like integration tests.
*
* @default true
*/
readonly assetMetadata?: boolean;

/**
* Enable asset staging.
*
* Disabling asset staging means that copyable assets will not be copied to the
* output directory and will be referenced with absolute paths.
*
* Not copied to the output directory: this is so users can iterate on the
* Lambda source and run SAM CLI without having to re-run CDK (note: we
* cannot achieve this for bundled assets, if assets are bundled they
* will have to re-run CDK CLI to re-bundle updated versions).
*
* Absolute path: SAM CLI expects `cwd`-relative paths in a resource's
* `aws:asset:path` metadata. In order to be predictable, we will always output
* absolute paths.
*
* @default true
*/
readonly assetStaging?: boolean;

/**
* Select which stacks should have asset bundling enabled
*
* @default ["**"] - all stacks
*/
readonly bundlingForStacks?: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { StackSelectionStrategy, StackSelector } from '../stack-selector';

export const ALL_STACKS: StackSelector = {
strategy: StackSelectionStrategy.ALL_STACKS,
};
109 changes: 109 additions & 0 deletions packages/@aws-cdk/toolkit/lib/api/cloud-assembly/source-builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import type * as cxapi from '@aws-cdk/cx-api';

export interface AppProps {
/**
* The output directory into which to the builder app will emit synthesized artifacts.
*/
readonly outdir?: string;

/**
* The context provided tp the builder app to synthesize the Cloud Assembly.
*/
readonly context?: { [key: string]: any };
}

export type AssemblyBuilder = (props: AppProps) => Promise<cxapi.CloudAssembly>;

/**
* Configuration for creating a CLI from an AWS CDK App directory
*/
export interface CdkAppSourceProps {
/**
* @default - current working directory
*/
readonly workingDirectory?: string;

/**
* Emits the synthesized cloud assembly into a directory
*
* @default cdk.out
*/
readonly outdir?: string;

/**
* Perform context lookups.
*
* Synthesis fails if this is disabled and context lookups need to be performed.
*
* @default true
*/
readonly lookups?: boolean;

/**
* Options that are passed through the context to a CDK app on synth
*/
readonly synthOptions?: AppSynthOptions;
}

/**
* Settings that are passed to a CDK app via the context
*/
export interface AppSynthOptions {
/**
* Debug the CDK app.
* Logs additional information during synthesis, such as creation stack traces of tokens.
* This also sets the `CDK_DEBUG` env variable and will slow down synthesis.
*
* @default false
*/
readonly debug?: boolean;

/**
* Enables the embedding of the "aws:cdk:path" in CloudFormation template metadata.
*
* @default true
*/
readonly pathMetadata?: boolean;

/**
* Enable the collection and reporting of version information.
*
* @default true
*/
readonly versionReporting?: boolean;

/**
* Whe enabled, `aws:asset:xxx` metadata entries are added to the template.
*
* Disabling this can be useful in certain cases like integration tests.
*
* @default true
*/
readonly assetMetadata?: boolean;

/**
* Enable asset staging.
*
* Disabling asset staging means that copyable assets will not be copied to the
* output directory and will be referenced with absolute paths.
*
* Not copied to the output directory: this is so users can iterate on the
* Lambda source and run SAM CLI without having to re-run CDK (note: we
* cannot achieve this for bundled assets, if assets are bundled they
* will have to re-run CDK CLI to re-bundle updated versions).
*
* Absolute path: SAM CLI expects `cwd`-relative paths in a resource's
* `aws:asset:path` metadata. In order to be predictable, we will always output
* absolute paths.
*
* @default true
*/
readonly assetStaging?: boolean;

/**
* Select which stacks should have asset bundling enabled
*
* @default ["**"] - all stacks
*/
readonly bundlingForStacks?: string;
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/toolkit/lib/api/io/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './io-host';
export * from './io-message';
Loading

0 comments on commit 63b0936

Please sign in to comment.