From 549ad732a7df9540acdb1dd5a8494e1806d7b11e Mon Sep 17 00:00:00 2001 From: Tomas Mazak Date: Tue, 22 Sep 2020 00:54:14 +0200 Subject: [PATCH] feat(pipelines): add a property to CdkPipeline to allow disabling self-mutation --- packages/@aws-cdk/pipelines/README.md | 18 ++++++++++ packages/@aws-cdk/pipelines/lib/pipeline.ts | 34 ++++++++++++++----- .../@aws-cdk/pipelines/test/pipeline.test.ts | 28 ++++++++++++++- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/packages/@aws-cdk/pipelines/README.md b/packages/@aws-cdk/pipelines/README.md index d567675f1ca2f..e975a7502b720 100644 --- a/packages/@aws-cdk/pipelines/README.md +++ b/packages/@aws-cdk/pipelines/README.md @@ -543,6 +543,24 @@ class MyPipelineStack extends Stack { } ``` +### Developing the pipeline + +The self-mutation feature of the `CdkPipeline` might at times get in the way +of the pipeline development workflow. Each change to the pipeline must be pushed +to git, otherwise, after the pipeline was updated using `cdk deploy`, it will +automatically revert to the state found in git. + +To make the development more convenient, the self-mutation feature can be turned +off temporarily, by passing `selfMutating: false` property, example: + +```ts +const pipeline = new CdkPipeline(this, 'Pipeline', { + selfMutating: false, + ... +}); +``` + + ## CDK Environment Bootstrapping An *environment* is an *(account, region)* pair where you want to deploy a diff --git a/packages/@aws-cdk/pipelines/lib/pipeline.ts b/packages/@aws-cdk/pipelines/lib/pipeline.ts index 28358928ecc35..0233af8ed87ca 100644 --- a/packages/@aws-cdk/pipelines/lib/pipeline.ts +++ b/packages/@aws-cdk/pipelines/lib/pipeline.ts @@ -105,6 +105,20 @@ export interface CdkPipelineProps { * @default - All private subnets. */ readonly subnetSelection?: ec2.SubnetSelection; + + /** + * Whether the pipeline will update itself + * + * This needs to be set to `true` to allow the pipeline to reconfigure + * itself when assets or stages are being added to it, and `true` is the + * recommended setting. + * + * You can temporarily set this to `false` while you are iterating + * on the pipeline itself and prefer to deploy changes using `cdk deploy`. + * + * @default true + */ + readonly selfMutating?: boolean; } /** @@ -178,15 +192,17 @@ export class CdkPipeline extends CoreConstruct { }); } - this._pipeline.addStage({ - stageName: 'UpdatePipeline', - actions: [new UpdatePipelineAction(this, 'UpdatePipeline', { - cloudAssemblyInput: this._cloudAssemblyArtifact, - pipelineStackName: pipelineStack.stackName, - cdkCliVersion: props.cdkCliVersion, - projectName: maybeSuffix(props.pipelineName, '-selfupdate'), - })], - }); + if (props.selfMutating ?? true) { + this._pipeline.addStage({ + stageName: 'UpdatePipeline', + actions: [new UpdatePipelineAction(this, 'UpdatePipeline', { + cloudAssemblyInput: this._cloudAssemblyArtifact, + pipelineStackName: pipelineStack.stackName, + cdkCliVersion: props.cdkCliVersion, + projectName: maybeSuffix(props.pipelineName, '-selfupdate'), + })], + }); + } this._assets = new AssetPublishing(this, 'Assets', { cloudAssemblyInput: this._cloudAssemblyArtifact, diff --git a/packages/@aws-cdk/pipelines/test/pipeline.test.ts b/packages/@aws-cdk/pipelines/test/pipeline.test.ts index 023f4bdcf575d..003aacf021d47 100644 --- a/packages/@aws-cdk/pipelines/test/pipeline.test.ts +++ b/packages/@aws-cdk/pipelines/test/pipeline.test.ts @@ -1,6 +1,15 @@ import * as fs from 'fs'; import * as path from 'path'; -import { anything, arrayWith, Capture, deepObjectLike, encodedJson, objectLike, stringLike } from '@aws-cdk/assert'; +import { + anything, + arrayWith, + Capture, + deepObjectLike, + encodedJson, + notMatching, + objectLike, + stringLike, +} from '@aws-cdk/assert'; import '@aws-cdk/assert/jest'; import * as cp from '@aws-cdk/aws-codepipeline'; import * as cpa from '@aws-cdk/aws-codepipeline-actions'; @@ -332,6 +341,23 @@ test('selfmutation stage correctly identifies nested assembly of pipeline stack' }); }); +test('selfmutation feature can be turned off', () => { + const stack = new Stack(); + const cloudAssemblyArtifact = new cp.Artifact(); + // WHEN + new TestGitHubNpmPipeline(stack, 'Cdk', { + cloudAssemblyArtifact, + selfMutating: false, + }); + // THEN + expect(stack).toHaveResourceLike('AWS::CodePipeline::Pipeline', { + Stages: notMatching(arrayWith({ + Name: 'UpdatePipeline', + Actions: anything(), + })), + }); +}); + test('overridden stack names are respected', () => { // WHEN pipeline.addApplicationStage(new OneStackAppWithCustomName(app, 'App1'));