Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,8 @@ class BoundAppStagingSynthesizer extends StackSynthesizer implements IBoundAppSt
bucketName: translateCfnTokenToAssetToken(bucketName),
bucketPrefix: prefix,
role: assumeRoleArn ? { assumeRoleArn: translateCfnTokenToAssetToken(assumeRoleArn) } : undefined,
}, {
displayName: asset.displayName,
});

if (dependencyStack) {
Expand All @@ -359,6 +361,8 @@ class BoundAppStagingSynthesizer extends StackSynthesizer implements IBoundAppSt
const location = this.assetManifest.defaultAddDockerImageAsset(this.boundStack, asset, {
repositoryName: translateCfnTokenToAssetToken(repoName),
role: assumeRoleArn ? { assumeRoleArn: translateCfnTokenToAssetToken(assumeRoleArn) } : undefined,
}, {
displayName: asset.displayName,
});

if (dependencyStack) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ describe(AppStagingSynthesizer, () => {

expect(firstFile).toEqual({
source: { path: 'Stack.template.json', packaging: 'file' },
displayName: 'Stack Template',
destinations: {
'000000000000-us-east-1': {
bucketName: `cdk-${APP_ID}-staging-000000000000-us-east-1`,
Expand Down Expand Up @@ -97,6 +98,7 @@ describe(AppStagingSynthesizer, () => {

expect(firstFile).toEqual({
source: { path: 'Stack2.template.json', packaging: 'file' },
displayName: 'Stack2 Template',
destinations: {
'111111111111-us-east-2': {
bucketName: `cdk-${APP_ID}-staging-111111111111-us-east-2`,
Expand Down Expand Up @@ -211,6 +213,7 @@ describe(AppStagingSynthesizer, () => {
const firstFile = manifest.files![Object.keys(manifest.files!)[0]];
const assetHash = '68539effc3f7ad46fff9765606c2a01b7f7965833643ab37e62799f19a37f650';
expect(firstFile).toEqual({
displayName: 'Lambda/Code',
source: {
packaging: 'zip',
path: `asset.${assetHash}`,
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/cx-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,12 @@
"semver": "^7.7.1"
},
"peerDependencies": {
"@aws-cdk/cloud-assembly-schema": "^40.6.0"
"@aws-cdk/cloud-assembly-schema": "^41.0.0"
},
"license": "Apache-2.0",
"devDependencies": {
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/cloud-assembly-schema": "^40.7.0",
"@aws-cdk/cloud-assembly-schema": "^41.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/jest": "^29.5.14",
"@types/mock-fs": "^4.13.4",
Expand Down
3 changes: 3 additions & 0 deletions packages/aws-cdk-lib/aws-ecr-assets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'MyBuildImage', {
directory: path.join(__dirname, 'my-image'),

// Optional: describe the purpose of the asset with a human-readable string
displayName: 'Source for my function',
});
```

Expand Down
26 changes: 25 additions & 1 deletion packages/aws-cdk-lib/aws-ecr-assets/lib/image-asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from 'path';
import { Construct } from 'constructs';
import { FingerprintOptions, FollowMode, IAsset } from '../../assets';
import * as ecr from '../../aws-ecr';
import { Annotations, AssetStaging, FeatureFlags, FileFingerprintOptions, IgnoreMode, Stack, SymlinkFollowMode, Token, Stage, CfnResource } from '../../core';
import { Annotations, AssetStaging, FeatureFlags, FileFingerprintOptions, IgnoreMode, Stack, SymlinkFollowMode, Token, Stage, CfnResource, Names } from '../../core';
import * as cxapi from '../../cx-api';

/**
Expand Down Expand Up @@ -314,6 +314,29 @@ export interface DockerImageAssetOptions extends FingerprintOptions, FileFingerp
* @default - cache is used
*/
readonly cacheDisabled?: boolean;

/**
* A display name for this asset
*
* If supplied, the display name will be used in locations where the asset
* identifier is printed, like in the CLI progress information. If the same
* asset is added multiple times, the display name of the first occurrence is
* used.
*
* If `assetName` is given, it will also be used as the default `displayName`.
* Otherwise, the default is the construct path of the ImageAsset construct,
* with respect to the enclosing stack. If the asset is produced by a
* construct helper function (such as `lambda.Code.fromAssetImage()`), this
* will look like `MyFunction/AssetImage`.
*
* We use the stack-relative construct path so that in the common case where
* you have multiple stacks with the same asset, we won't show something like
* `/MyBetaStack/MyFunction/Code` when you are actually deploying to
* production.
*
* @default - Stack-relative construct path
*/
readonly displayName?: string;
}

/**
Expand Down Expand Up @@ -534,6 +557,7 @@ export class DockerImageAsset extends Construct implements IAsset {
dockerCacheFrom: this.dockerCacheFrom,
dockerCacheTo: this.dockerCacheTo,
dockerCacheDisabled: this.dockerCacheDisabled,
displayName: props.displayName ?? props.assetName ?? Names.stackRelativeConstructPath(this),
});

this.repository = ecr.Repository.fromRepositoryName(this, 'Repository', location.repositoryName);
Expand Down
25 changes: 24 additions & 1 deletion packages/aws-cdk-lib/aws-ecr-assets/lib/tarball-asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as path from 'path';
import { Construct } from 'constructs';
import { IAsset } from '../../assets';
import * as ecr from '../../aws-ecr';
import { AssetStaging, Stack, Stage } from '../../core';
import { AssetStaging, Names, Stack, Stage } from '../../core';

/**
* Options for TarballImageAsset
Expand All @@ -17,6 +17,28 @@ export interface TarballImageAssetProps {
* is located as a resource inside your project.
*/
readonly tarballFile: string;

/**
* A display name for this asset
*
* If supplied, the display name will be used in locations where the asset
* identifier is printed, like in the CLI progress information. If the same
* asset is added multiple times, the display name of the first occurrence is
* used.
*
* The default is the construct path of the `TarballImageAsset` construct,
* with respect to the enclosing stack. If the asset is produced by a
* construct helper function (such as `lambda.Code.fromAssetImage()`), this
* will look like `MyFunction/AssetImage`.
*
* We use the stack-relative construct path so that in the common case where
* you have multiple stacks with the same asset, we won't show something like
* `/MyBetaStack/MyFunction/Code` when you are actually deploying to
* production.
*
* @default - Stack-relative construct path
*/
readonly displayName?: string;
}

/**
Expand Down Expand Up @@ -79,6 +101,7 @@ export class TarballImageAsset extends Construct implements IAsset {
'-c',
`docker load -i ${relativePathInOutDir} | tail -n 1 | sed "s/Loaded image: //g"`,
],
displayName: props.displayName ?? Names.stackRelativeConstructPath(this),
});

this.repository = ecr.Repository.fromRepositoryName(this, 'Repository', location.repositoryName);
Expand Down
23 changes: 23 additions & 0 deletions packages/aws-cdk-lib/aws-s3-assets/lib/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ export interface AssetOptions extends CopyOptions, cdk.FileCopyOptions, cdk.Asse
* @default - the default server-side encryption with Amazon S3 managed keys(SSE-S3) key will be used.
*/
readonly sourceKMSKey?: kms.IKey;

/**
* A display name for this asset
*
* If supplied, the display name will be used in locations where the asset
* identifier is printed, like in the CLI progress information. If the same
* asset is added multiple times, the display name of the first occurrence is
* used.
*
* The default is the construct path of the Asset construct, with respect to
* the enclosing stack. If the asset is produced by a construct helper
* function (such as `lambda.Code.fromAsset()`), this will look like
* `MyFunction/Code`.
*
* We use the stack-relative construct path so that in the common case where
* you have multiple stacks with the same asset, we won't show something like
* `/MyBetaStack/MyFunction/Code` when you are actually deploying to
* production.
*
* @default - Stack-relative construct path
*/
readonly displayName?: string;
}

export interface AssetProps extends AssetOptions {
Expand Down Expand Up @@ -173,6 +195,7 @@ export class Asset extends Construct implements cdk.IAsset {
sourceHash: this.sourceHash,
fileName: this.assetPath,
deployTime: props.deployTime,
displayName: props.displayName ?? cdk.Names.stackRelativeConstructPath(this),
});

this.s3BucketName = location.bucketName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class TestStack extends cdk.Stack {
/// !show
const asset = new assets.Asset(this, 'SampleAsset', {
path: path.join(__dirname, 'file-asset.txt'),

// Optional: describe the purpose of the asset with a human-readable string
displayName: 'My file',
});
/// !hide

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export class ProductStack extends cdk.Stack {
packaging: cdk.FileAssetPackaging.FILE,
sourceHash: templateHash,
fileName: this.templateFile,
displayName: `${this.node.path} Template`,
}).httpUrl;

if (this._parentProductStackHistory) {
Expand Down
20 changes: 20 additions & 0 deletions packages/aws-cdk-lib/core/lib/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,16 @@ export interface FileAssetSource {
* @default false
*/
readonly deployTime?: boolean;

/**
* A display name for this asset
*
* If supplied, the display name will be used in locations where the asset
* identifier is printed, like in the CLI progress information.
*
* @default - The asset hash is used to display the asset
*/
readonly displayName?: string;
}

export interface DockerImageAssetSource {
Expand Down Expand Up @@ -291,6 +301,16 @@ export interface DockerImageAssetSource {
* @default - cache is used
*/
readonly dockerCacheDisabled?: boolean;

/**
* A display name for this asset
*
* If supplied, the display name will be used in locations where the asset
* identifier is printed, like in the CLI progress information.
*
* @default - The asset hash is used to display the asset
*/
readonly displayName?: string;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export abstract class CustomResourceProviderBase extends Construct {
fileName: assetFileName,
sourceHash: staging.assetHash,
packaging: FileAssetPackaging.ZIP_DIRECTORY,
displayName: `${this.node.path} Code`,
});

this._codeHash = staging.assetHash;
Expand Down
36 changes: 33 additions & 3 deletions packages/aws-cdk-lib/core/lib/names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,42 @@ export class Names {
public static uniqueResourceName(construct: IConstruct, options: UniqueResourceNameOptions) {
const node = Node.of(construct);

const componentsPath = node.scopes.slice(node.scopes.indexOf(node.scopes.reverse()
.find(component => (Stack.isStack(component) && !unresolved(component.stackName)))!,
)).map(component => Stack.isStack(component) && !unresolved(component.stackName) ? component.stackName : Node.of(component).id);
const scopes = node.scopes;
const isStack = scopes.map(isTopLevelStack);
const lastStackIndex = Math.max(findLastIndex(isStack, x => x), 0);

const componentsPath = node.scopes
.slice(lastStackIndex)
.map(component => isTopLevelStack(component) ? component.stackName : Node.of(component).id);

return makeUniqueResourceName(componentsPath, options);
}

/**
* Return the construct path of the given construct, starting at the nearest enclosing Stack
*
* Skips over Nested Stacks, in other words Nested Stacks are included in the construct
* paths.
*/
public static stackRelativeConstructPath(construct: IConstruct): string {
const scopes = construct.node.scopes;
const isStack = scopes.map(isTopLevelStack);
const lastStackIndex = findLastIndex(isStack, x => x);
return scopes.slice(lastStackIndex + 1).map(x => x.node.id).join('/');
}

private constructor() {}
}

function isTopLevelStack(x: IConstruct): x is Stack {
return Stack.isStack(x) && !unresolved(x.stackName);
}

function findLastIndex<A>(xs: A[], pred: (x: A) => boolean): number {
for (let i = xs.length - 1; i >= 0; i--) {
if (pred(xs[i])) {
return i;
}
}
return -1;
}
1 change: 1 addition & 0 deletions packages/aws-cdk-lib/core/lib/nested-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export class NestedStack extends Stack {
packaging: FileAssetPackaging.FILE,
sourceHash: templateHash,
fileName: this.templateFile,
displayName: `${this.stackName} Template`,
});

this.addResourceMetadata(this.resource, 'TemplateURL');
Expand Down
Loading