diff --git a/packages/@aws-cdk/toolkit-lib/lib/api/io/toolkit-action.ts b/packages/@aws-cdk/toolkit-lib/lib/api/io/toolkit-action.ts index a5abd05b2..cd12baa2a 100644 --- a/packages/@aws-cdk/toolkit-lib/lib/api/io/toolkit-action.ts +++ b/packages/@aws-cdk/toolkit-lib/lib/api/io/toolkit-action.ts @@ -7,6 +7,7 @@ export type ToolkitAction = | 'synth' | 'list' | 'diff' +| 'publish' | 'deploy' | 'drift' | 'rollback' diff --git a/packages/aws-cdk/lib/cli/cdk-toolkit.ts b/packages/aws-cdk/lib/cli/cdk-toolkit.ts index b22eed419..588273fbe 100644 --- a/packages/aws-cdk/lib/cli/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cli/cdk-toolkit.ts @@ -374,6 +374,30 @@ export class CdkToolkit { return diffs && options.fail ? 1 : 0; } + public async publish(options: PublishOptions) { + const buildAsset = async (assetNode: AssetBuildNode) => { + await this.props.deployments.buildSingleAsset( + assetNode.assetManifestArtifact, + assetNode.assetManifest, + assetNode.asset, + { + stack: assetNode.parentStack, + roleArn: options.roleArn, + stackName: assetNode.parentStack.stackName, + }, + ); + }; + + const publishAsset = async (assetNode: AssetPublishNode) => { + await this.props.deployments.publishSingleAsset(assetNode.assetManifest, assetNode.asset, { + stack: assetNode.parentStack, + roleArn: options.roleArn, + stackName: assetNode.parentStack.stackName, + forcePublish: options.force, + }); + }; + } + public async deploy(options: DeployOptions) { if (options.watch) { return this.watch(options); @@ -1679,6 +1703,19 @@ interface WatchOptions extends Omit { readonly concurrency?: number; } +export interface PublishOptions { + /** + * Role to pass to CloudFormation for asset publishing + */ + roleArn?: string; + + /** + * Always publish, even if it already exists + * @default false + */ + force?: boolean; +} + export interface DeployOptions extends CfnDeployOptions, WatchOptions { /** * ARNs of SNS topics that CloudFormation will notify with stack related events diff --git a/packages/aws-cdk/lib/cli/cli-config.ts b/packages/aws-cdk/lib/cli/cli-config.ts index 841056488..f7f35d75d 100644 --- a/packages/aws-cdk/lib/cli/cli-config.ts +++ b/packages/aws-cdk/lib/cli/cli-config.ts @@ -136,6 +136,12 @@ export async function makeConfig(): Promise { concurrency: { type: 'number', alias: ['n'], desc: 'Maximum number of simultaneous synths to execute.', default: 4, requiresArg: true }, }, }, + 'publish': { + description: 'Publishes synthesized assets (e.g. Docker images, Lambda ZIPs, S3 files) to their destinations', + options: { + force: { alias: 'f', type: 'boolean', desc: 'Always publish, even if it already exists', default: false }, + }, + }, 'deploy': { description: 'Deploys the stack(s) named STACKS into your AWS account', options: { diff --git a/packages/aws-cdk/lib/cli/cli-type-registry.json b/packages/aws-cdk/lib/cli/cli-type-registry.json index 439316754..599d5524e 100644 --- a/packages/aws-cdk/lib/cli/cli-type-registry.json +++ b/packages/aws-cdk/lib/cli/cli-type-registry.json @@ -407,6 +407,17 @@ } } }, + "publish": { + "description": "Publishes synthesized assets (e.g. Docker images, Lambda ZIPs, S3 files) to their destinations", + "options": { + "force": { + "alias": "f", + "type": "boolean", + "desc": "Always publish, even if it already exists", + "default": false + } + } + }, "deploy": { "description": "Deploys the stack(s) named STACKS into your AWS account", "options": { diff --git a/packages/aws-cdk/lib/cli/cli.ts b/packages/aws-cdk/lib/cli/cli.ts index 4e2f68df1..acae82ff0 100644 --- a/packages/aws-cdk/lib/cli/cli.ts +++ b/packages/aws-cdk/lib/cli/cli.ts @@ -372,6 +372,13 @@ export async function exec(args: string[], synthesizer?: Synthesizer): Promise): any { requiresArg: true, }), ) + .command('publish', 'Publishes synthesized assets (e.g. Docker images, Lambda ZIPs, S3 files) to their destinations', (yargs: Argv) => + yargs.option('force', { + default: false, + alias: 'f', + type: 'boolean', + desc: 'Always publish, even if it already exists', + }), + ) .command('deploy [STACKS..]', 'Deploys the stack(s) named STACKS into your AWS account', (yargs: Argv) => yargs .option('all', { diff --git a/packages/aws-cdk/lib/cli/user-configuration.ts b/packages/aws-cdk/lib/cli/user-configuration.ts index 733f56a83..73ff33f80 100644 --- a/packages/aws-cdk/lib/cli/user-configuration.ts +++ b/packages/aws-cdk/lib/cli/user-configuration.ts @@ -17,6 +17,7 @@ export enum Command { LIST = 'list', DIFF = 'diff', BOOTSTRAP = 'bootstrap', + PUBLISH = 'publish', DEPLOY = 'deploy', DESTROY = 'destroy', SYNTHESIZE = 'synthesize', diff --git a/packages/aws-cdk/lib/cli/user-input.ts b/packages/aws-cdk/lib/cli/user-input.ts index 9d3f9cc11..64061e820 100644 --- a/packages/aws-cdk/lib/cli/user-input.ts +++ b/packages/aws-cdk/lib/cli/user-input.ts @@ -50,6 +50,11 @@ export interface UserInput { */ readonly flags?: FlagsOptions; + /** + * Publishes synthesized assets (e.g. Docker images, Lambda ZIPs, S3 files) to their destinations + */ + readonly publish?: PublishOptions; + /** * Deploys the stack(s) named STACKS into your AWS account */ @@ -710,6 +715,22 @@ export interface FlagsOptions { readonly FLAGNAME?: Array; } +/** + * Publishes synthesized assets (e.g. Docker images, Lambda ZIPs, S3 files) to their destinations + * + * @struct + */ +export interface PublishOptions { + /** + * Always publish, even if it already exists + * + * aliases: f + * + * @default - false + */ + readonly force?: boolean; +} + /** * Deploys the stack(s) named STACKS into your AWS account * diff --git a/packages/aws-cdk/test/cli/cli-arguments.test.ts b/packages/aws-cdk/test/cli/cli-arguments.test.ts index 3c3269361..18a54f0a7 100644 --- a/packages/aws-cdk/test/cli/cli-arguments.test.ts +++ b/packages/aws-cdk/test/cli/cli-arguments.test.ts @@ -125,6 +125,7 @@ describe('config', () => { }), context: expect.anything(), acknowledge: expect.anything(), + publish: expect.anything(), deploy: expect.anything(), destroy: expect.anything(), diff: expect.anything(),