Skip to content

Commit

Permalink
feat(codepipeline-actions): introduce the CodeStarConnectionsSourceAc…
Browse files Browse the repository at this point in the history
…tion (#13781)

At the same time, deprecate the unfortunately-named `BitBucketSourceAction`.

Fixes #10632

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
skinny85 committed Apr 7, 2021
1 parent 1c910c1 commit 8782e67
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 125 deletions.
7 changes: 3 additions & 4 deletions packages/@aws-cdk/aws-codepipeline-actions/README.md
Expand Up @@ -168,7 +168,7 @@ the connection has already been created.

```ts
const sourceOutput = new codepipeline.Artifact();
const sourceAction = new codepipeline_actions.BitBucketSourceAction({
const sourceAction = new codepipeline_actions.CodeStarConnectionsSourceAction({
actionName: 'BitBucket_Source',
owner: 'aws',
repo: 'aws-cdk',
Expand All @@ -177,9 +177,8 @@ const sourceAction = new codepipeline_actions.BitBucketSourceAction({
});
```

**Note**: as this feature is still in Beta in CodePipeline,
the above class `BitBucketSourceAction` is experimental -
we reserve the right to make breaking changes to it.
You can also use the `CodeStarConnectionsSourceAction` to connect to GitHub, in the same way
(you just have to select GitHub as the source when creating the connection in the console).

### AWS S3 Source

Expand Down
@@ -1,8 +1,6 @@
import * as codepipeline from '@aws-cdk/aws-codepipeline';
import * as iam from '@aws-cdk/aws-iam';

import { Action } from '../action';
import { sourceArtifactBounds } from '../common';
import * as events from '@aws-cdk/aws-events';
import { CodeStarConnectionsSourceAction, CodeStarConnectionsSourceActionProps } from '../codestar-connections/source-action';

// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
// eslint-disable-next-line no-duplicate-imports, import/order
Expand All @@ -11,132 +9,32 @@ import { Construct } from '@aws-cdk/core';
/**
* Construction properties for {@link BitBucketSourceAction}.
*
* @experimental
* @deprecated use CodeStarConnectionsSourceActionProps instead
*/
export interface BitBucketSourceActionProps extends codepipeline.CommonAwsActionProps {
/**
* The output artifact that this action produces.
* Can be used as input for further pipeline actions.
*/
readonly output: codepipeline.Artifact;

/**
* The ARN of the CodeStar Connection created in the AWS console
* that has permissions to access this BitBucket repository.
*
* @example 'arn:aws:codestar-connections:us-east-1:123456789012:connection/12345678-abcd-12ab-34cdef5678gh'
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/connections-create.html
*/
readonly connectionArn: string;

/**
* The owning user or organization of the repository.
*
* @example 'aws'
*/
readonly owner: string;

/**
* The name of the repository.
*
* @example 'aws-cdk'
*/
readonly repo: string;

/**
* The branch to build.
*
* @default 'master'
*/
readonly branch?: string;

// long URL in @see
/**
* Whether the output should be the contents of the repository
* (which is the default),
* or a link that allows CodeBuild to clone the repository before building.
*
* **Note**: if this option is true,
* then only CodeBuild actions can use the resulting {@link output}.
*
* @default false
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html#action-reference-CodestarConnectionSource-config
*/
readonly codeBuildCloneOutput?: boolean;

/**
* Controls automatically starting your pipeline when a new commit
* is made on the configured repository and branch. If unspecified,
* the default value is true, and the field does not display by default.
*
* @default true
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html
*/
readonly triggerOnPush?: boolean;
export interface BitBucketSourceActionProps extends CodeStarConnectionsSourceActionProps {
}

/**
* A CodePipeline source action for BitBucket.
*
* @experimental
* @deprecated use CodeStarConnectionsSourceAction instead
*/
export class BitBucketSourceAction extends Action {
/**
* The name of the property that holds the ARN of the CodeStar Connection
* inside of the CodePipeline Artifact's metadata.
*
* @internal
*/
public static readonly _CONNECTION_ARN_PROPERTY = 'CodeStarConnectionArnProperty';

private readonly props: BitBucketSourceActionProps;
export class BitBucketSourceAction implements codepipeline.IAction {
private readonly codeStarConnectionsSourceAction: CodeStarConnectionsSourceAction;

constructor(props: BitBucketSourceActionProps) {
super({
...props,
category: codepipeline.ActionCategory.SOURCE,
owner: 'AWS', // because props also has a (different!) owner property!
provider: 'CodeStarSourceConnection',
artifactBounds: sourceArtifactBounds(),
outputs: [props.output],
});

this.props = props;
this.codeStarConnectionsSourceAction = new CodeStarConnectionsSourceAction(props);
}

protected bound(_scope: Construct, _stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig {
// https://docs.aws.amazon.com/codepipeline/latest/userguide/security-iam.html#how-to-update-role-new-services
options.role.addToPolicy(new iam.PolicyStatement({
actions: [
'codestar-connections:UseConnection',
],
resources: [
this.props.connectionArn,
],
}));

// the action needs to write the output to the pipeline bucket
options.bucket.grantReadWrite(options.role);
options.bucket.grantPutAcl(options.role);
public get actionProperties(): codepipeline.ActionProperties {
return this.codeStarConnectionsSourceAction.actionProperties;
}

// if codeBuildCloneOutput is true,
// save the connectionArn in the Artifact instance
// to be read by the CodeBuildAction later
if (this.props.codeBuildCloneOutput === true) {
this.props.output.setMetadata(BitBucketSourceAction._CONNECTION_ARN_PROPERTY,
this.props.connectionArn);
}
public bind(scope: Construct, stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig {
return this.codeStarConnectionsSourceAction.bind(scope, stage, options);
}

return {
configuration: {
ConnectionArn: this.props.connectionArn,
FullRepositoryId: `${this.props.owner}/${this.props.repo}`,
BranchName: this.props.branch ?? 'master',
OutputArtifactFormat: this.props.codeBuildCloneOutput === true
? 'CODEBUILD_CLONE_REF'
: undefined,
DetectChanges: this.props.triggerOnPush,
},
};
public onStateChange(name: string, target?: events.IRuleTarget, options?: events.RuleProps): events.Rule {
return this.codeStarConnectionsSourceAction.onStateChange(name, target, options);
}
}
Expand Up @@ -2,7 +2,7 @@ import * as codebuild from '@aws-cdk/aws-codebuild';
import * as codepipeline from '@aws-cdk/aws-codepipeline';
import * as iam from '@aws-cdk/aws-iam';
import * as cdk from '@aws-cdk/core';
import { BitBucketSourceAction } from '..';
import { CodeStarConnectionsSourceAction } from '..';
import { Action } from '../action';
import { CodeCommitSourceAction } from '../codecommit/source-action';

Expand Down Expand Up @@ -180,10 +180,10 @@ export class CodeBuildAction extends Action {
}

for (const inputArtifact of this.actionProperties.inputs || []) {
// if any of the inputs come from the BitBucketSourceAction
// if any of the inputs come from the CodeStarConnectionsSourceAction
// with codeBuildCloneOutput=true,
// grant the Project's Role to use the connection
const connectionArn = inputArtifact.getMetadata(BitBucketSourceAction._CONNECTION_ARN_PROPERTY);
const connectionArn = inputArtifact.getMetadata(CodeStarConnectionsSourceAction._CONNECTION_ARN_PROPERTY);
if (connectionArn) {
this.props.project.addToRolePolicy(new iam.PolicyStatement({
actions: ['codestar-connections:UseConnection'],
Expand Down
@@ -0,0 +1,139 @@
import * as codepipeline from '@aws-cdk/aws-codepipeline';
import * as iam from '@aws-cdk/aws-iam';

import { Action } from '../action';
import { sourceArtifactBounds } from '../common';

// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
// eslint-disable-next-line no-duplicate-imports, import/order
import { Construct } from '@aws-cdk/core';

/**
* Construction properties for {@link CodeStarConnectionsSourceAction}.
*/
export interface CodeStarConnectionsSourceActionProps extends codepipeline.CommonAwsActionProps {
/**
* The output artifact that this action produces.
* Can be used as input for further pipeline actions.
*/
readonly output: codepipeline.Artifact;

/**
* The ARN of the CodeStar Connection created in the AWS console
* that has permissions to access this BitBucket repository.
*
* @example 'arn:aws:codestar-connections:us-east-1:123456789012:connection/12345678-abcd-12ab-34cdef5678gh'
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/connections-create.html
*/
readonly connectionArn: string;

/**
* The owning user or organization of the repository.
*
* @example 'aws'
*/
readonly owner: string;

/**
* The name of the repository.
*
* @example 'aws-cdk'
*/
readonly repo: string;

/**
* The branch to build.
*
* @default 'master'
*/
readonly branch?: string;

// long URL in @see
/**
* Whether the output should be the contents of the repository
* (which is the default),
* or a link that allows CodeBuild to clone the repository before building.
*
* **Note**: if this option is true,
* then only CodeBuild actions can use the resulting {@link output}.
*
* @default false
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html#action-reference-CodestarConnectionSource-config
*/
readonly codeBuildCloneOutput?: boolean;

/**
* Controls automatically starting your pipeline when a new commit
* is made on the configured repository and branch. If unspecified,
* the default value is true, and the field does not display by default.
*
* @default true
* @see https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html
*/
readonly triggerOnPush?: boolean;
}

/**
* A CodePipeline source action for the CodeStar Connections source,
* which allows connecting to GitHub and BitBucket.
*/
export class CodeStarConnectionsSourceAction extends Action {
/**
* The name of the property that holds the ARN of the CodeStar Connection
* inside of the CodePipeline Artifact's metadata.
*
* @internal
*/
public static readonly _CONNECTION_ARN_PROPERTY = 'CodeStarConnectionArnProperty';

private readonly props: CodeStarConnectionsSourceActionProps;

constructor(props: CodeStarConnectionsSourceActionProps) {
super({
...props,
category: codepipeline.ActionCategory.SOURCE,
owner: 'AWS', // because props also has a (different!) owner property!
provider: 'CodeStarSourceConnection',
artifactBounds: sourceArtifactBounds(),
outputs: [props.output],
});

this.props = props;
}

protected bound(_scope: Construct, _stage: codepipeline.IStage, options: codepipeline.ActionBindOptions): codepipeline.ActionConfig {
// https://docs.aws.amazon.com/codepipeline/latest/userguide/security-iam.html#how-to-update-role-new-services
options.role.addToPolicy(new iam.PolicyStatement({
actions: [
'codestar-connections:UseConnection',
],
resources: [
this.props.connectionArn,
],
}));

// the action needs to write the output to the pipeline bucket
options.bucket.grantReadWrite(options.role);
options.bucket.grantPutAcl(options.role);

// if codeBuildCloneOutput is true,
// save the connectionArn in the Artifact instance
// to be read by the CodeBuildAction later
if (this.props.codeBuildCloneOutput === true) {
this.props.output.setMetadata(CodeStarConnectionsSourceAction._CONNECTION_ARN_PROPERTY,
this.props.connectionArn);
}

return {
configuration: {
ConnectionArn: this.props.connectionArn,
FullRepositoryId: `${this.props.owner}/${this.props.repo}`,
BranchName: this.props.branch ?? 'master',
OutputArtifactFormat: this.props.codeBuildCloneOutput === true
? 'CODEBUILD_CLONE_REF'
: undefined,
DetectChanges: this.props.triggerOnPush,
},
};
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts
@@ -1,5 +1,6 @@
export * from './alexa-ask/deploy-action';
export * from './bitbucket/source-action';
export * from './codestar-connections/source-action';
export * from './cloudformation/pipeline-actions';
export * from './codebuild/build-action';
export * from './codecommit/source-action';
Expand Down

0 comments on commit 8782e67

Please sign in to comment.