Skip to content

Commit

Permalink
feat(pipelines): room for extra sequential intermediary actions in Cd…
Browse files Browse the repository at this point in the history
…kStage addApplication()

Currently there is no way of reordering stages/actions once they are created. Getting to

the Prepare and Execute change set actions while adding an application stage, we identified a

use case within our company that needs one or more intermediary sequential actions before

actually executing the change set. To resolve the problem, I suggest extending

the AddStageOptions interface with an optional property representing the number of

intermediary actions you need room for.

Closes aws#11333
  • Loading branch information
adriantaut committed Nov 9, 2020
1 parent 550dd99 commit d801456
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
10 changes: 10 additions & 0 deletions packages/@aws-cdk/pipelines/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,16 @@ testingStage.addApplication(new MyApplication2(this, 'MyApp2', {
}));
```

Even more, adding a manual approval action or reserving space for some extra sequential actions
before executing the Change Set is also possible.

```ts
pipeline.addApplicationStage(new MyApplication(this, 'Production'), {
manualApprovals: true,
roomForIntermediaryActions: 1,
});
```

## Adding validations to the pipeline

You can add any type of CodePipeline Action to the pipeline in order to validate
Expand Down
15 changes: 12 additions & 3 deletions packages/@aws-cdk/pipelines/lib/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export class CdkStage extends CoreConstruct {
*/
public addApplication(appStage: Stage, options: AddStageOptions = {}) {
const asm = appStage.synth();
const roomForIntermediaryActions = options.roomForIntermediaryActions ?? 0;

if (asm.stacks.length === 0) {
// If we don't check here, a more puzzling "stage contains no actions"
Expand All @@ -88,9 +89,8 @@ export class CdkStage extends CoreConstruct {
stack => stack.dependencies.map(d => d.id));

for (const stacks of sortedTranches) {
const runOrder = this.nextSequentialRunOrder(2); // We need 2 actions
let executeRunOrder = runOrder + 1;

const runOrder = this.nextSequentialRunOrder(roomForIntermediaryActions + 2); // 2 actions for Prepare/Execute ChangeSet
let executeRunOrder = runOrder + roomForIntermediaryActions + 1;
// If we need to insert a manual approval action, then what's the executeRunOrder
// now is where we add a manual approval step, and we allocate 1 more runOrder
// for the execute.
Expand Down Expand Up @@ -371,6 +371,15 @@ export interface AddStageOptions {
* @default false
*/
readonly manualApprovals?: boolean;
/**
* Add room for extra sequetial intermediary actions
*
* This increases the executeRunOrder of the execute change set action with
* the value passed.
*
* @default 0
*/
readonly roomForIntermediaryActions?: number;
}

/**
Expand Down
23 changes: 23 additions & 0 deletions packages/@aws-cdk/pipelines/test/stack-ordering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,29 @@ test('manual approval is inserted in correct location', () => {
});
});

test('room for sequential intermediary actions is reserved', () => {
// WHEN
pipeline.addApplicationStage(new TwoStackApp(app, 'MyApp'), {
roomForIntermediaryActions: 1,
});

// THEN
expect(pipelineStack).toHaveResourceLike('AWS::CodePipeline::Pipeline', {
Stages: arrayWith({
Name: 'MyApp',
Actions: sortedByRunOrder([
objectLike({
Name: 'Stack1.Prepare',
RunOrder: 1,
}),
objectLike({
Name: 'Stack1.Deploy',
RunOrder: 3,
}),
]),
}),
});
});

class TwoStackApp extends Stage {
constructor(scope: Construct, id: string, props?: StageProps) {
Expand Down

0 comments on commit d801456

Please sign in to comment.