@@ -12,22 +12,37 @@ import { AddStageOptions, AssetPublishingCommand, CdkStage, StackOutput } from '
12
12
export interface CdkPipelineProps {
13
13
/**
14
14
* The CodePipeline action used to retrieve the CDK app's source
15
+ *
16
+ * @default - Required unless `codePipeline` is given
15
17
*/
16
- readonly sourceAction : codepipeline . IAction ;
18
+ readonly sourceAction ? : codepipeline . IAction ;
17
19
18
20
/**
19
21
* The CodePipeline action build and synthesis step of the CDK app
22
+ *
23
+ * @default - Required unless `codePipeline` or `sourceAction` is given
20
24
*/
21
- readonly synthAction : codepipeline . IAction ;
25
+ readonly synthAction ? : codepipeline . IAction ;
22
26
23
27
/**
24
28
* The artifact you have defined to be the artifact to hold the cloudAssemblyArtifact for the synth action
25
29
*/
26
30
readonly cloudAssemblyArtifact : codepipeline . Artifact ;
27
31
32
+ /**
33
+ * Existing CodePipeline to modify
34
+ *
35
+ * The Pipeline should have been created with `restartExecutionOnUpdate: true`.
36
+ *
37
+ * @default - A new CodePipeline is automatically generated
38
+ */
39
+ readonly codePipeline ?: codepipeline . Pipeline ;
40
+
28
41
/**
29
42
* Name of the pipeline
30
43
*
44
+ * Can only be set if `codePipeline` is not set.
45
+ *
31
46
* @default - A name is automatically generated
32
47
*/
33
48
readonly pipelineName ?: string ;
@@ -72,28 +87,58 @@ export class CdkPipeline extends Construct {
72
87
this . _cloudAssemblyArtifact = props . cloudAssemblyArtifact ;
73
88
const pipelineStack = Stack . of ( this ) ;
74
89
75
- this . _pipeline = new codepipeline . Pipeline ( this , 'Pipeline' , {
76
- ...props ,
77
- restartExecutionOnUpdate : true ,
78
- stages : [
79
- {
80
- stageName : 'Source' ,
81
- actions : [ props . sourceAction ] ,
82
- } ,
83
- {
84
- stageName : 'Build' ,
85
- actions : [ props . synthAction ] ,
86
- } ,
87
- {
88
- stageName : 'UpdatePipeline' ,
89
- actions : [ new UpdatePipelineAction ( this , 'UpdatePipeline' , {
90
- cloudAssemblyInput : this . _cloudAssemblyArtifact ,
91
- pipelineStackName : pipelineStack . stackName ,
92
- cdkCliVersion : props . cdkCliVersion ,
93
- projectName : maybeSuffix ( props . pipelineName , '-selfupdate' ) ,
94
- } ) ] ,
95
- } ,
96
- ] ,
90
+ if ( props . codePipeline ) {
91
+ if ( props . pipelineName ) {
92
+ throw new Error ( 'Cannot set \'pipelineName\' if an existing CodePipeline is given using \'codePipeline\'' ) ;
93
+ }
94
+
95
+ this . _pipeline = props . codePipeline ;
96
+ } else {
97
+ this . _pipeline = new codepipeline . Pipeline ( this , 'Pipeline' , {
98
+ pipelineName : props . pipelineName ,
99
+ restartExecutionOnUpdate : true ,
100
+ } ) ;
101
+ }
102
+
103
+ if ( props . sourceAction && ! props . synthAction ) {
104
+ // Because of ordering limitations, you can: bring your own Source, bring your own
105
+ // Both, or bring your own Nothing. You cannot bring your own Build (which because of the
106
+ // current CodePipeline API must go BEFORE what we're adding) and then having us add a
107
+ // Source after it. That doesn't make any sense.
108
+ throw new Error ( 'When passing a \'sourceAction\' you must also pass a \'synthAction\' (or a \'codePipeline\' that already has both)' ) ;
109
+ }
110
+ if ( ! props . sourceAction && ( ! props . codePipeline || props . codePipeline . stages . length < 1 ) ) {
111
+ throw new Error ( 'You must pass a \'sourceAction\' (or a \'codePipeline\' that already has a Source stage)' ) ;
112
+ }
113
+ if ( ! props . synthAction && ( ! props . codePipeline || props . codePipeline . stages . length < 2 ) ) {
114
+ // This looks like a weirdly specific requirement, but actually the underlying CodePipeline
115
+ // requires that a Pipeline has at least 2 stages. We're just hitching onto upstream
116
+ // requirements to do this check.
117
+ throw new Error ( 'You must pass a \'synthAction\' (or a \'codePipeline\' that already has a Build stage)' ) ;
118
+ }
119
+
120
+ if ( props . sourceAction ) {
121
+ this . _pipeline . addStage ( {
122
+ stageName : 'Source' ,
123
+ actions : [ props . sourceAction ] ,
124
+ } ) ;
125
+ }
126
+
127
+ if ( props . synthAction ) {
128
+ this . _pipeline . addStage ( {
129
+ stageName : 'Build' ,
130
+ actions : [ props . synthAction ] ,
131
+ } ) ;
132
+ }
133
+
134
+ this . _pipeline . addStage ( {
135
+ stageName : 'UpdatePipeline' ,
136
+ actions : [ new UpdatePipelineAction ( this , 'UpdatePipeline' , {
137
+ cloudAssemblyInput : this . _cloudAssemblyArtifact ,
138
+ pipelineStackName : pipelineStack . stackName ,
139
+ cdkCliVersion : props . cdkCliVersion ,
140
+ projectName : maybeSuffix ( props . pipelineName , '-selfupdate' ) ,
141
+ } ) ] ,
97
142
} ) ;
98
143
99
144
this . _assets = new AssetPublishing ( this , 'Assets' , {
@@ -112,10 +157,19 @@ export class CdkPipeline extends Construct {
112
157
* You can use this to add more Stages to the pipeline, or Actions
113
158
* to Stages.
114
159
*/
115
- public get pipeline ( ) : codepipeline . Pipeline {
160
+ public get codePipeline ( ) : codepipeline . Pipeline {
116
161
return this . _pipeline ;
117
162
}
118
163
164
+ /**
165
+ * Access one of the pipeline's stages by stage name
166
+ *
167
+ * You can use this to add more Actions to a stage.
168
+ */
169
+ public stage ( stageName : string ) : codepipeline . IStage {
170
+ return this . _pipeline . stage ( stageName ) ;
171
+ }
172
+
119
173
/**
120
174
* Add pipeline stage that will deploy the given application stage
121
175
*
0 commit comments