Skip to content

Commit b778e10

Browse files
authored
feat(codepipeline): change to stand-alone Artifacts. (#2338)
This commit changes the way Artifacts are used in CodePipeline. Instead of being properties on the Actions, they are now stand-alone objects, created independently of the Actions, and referenced when instantiating them. This is to not force users to assign Actions to intermediate variables when defining a Pipeline. This change had a few interesting consequences: * We no longer needed the abstract subclasses of Action like SourceAction, DeployAction, etc., and so they were removed. * The old naming convention of `inputArtifacts` and `outputArtifactNames` was shortened to be simply `inputs` and `outputs`. * There was no longer any need to differentiate Build and Test Actions, and so the two CodeBuild and Jenkins Actions were merged into one. BREAKING CHANGE: CodePipeline Actions no longer have the `outputArtifact` and `outputArtifacts` properties. * `inputArtifact(s)` and `additionalInputArtifacts` properties were renamed to `input(s)` and `extraInputs`. * `outputArtifactName(s)` and `additionalOutputArtifactNames` properties were renamed to `output(s)` and `extraOutputs`. * The classes `CodeBuildBuildAction` and `CodeBuildTestAction` were merged into one class `CodeBuildAction`. * The classes `JenkinsBuildAction` and `JenkinsTestAction` were merged into one class `JenkinsAction`.
1 parent 486a7a8 commit b778e10

File tree

73 files changed

+1465
-1237
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1465
-1237
lines changed

packages/@aws-cdk/app-delivery/README.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@ const pipeline = new codepipeline.Pipeline(pipelineStack, 'CodePipeline', {
5050
});
5151

5252
// Configure the CodePipeline source - where your CDK App's source code is hosted
53+
const sourceOutput = new codepipeline.Artifact();
5354
const source = new codepipeline_actions.GitHubSourceAction({
5455
actionName: 'GitHub',
56+
output: sourceOutput,
5557
/* ... */
5658
});
5759
pipeline.addStage({
@@ -69,23 +71,24 @@ const project = new codebuild.PipelineProject(pipelineStack, 'CodeBuild', {
6971
* },
7072
*/
7173
});
72-
const buildAction = new codepipeline_actions.CodeBuildBuildAction({
74+
const synthesizedApp = new codepipeline.Artifact();
75+
const buildAction = new codepipeline_actions.CodeBuildAction({
7376
actionName: 'CodeBuild',
7477
project,
75-
inputArtifact: source.outputArtifact,
78+
input: sourceOutput,
79+
output: synthesizedApp,
7680
});
7781
pipeline.addStage({
7882
name: 'build',
7983
actions: [buildAction],
8084
});
81-
const synthesizedApp = buildAction.outputArtifact;
8285

8386
// Optionally, self-update the pipeline stack
8487
const selfUpdateStage = pipeline.addStage({ name: 'SelfUpdate' });
8588
new cicd.PipelineDeployStackAction(pipelineStack, 'SelfUpdatePipeline', {
8689
stage: selfUpdateStage,
8790
stack: pipelineStack,
88-
inputArtifact: synthesizedApp,
91+
input: synthesizedApp,
8992
});
9093

9194
// Now add our service stacks
@@ -95,7 +98,7 @@ const serviceStackA = new MyServiceStackA(app, 'ServiceStackA', { /* ... */ });
9598
const deployServiceAAction = new cicd.PipelineDeployStackAction(pipelineStack, 'DeployServiceStackA', {
9699
stage: deployStage,
97100
stack: serviceStackA,
98-
inputArtifact: synthesizedApp,
101+
input: synthesizedApp,
99102
// See the note below for details about this option.
100103
adminPermissions: false,
101104
});
@@ -114,7 +117,7 @@ const serviceStackB = new MyServiceStackB(app, 'ServiceStackB', { /* ... */ });
114117
new cicd.PipelineDeployStackAction(pipelineStack, 'DeployServiceStackB', {
115118
stage: deployStage,
116119
stack: serviceStackB,
117-
inputArtifact: synthesizedApp,
120+
input: synthesizedApp,
118121
createChangeSetRunOrder: 998,
119122
adminPermissions: true, // no need to modify the role with admin
120123
});
@@ -148,7 +151,7 @@ artifacts:
148151
files: '**/*'
149152
```
150153
151-
The `PipelineDeployStackAction` expects it's `inputArtifact` to contain the result of
154+
The `PipelineDeployStackAction` expects it's `input` to contain the result of
152155
synthesizing a CDK App using the `cdk synth -o <directory>`.
153156

154157

packages/@aws-cdk/app-delivery/lib/pipeline-deploy-stack-action.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface PipelineDeployStackActionProps {
2020
* The CodePipeline artifact that holds the synthesized app, which is the
2121
* contents of the ``<directory>`` when running ``cdk synth -o <directory>``.
2222
*/
23-
readonly inputArtifact: codepipeline.Artifact;
23+
readonly input: codepipeline.Artifact;
2424

2525
/**
2626
* The name to use when creating a ChangeSet for the stack.
@@ -126,7 +126,7 @@ export class PipelineDeployStackAction extends cdk.Construct {
126126
changeSetName,
127127
runOrder: createChangeSetRunOrder,
128128
stackName: props.stack.name,
129-
templatePath: props.inputArtifact.atPath(`${props.stack.name}.template.yaml`),
129+
templatePath: props.input.atPath(`${props.stack.name}.template.yaml`),
130130
adminPermissions: props.adminPermissions,
131131
deploymentRole: props.role,
132132
capabilities,

packages/@aws-cdk/app-delivery/test/integ.cicd.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ const pipeline = new codepipeline.Pipeline(stack, 'CodePipeline', {
1313
removalPolicy: cdk.RemovalPolicy.Destroy
1414
})
1515
});
16+
const sourceOutput = new codepipeline.Artifact('Artifact_CICDGitHubF8BA7ADD');
1617
const source = new cpactions.GitHubSourceAction({
1718
actionName: 'GitHub',
1819
owner: 'awslabs',
1920
repo: 'aws-cdk',
2021
oauthToken: cdk.SecretValue.plainText('DummyToken'),
2122
pollForSourceChanges: true,
22-
outputArtifactName: 'Artifact_CICDGitHubF8BA7ADD',
23+
output: sourceOutput,
2324
});
2425
pipeline.addStage({
2526
name: 'Source',
@@ -32,7 +33,7 @@ new cicd.PipelineDeployStackAction(stack, 'DeployStack', {
3233
changeSetName: 'CICD-ChangeSet',
3334
createChangeSetRunOrder: 10,
3435
executeChangeSetRunOrder: 999,
35-
inputArtifact: source.outputArtifact,
36+
input: sourceOutput,
3637
adminPermissions: false,
3738
capabilities: cfn.CloudFormationCapabilities.None,
3839
});

packages/@aws-cdk/app-delivery/test/test.pipeline-deploy-stack-action.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { countResources, expect, haveResource, isSuperObject } from '@aws-cdk/assert';
12
import cfn = require('@aws-cdk/aws-cloudformation');
23
import codebuild = require('@aws-cdk/aws-codebuild');
34
import codepipeline = require('@aws-cdk/aws-codepipeline');
@@ -8,8 +9,6 @@ import cdk = require('@aws-cdk/cdk');
89
import cxapi = require('@aws-cdk/cx-api');
910
import fc = require('fast-check');
1011
import nodeunit = require('nodeunit');
11-
12-
import { countResources, expect, haveResource, isSuperObject } from '@aws-cdk/assert';
1312
import { PipelineDeployStackAction } from '../lib/pipeline-deploy-stack-action';
1413

1514
interface SelfUpdatingPipeline {
@@ -36,7 +35,7 @@ export = nodeunit.testCase({
3635
});
3736
new PipelineDeployStackAction(stack, 'Action', {
3837
changeSetName: 'ChangeSet',
39-
inputArtifact: fakeAction.outputArtifact,
38+
input: fakeAction.outputArtifact,
4039
stack: new cdk.Stack(app, 'DeployedStack', { env: { account: stackAccount } }),
4140
stage: pipeline.addStage({ name: 'DeployStage' }),
4241
adminPermissions: false,
@@ -67,7 +66,7 @@ export = nodeunit.testCase({
6766
changeSetName: 'ChangeSet',
6867
createChangeSetRunOrder: createRunOrder,
6968
executeChangeSetRunOrder: executeRunOrder,
70-
inputArtifact: fakeAction.outputArtifact,
69+
input: fakeAction.outputArtifact,
7170
stack: new cdk.Stack(app, 'DeployedStack'),
7271
stage: pipeline.addStage({ name: 'DeployStage' }),
7372
adminPermissions: false,
@@ -96,21 +95,21 @@ export = nodeunit.testCase({
9695
new PipelineDeployStackAction(pipelineStack, 'SelfUpdatePipeline', {
9796
stage: selfUpdateStage1,
9897
stack: pipelineStack,
99-
inputArtifact: selfUpdatingStack.synthesizedApp,
98+
input: selfUpdatingStack.synthesizedApp,
10099
capabilities: cfn.CloudFormationCapabilities.NamedIAM,
101100
adminPermissions: false,
102101
});
103102
new PipelineDeployStackAction(pipelineStack, 'DeployStack', {
104103
stage: selfUpdateStage2,
105104
stack: stackWithNoCapability,
106-
inputArtifact: selfUpdatingStack.synthesizedApp,
105+
input: selfUpdatingStack.synthesizedApp,
107106
capabilities: cfn.CloudFormationCapabilities.None,
108107
adminPermissions: false,
109108
});
110109
new PipelineDeployStackAction(pipelineStack, 'DeployStack2', {
111110
stage: selfUpdateStage3,
112111
stack: stackWithAnonymousCapability,
113-
inputArtifact: selfUpdatingStack.synthesizedApp,
112+
input: selfUpdatingStack.synthesizedApp,
114113
capabilities: cfn.CloudFormationCapabilities.AnonymousIAM,
115114
adminPermissions: false,
116115
});
@@ -159,7 +158,7 @@ export = nodeunit.testCase({
159158
new PipelineDeployStackAction(pipelineStack, 'SelfUpdatePipeline', {
160159
stage: selfUpdateStage,
161160
stack: pipelineStack,
162-
inputArtifact: selfUpdatingStack.synthesizedApp,
161+
input: selfUpdatingStack.synthesizedApp,
163162
adminPermissions: true,
164163
});
165164
expect(pipelineStack).to(haveResource('AWS::IAM::Policy', {
@@ -195,7 +194,7 @@ export = nodeunit.testCase({
195194
const deployAction = new PipelineDeployStackAction(pipelineStack, 'SelfUpdatePipeline', {
196195
stage: selfUpdateStage,
197196
stack: pipelineStack,
198-
inputArtifact: selfUpdatingStack.synthesizedApp,
197+
input: selfUpdatingStack.synthesizedApp,
199198
adminPermissions: false,
200199
role
201200
});
@@ -218,7 +217,7 @@ export = nodeunit.testCase({
218217
const deployAction = new PipelineDeployStackAction(pipelineStack, 'DeployServiceStackA', {
219218
stage: deployStage,
220219
stack: emptyStack,
221-
inputArtifact: selfUpdatingStack.synthesizedApp,
220+
input: selfUpdatingStack.synthesizedApp,
222221
adminPermissions: false,
223222
});
224223
// we might need to add permissions
@@ -282,7 +281,7 @@ export = nodeunit.testCase({
282281
const deployStage = pipeline.addStage({ name: 'DeployStage' });
283282
const action = new PipelineDeployStackAction(stack, 'Action', {
284283
changeSetName: 'ChangeSet',
285-
inputArtifact: fakeAction.outputArtifact,
284+
input: fakeAction.outputArtifact,
286285
stack: deployedStack,
287286
stage: deployStage,
288287
adminPermissions: false,
@@ -305,7 +304,7 @@ class FakeAction extends codepipeline.Action {
305304
constructor(actionName: string) {
306305
super({
307306
actionName,
308-
artifactBounds: codepipeline.defaultBounds(),
307+
artifactBounds: { minInputs: 0, maxInputs: 5, minOutputs: 0, maxOutputs: 5 },
309308
category: codepipeline.ActionCategory.Test,
310309
provider: 'Test',
311310
});
@@ -329,28 +328,31 @@ function createSelfUpdatingStack(pipelineStack: cdk.Stack): SelfUpdatingPipeline
329328

330329
// simple source
331330
const bucket = s3.Bucket.import( pipeline, 'PatternBucket', { bucketArn: 'arn:aws:s3:::totally-fake-bucket' });
331+
const sourceOutput = new codepipeline.Artifact('SourceOutput');
332332
const sourceAction = new cpactions.S3SourceAction({
333333
actionName: 'S3Source',
334334
bucket,
335335
bucketKey: 'the-great-key',
336+
output: sourceOutput,
336337
});
337338
pipeline.addStage({
338339
name: 'source',
339340
actions: [sourceAction],
340341
});
341342

342343
const project = new codebuild.PipelineProject(pipelineStack, 'CodeBuild');
343-
const buildAction = new cpactions.CodeBuildBuildAction({
344+
const buildOutput = new codepipeline.Artifact('BuildOutput');
345+
const buildAction = new cpactions.CodeBuildAction({
344346
actionName: 'CodeBuild',
345347
project,
346-
inputArtifact: sourceAction.outputArtifact,
348+
input: sourceOutput,
349+
output: buildOutput,
347350
});
348351
pipeline.addStage({
349352
name: 'build',
350353
actions: [buildAction],
351354
});
352-
const synthesizedApp = buildAction.outputArtifact;
353-
return {synthesizedApp, pipeline};
355+
return {synthesizedApp: buildOutput, pipeline};
354356
}
355357

356358
function hasPipelineAction(expectedAction: any): (props: any) => boolean {

packages/@aws-cdk/aws-codebuild/lib/project.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -753,11 +753,11 @@ export class Project extends ProjectBase {
753753
if (this.source.type === SourceType.CodePipeline) {
754754
if (this._secondarySources.length > 0) {
755755
ret.push('A Project with a CodePipeline Source cannot have secondary sources. ' +
756-
"Use the CodeBuild Pipeline Actions' `additionalInputArtifacts` property instead");
756+
"Use the CodeBuild Pipeline Actions' `extraInputs` property instead");
757757
}
758758
if (this._secondaryArtifacts.length > 0) {
759759
ret.push('A Project with a CodePipeline Source cannot have secondary artifacts. ' +
760-
"Use the CodeBuild Pipeline Actions' `additionalOutputArtifactNames` property instead");
760+
"Use the CodeBuild Pipeline Actions' `extraOutputs` property instead");
761761
}
762762
}
763763
return ret;

0 commit comments

Comments
 (0)