From 594297862f2626b64b174d6998886a40f1b316be Mon Sep 17 00:00:00 2001 From: Rico Hermans Date: Thu, 9 Feb 2023 18:06:06 +0100 Subject: [PATCH] fix(pipelines): SelfMutation CodeBuild project not accessible (#24073) The Pipelines-generated Synth CodeBuild project is already exposed so that users can tweak it or its permissions. Do the same for the SelfMutation CodeBuild project, so that certain users with very specific use cases can stretch CDK Pipelines a little beyond its design goals. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/codepipeline/codepipeline.ts | 20 +++++++++++++ .../test/codepipeline/codepipeline.test.ts | 30 ++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts b/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts index ef94a85989f73..0f6997e392b18 100644 --- a/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts +++ b/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts @@ -320,6 +320,7 @@ export class CodePipeline extends PipelineBase { private _pipeline?: cp.Pipeline; private artifacts = new ArtifactMap(); private _synthProject?: cb.IProject; + private _selfMutationProject?: cb.IProject; private readonly selfMutation: boolean; private readonly useChangeSets: boolean; private _myCxAsmRoot?: string; @@ -365,6 +366,22 @@ export class CodePipeline extends PipelineBase { return this._synthProject; } + /** + * The CodeBuild project that performs the SelfMutation + * + * Will throw an error if this is accessed before `buildPipeline()` + * is called. + * + * May return no value if `selfMutation` was set to `false` when + * the `CodePipeline` was defined. + */ + public get selfMutationProject(): cb.IProject | undefined { + if (!this._pipeline) { + throw new Error('Call pipeline.buildPipeline() before reading this property'); + } + return this._selfMutationProject; + } + /** * The CodePipeline pipeline that deploys the CDK app * @@ -527,6 +544,9 @@ export class CodePipeline extends PipelineBase { if (nodeType === CodeBuildProjectType.SYNTH) { this._synthProject = result.project; } + if (nodeType === CodeBuildProjectType.SELF_MUTATE) { + this._selfMutationProject = result.project; + } } if (node.data?.type === 'step' && node.data.step.primaryOutput?.primaryOutput && !this._fallbackArtifact) { diff --git a/packages/@aws-cdk/pipelines/test/codepipeline/codepipeline.test.ts b/packages/@aws-cdk/pipelines/test/codepipeline/codepipeline.test.ts index eb1fe053ef201..a0ea38fe6f264 100644 --- a/packages/@aws-cdk/pipelines/test/codepipeline/codepipeline.test.ts +++ b/packages/@aws-cdk/pipelines/test/codepipeline/codepipeline.test.ts @@ -8,7 +8,7 @@ import { Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; import * as cdkp from '../../lib'; import { CodePipeline } from '../../lib'; -import { PIPELINE_ENV, TestApp, ModernTestGitHubNpmPipeline, FileAssetApp, TwoStackApp } from '../testhelpers'; +import { PIPELINE_ENV, TestApp, ModernTestGitHubNpmPipeline, FileAssetApp, TwoStackApp, StageWithStackOutput } from '../testhelpers'; let app: TestApp; @@ -426,6 +426,34 @@ test('synths with change set approvers', () => { }); }); +test('selfMutationProject can be accessed after buildPipeline', () => { + // GIVEN + const pipelineStack = new cdk.Stack(app, 'PipelineStack', { env: PIPELINE_ENV }); + const pipeline = new ModernTestGitHubNpmPipeline(pipelineStack, 'Cdk'); + pipeline.addStage(new StageWithStackOutput(pipelineStack, 'Stage')); + + // WHEN + pipeline.buildPipeline(); + + // THEN + expect(pipeline.selfMutationProject).toBeTruthy(); +}); + +test('selfMutationProject is undefined if switched off', () => { + // GIVEN + const pipelineStack = new cdk.Stack(app, 'PipelineStack', { env: PIPELINE_ENV }); + const pipeline = new ModernTestGitHubNpmPipeline(pipelineStack, 'Cdk', { + selfMutation: false, + }); + pipeline.addStage(new StageWithStackOutput(pipelineStack, 'Stage')); + + // WHEN + pipeline.buildPipeline(); + + // THEN + expect(pipeline.selfMutationProject).toBeUndefined(); +}); + interface ReuseCodePipelineStackProps extends cdk.StackProps { reuseCrossRegionSupportStacks?: boolean; }