Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pipelines): room for extra sequential intermediary actions in CdkStage addApplication() #11376

Merged
merged 3 commits into from
Nov 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
between 'Prepare' and 'Execute' ChangeSet actions is possible.

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

## Adding validations to the pipeline

You can add any type of CodePipeline Action to the pipeline in order to validate
Expand Down
14 changes: 12 additions & 2 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 extraRunOrderSpace = options.extraRunOrderSpace ?? 0;

if (asm.stacks.length === 0) {
// If we don't check here, a more puzzling "stage contains no actions"
Expand All @@ -88,8 +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(extraRunOrderSpace + 2); // 2 actions for Prepare/Execute ChangeSet
let executeRunOrder = runOrder + extraRunOrderSpace + 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
Expand Down Expand Up @@ -371,6 +372,15 @@ export interface AddStageOptions {
* @default false
*/
readonly manualApprovals?: boolean;
/**
* Add room for extra actions
*
* You can use this to make extra room in the runOrder sequence between the
* changeset 'prepare' and 'execute' actions and insert your own actions there.
*
* @default 0
*/
readonly extraRunOrderSpace?: number;
}

/**
Expand Down
31 changes: 31 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,37 @@ test('manual approval is inserted in correct location', () => {
});
});

test('extra space for sequential intermediary actions is reserved', () => {
// WHEN
pipeline.addApplicationStage(new TwoStackApp(app, 'MyApp'), {
extraRunOrderSpace: 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,
}),
objectLike({
Name: 'Stack2.Prepare',
RunOrder: 4,
}),
objectLike({
Name: 'Stack2.Deploy',
RunOrder: 6,
}),
]),
}),
});
});

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