diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/ecr/source-action.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/ecr/source-action.ts index a7e4c6cf8ce7b..a86faabe50b60 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/ecr/source-action.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/ecr/source-action.ts @@ -1,10 +1,10 @@ import { Construct } from 'constructs'; import * as codepipeline from '../../../aws-codepipeline'; -import * as ecr from '../../../aws-ecr'; import { Rule } from '../../../aws-events'; import * as targets from '../../../aws-events-targets'; import * as iam from '../../../aws-iam'; import { Names } from '../../../core'; +import { IRepositoryRef } from '../../../interfaces/generated/aws-ecr-interfaces.generated'; import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; @@ -49,7 +49,7 @@ export interface EcrSourceActionProps extends codepipeline.CommonAwsActionProps /** * The repository that will be watched for changes. */ - readonly repository: ecr.IRepository; + readonly repository: IRepositoryRef; } /** @@ -65,7 +65,6 @@ export class EcrSourceAction extends Action { constructor(props: EcrSourceActionProps) { super({ ...props, - resource: props.repository, category: codepipeline.ActionCategory.SOURCE, provider: 'ECR', artifactBounds: sourceArtifactBounds(), @@ -90,7 +89,7 @@ export class EcrSourceAction extends Action { codepipeline.ActionConfig { options.role.addToPolicy(new iam.PolicyStatement({ actions: ['ecr:DescribeImages'], - resources: [this.props.repository.repositoryArn], + resources: [this.props.repository.repositoryRef.repositoryArn], })); new Rule(scope, Names.nodeUniqueId(stage.pipeline.node) + 'SourceEventRule', { @@ -102,7 +101,7 @@ export class EcrSourceAction extends Action { source: ['aws.ecr'], detail: { 'result': ['SUCCESS'], - 'repository-name': [this.props.repository.repositoryName], + 'repository-name': [this.props.repository.repositoryRef.repositoryName], 'image-tag': [this.props.imageTag === '' ? undefined : (this.props.imageTag ?? 'latest')], 'action-type': ['PUSH'], }, @@ -114,7 +113,7 @@ export class EcrSourceAction extends Action { return { configuration: { - RepositoryName: this.props.repository.repositoryName, + RepositoryName: this.props.repository.repositoryRef.repositoryName, ImageTag: this.props.imageTag ? this.props.imageTag : undefined, // `''` is falsy in JS/TS }, }; diff --git a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/inspector/ecr-image-scan-action.ts b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/inspector/ecr-image-scan-action.ts index 50082f59cd16c..5c2483cb1c081 100644 --- a/packages/aws-cdk-lib/aws-codepipeline-actions/lib/inspector/ecr-image-scan-action.ts +++ b/packages/aws-cdk-lib/aws-codepipeline-actions/lib/inspector/ecr-image-scan-action.ts @@ -3,6 +3,7 @@ import { InspectorScanActionBase, InspectorScanActionBaseProps } from './scan-ac import * as codepipeline from '../../../aws-codepipeline'; import * as ecr from '../../../aws-ecr'; import * as iam from '../../../aws-iam'; +import { IRepositoryRef } from '../../../interfaces/generated/aws-ecr-interfaces.generated'; /** * Construction properties of the `InspectorEcrImageScanAction`. @@ -11,7 +12,7 @@ export interface InspectorEcrImageScanActionProps extends InspectorScanActionBas /** * The Amazon ECR repository where the image is pushed. */ - readonly repository: ecr.IRepository; + readonly repository: IRepositoryRef; /** * The tag used for the image. @@ -35,7 +36,7 @@ export class InspectorEcrImageScanAction extends InspectorScanActionBase { protected renderActionConfiguration(): Record { return { InspectorRunMode: 'ECRImageScan', - ECRRepositoryName: this.ecrProps.repository.repositoryName, + ECRRepositoryName: this.ecrProps.repository.repositoryRef.repositoryName, ImageTag: this.ecrProps.imageTag, }; } @@ -46,7 +47,7 @@ export class InspectorEcrImageScanAction extends InspectorScanActionBase { // see: https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-InspectorScan.html#edit-role-InspectorScan options.role.addToPrincipalPolicy(new iam.PolicyStatement({ - resources: [this.ecrProps.repository.repositoryArn], + resources: [this.ecrProps.repository.repositoryRef.repositoryArn], actions: [ 'ecr:GetDownloadUrlForLayer', 'ecr:BatchGetImage', diff --git a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts index 9a8c70477eee6..5ca36f983b37b 100644 --- a/packages/aws-cdk-lib/aws-ecr/lib/repository.ts +++ b/packages/aws-cdk-lib/aws-ecr/lib/repository.ts @@ -27,6 +27,7 @@ import { import { addConstructMetadata, MethodMetadata } from '../../core/lib/metadata-resource'; import { propertyInjectable } from '../../core/lib/prop-injectable'; import { AutoDeleteImagesProvider } from '../../custom-resource-handlers/dist/aws-ecr/auto-delete-images-provider.generated'; +import { IRepositoryRef, RepositoryReference } from '../../interfaces/generated/aws-ecr-interfaces.generated'; const AUTO_DELETE_IMAGES_RESOURCE_TYPE = 'Custom::ECRAutoDeleteImages'; const AUTO_DELETE_IMAGES_TAG = 'aws-cdk:auto-delete-images'; @@ -34,7 +35,7 @@ const AUTO_DELETE_IMAGES_TAG = 'aws-cdk:auto-delete-images'; /** * Represents an ECR repository. */ -export interface IRepository extends IResource { +export interface IRepository extends IResource, IRepositoryRef { /** * The name of the repository * @attribute @@ -191,6 +192,16 @@ export abstract class RepositoryBase extends Resource implements IRepository { */ public abstract readonly repositoryArn: string; + /** + * A reference to this repository + */ + public get repositoryRef(): RepositoryReference { + return { + repositoryName: this.repositoryName, + repositoryArn: this.repositoryArn, + }; + } + /** * Add a policy statement to the repository's resource policy */ diff --git a/packages/aws-cdk-lib/pipelines/lib/codepipeline/codepipeline-source.ts b/packages/aws-cdk-lib/pipelines/lib/codepipeline/codepipeline-source.ts index 4cc832a6604e0..9fd89e8f33d0b 100644 --- a/packages/aws-cdk-lib/pipelines/lib/codepipeline/codepipeline-source.ts +++ b/packages/aws-cdk-lib/pipelines/lib/codepipeline/codepipeline-source.ts @@ -6,10 +6,10 @@ import * as cp from '../../../aws-codepipeline'; import { Artifact } from '../../../aws-codepipeline'; import * as cp_actions from '../../../aws-codepipeline-actions'; import { Action, CodeCommitTrigger, GitHubTrigger, S3Trigger } from '../../../aws-codepipeline-actions'; -import { IRepository } from '../../../aws-ecr'; import * as iam from '../../../aws-iam'; import { IBucket } from '../../../aws-s3'; import { Fn, SecretValue, Token, UnscopedValidationError } from '../../../core'; +import { IRepositoryRef } from '../../../interfaces/generated/aws-ecr-interfaces.generated'; import { FileSet, Step } from '../blueprint'; /** @@ -76,7 +76,7 @@ export abstract class CodePipelineSource extends Step implements ICodePipelineAc * imageTag: 'latest', * }); */ - public static ecr(repository: IRepository, props: ECRSourceOptions = {}): CodePipelineSource { + public static ecr(repository: IRepositoryRef, props: ECRSourceOptions = {}): CodePipelineSource { return new ECRSource(repository, props); } @@ -352,7 +352,7 @@ export interface ECRSourceOptions { } class ECRSource extends CodePipelineSource { - constructor(readonly repository: IRepository, readonly props: ECRSourceOptions) { + constructor(readonly repository: IRepositoryRef, readonly props: ECRSourceOptions) { super(Node.of(repository).addr); this.configurePrimaryOutput(new FileSet('Source', this)); @@ -360,7 +360,7 @@ class ECRSource extends CodePipelineSource { protected getAction(output: Artifact, _actionName: string, runOrder: number, variablesNamespace: string) { // RepositoryName can contain '/' that is not a valid ActionName character, use '_' instead - const formattedRepositoryName = Fn.join('_', Fn.split('/', this.repository.repositoryName)); + const formattedRepositoryName = Fn.join('_', Fn.split('/', this.repository.repositoryRef.repositoryName)); return new cp_actions.EcrSourceAction({ output, actionName: this.props.actionName ?? formattedRepositoryName,