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(codepipeline): GitPushFilter with branches and file paths for trigger #29127

Merged
merged 23 commits into from
Jun 3, 2024
Merged
Changes from 5 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
70 changes: 65 additions & 5 deletions packages/aws-cdk-lib/aws-codepipeline/README.md
Original file line number Diff line number Diff line change
@@ -579,12 +579,17 @@ const rule = pipeline.notifyOnExecutionStateChange('NotifyOnExecutionStateChange

## Trigger

To trigger a pipeline with Git tags, specify the `triggers` property. When a Git tag is pushed,
your pipeline starts. You can filter with glob patterns. The `tagsExcludes` takes priority over
the `tagsIncludes`.

To trigger a pipeline with Git tags or branches, specify the `triggers` property.
The triggers can only be used with pipeline type V2.

### Push filter
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not separated here by the chapters "Tags" and "Branches" to add pull request filters in the PR.


Pipelines can be started based on push events. You can specify the `pushFilter` property to
filter the push events. The `pushFilter` can specify Git tags and branches.

In the case of Git tags, your pipeline starts when a Git tag is pushed.
You can filter with glob patterns. The `tagsExcludes` takes priority over the `tagsIncludes`.

```ts
declare const sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction;
declare const buildAction: codepipeline_actions.CodeBuildAction;
@@ -614,7 +619,62 @@ new codepipeline.Pipeline(this, 'Pipeline', {
});
```

Or append a trigger to an existing pipeline:
In the case of branches, your pipeline starts when a commit is pushed on the specified branches.
You can filter with glob patterns. The `branchesExcludes` takes priority over the `branchesIncludes`.

```ts
declare const sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction;
declare const buildAction: codepipeline_actions.CodeBuildAction;

new codepipeline.Pipeline(this, 'Pipeline', {
pipelineType: codepipeline.PipelineType.V2,
stages: [
{
stageName: 'Source',
actions: [sourceAction],
},
{
stageName: 'Build',
actions: [buildAction],
},
],
triggers: [{
providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION,
gitConfiguration: {
sourceAction,
pushFilter: [{
branchesExcludes: ['exclude1', 'exclude2'],
branchesIncludes: ['include*'],
}],
},
}],
});
```

File paths can also be specified along with the branches to start the pipeline.
You can filter with glob patterns. The `filePathsExcludes` takes priority over the `filePathsIncludes`.

```ts
declare const pipeline: codepipeline.Pipeline;
declare const sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction;

pipeline.addTrigger({
providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION,
gitConfiguration: {
sourceAction,
pushFilter: [{
branchesExcludes: ['exclude1', 'exclude2'],
branchesIncludes: ['include1', 'include2'],
filePathsExcludes: ['/path/to/exclude1', '/path/to/exclude2'],
filePathsIncludes: ['/path/to/include1', '/path/to/include1'],
}],
},
});
```

### Append a trigger to an existing pipeline

You can append a trigger to an existing pipeline:

```ts
declare const pipeline: codepipeline.Pipeline;
88 changes: 83 additions & 5 deletions packages/aws-cdk-lib/aws-codepipeline/lib/trigger.ts
Original file line number Diff line number Diff line change
@@ -30,6 +30,58 @@ export interface GitPushFilter {
* @default - no tags.
*/
readonly tagsIncludes?: string[];

/**
* The list of patterns of Git branches that, when a commit is pushed, are
* to be excluded from starting the pipeline.
*
* You can filter with glob patterns. The `branchesExcludes` takes priority
* over the `branchesIncludes`.
*
* Maximum length of this array is 8.
*
* @default - no branches.
*/
readonly branchesExcludes?: string[];

/**
* The list of patterns of Git branches that, when a commit is pushed, are
* to be included as criteria that starts the pipeline.
*
* You can filter with glob patterns. The `branchesExcludes` takes priority
* over the `branchesIncludes`.
*
* Maximum length of this array is 8.
*
* @default - no branches.
*/
readonly branchesIncludes?: string[];

/**
* The list of patterns of Git repository file paths that, when a commit is pushed,
* are to be excluded from starting the pipeline.
*
* You can filter with glob patterns. The `filePathsExcludes` takes priority
* over the `filePathsIncludes`.
*
* Maximum length of this array is 8.
*
* @default - no filePaths.
*/
readonly filePathsExcludes?: string[];

/**
* The list of patterns of Git repository file paths that, when a commit is pushed,
* are to be included as criteria that starts the pipeline.
*
* You can filter with glob patterns. The `filePathsExcludes` takes priority
* over the `filePathsIncludes`.
*
* Maximum length of this array is 8.
*
* @default - no filePaths.
*/
readonly filePathsIncludes?: string[];
}

/**
@@ -51,8 +103,6 @@ export interface GitConfiguration {
* The field where the repository event that will start the pipeline,
* such as pushing Git tags, is specified with details.
*
* Git tags is the only supported event type.
*
* The length must be less than or equal to 3.
*
* @default - no filter.
@@ -116,11 +166,29 @@ export class Trigger {
}

pushFilter?.forEach(filter => {
if ((filter.tagsExcludes || filter.tagsIncludes) && (filter.branchesExcludes || filter.branchesIncludes)) {
throw new Error(`cannot specify both tags and branches in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}'`);
}
Comment on lines +273 to +275
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is no this validation, the error occurred in CFn: The trigger configuration for the source action is not valid. Make sure to choose valid filter combinations..

In addition, we can only choose tags or branches (with file paths) in the AWS console.

if (!filter.branchesExcludes && !filter.branchesIncludes && (filter.filePathsExcludes || filter.filePathsIncludes)) {
throw new Error(`cannot specify filePaths without branches in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}'`);
}
if (filter.tagsExcludes && filter.tagsExcludes.length > 8) {
throw new Error(`maximum length of tagsExcludes for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsExcludes.length}`);
throw new Error(`maximum length of tagsExcludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsExcludes.length}`);
}
if (filter.tagsIncludes && filter.tagsIncludes.length > 8) {
throw new Error(`maximum length of tagsIncludes for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsIncludes.length}`);
throw new Error(`maximum length of tagsIncludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsIncludes.length}`);
}
if (filter.branchesExcludes && filter.branchesExcludes.length > 8) {
throw new Error(`maximum length of branchesExcludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.branchesExcludes.length}`);
}
if (filter.branchesIncludes && filter.branchesIncludes.length > 8) {
throw new Error(`maximum length of branchesIncludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.branchesIncludes.length}`);
}
if (filter.filePathsExcludes && filter.filePathsExcludes.length > 8) {
throw new Error(`maximum length of filePathsExcludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.filePathsExcludes.length}`);
}
if (filter.filePathsIncludes && filter.filePathsIncludes.length > 8) {
throw new Error(`maximum length of filePathsIncludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.filePathsIncludes.length}`);
}
});
}
@@ -143,7 +211,17 @@ export class Trigger {
excludes: filter.tagsExcludes?.length ? filter.tagsExcludes : undefined,
includes: filter.tagsIncludes?.length ? filter.tagsIncludes : undefined,
};
return { tags };
const branches: CfnPipeline.GitBranchFilterCriteriaProperty | undefined = {
// set to undefined if empty array because CloudFormation does not accept empty array
excludes: filter.branchesExcludes?.length ? filter.branchesExcludes : undefined,
includes: filter.branchesIncludes?.length ? filter.branchesIncludes : undefined,
};
const filePaths: CfnPipeline.GitFilePathFilterCriteriaProperty | undefined = {
// set to undefined if empty array because CloudFormation does not accept empty array
excludes: filter.filePathsExcludes?.length ? filter.filePathsExcludes : undefined,
includes: filter.filePathsIncludes?.length ? filter.filePathsIncludes : undefined,
};
return { tags, branches, filePaths };
});

gitConfiguration = {
Loading