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): variables for CodeStar Connections source Action #18086

Merged
merged 7 commits into from
Dec 29, 2021
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
29 changes: 29 additions & 0 deletions packages/@aws-cdk/aws-codepipeline-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,35 @@ const sourceAction = new codepipeline_actions.CodeStarConnectionsSourceAction({
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).

Similarly to `GitHubSourceAction`, `CodeStarConnectionsSourceAction` also emits the variables:

```ts
declare const project: codebuild.Project;

const sourceOutput = new codepipeline.Artifact();
const sourceAction = new codepipeline_actions.CodeStarConnectionsSourceAction({
skinny85 marked this conversation as resolved.
Show resolved Hide resolved
actionName: 'BitBucket_Source',
owner: 'aws',
repo: 'aws-cdk',
output: sourceOutput,
connectionArn: 'arn:aws:codestar-connections:us-east-1:123456789012:connection/12345678-abcd-12ab-34cdef5678gh',
variablesNamespace: 'SomeSpace', // optional - by default, a name will be generated for you
});

// later:

new codepipeline_actions.CodeBuildAction({
actionName: 'CodeBuild',
project,
input: sourceOutput,
environmentVariables: {
COMMIT_ID: {
value: sourceAction.variables.commitId,
},
},
});
```

### AWS S3 Source

To use an S3 Bucket as a source in CodePipeline:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@ import { sourceArtifactBounds } from '../common';
// eslint-disable-next-line no-duplicate-imports, import/order
import { Construct } from '@aws-cdk/core';
kornicameister marked this conversation as resolved.
Show resolved Hide resolved

/**
* The CodePipeline variables emitted by CodeStar source Action.
*/
export interface CodeStarSourceVariables {
/** The name of the repository this action points to. */
readonly fullRepositoryName: string;
/** The name of the branch this action tracks. */
readonly branchName: string;
/** The date the currently last commit on the tracked branch was authored, in ISO-8601 format. */
readonly authorDate: string;
/** The SHA1 hash of the currently last commit on the tracked branch. */
readonly commitId: string;
/** The message of the currently last commit on the tracked branch. */
readonly commitMessage: string;
/** The connection ARN this source uses. */
readonly connectionArn: string;
}

/**
* Construction properties for {@link CodeStarConnectionsSourceAction}.
*/
Expand Down Expand Up @@ -101,6 +119,18 @@ export class CodeStarConnectionsSourceAction extends Action {
this.props = props;
}

/** The variables emitted by this action. */
public get variables(): CodeStarSourceVariables {
return {
fullRepositoryName: this.variableExpression('FullRepositoryName'),
branchName: this.variableExpression('BranchName'),
authorDate: this.variableExpression('AuthorDate'),
commitId: this.variableExpression('CommitId'),
commitMessage: this.variableExpression('CommitMessage'),
connectionArn: this.variableExpression('ConnectionArn'),
};
}

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({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '@aws-cdk/assert-internal/jest';
import { arrayWith, objectLike } from '@aws-cdk/assert-internal';
import { arrayWith, objectLike, SynthUtils } from '@aws-cdk/assert-internal';
import * as codebuild from '@aws-cdk/aws-codebuild';
import * as codepipeline from '@aws-cdk/aws-codepipeline';
import { Stack } from '@aws-cdk/core';
Expand Down Expand Up @@ -148,26 +148,139 @@ describe('CodeStar Connections source Action', () => {
],
});

});

test('exposes variables', () => {
const stack = new Stack();
createBitBucketAndCodeBuildPipeline(stack);

expect(stack).toHaveResourceLike('AWS::CodePipeline::Pipeline', {
'Stages': [
{
'Name': 'Source',
},
{
'Name': 'Build',
'Actions': [
{
'Name': 'CodeBuild',
'Configuration': {
'EnvironmentVariables': '[{"name":"CommitId","type":"PLAINTEXT","value":"#{Source_BitBucket_NS.CommitId}"}]',
},
},
],
},
],
});
});

test('exposes variables with custom namespace', () => {
const stack = new Stack();
createBitBucketAndCodeBuildPipeline(stack, {
variablesNamespace: 'kornicameister',
});

expect(stack).toHaveResourceLike('AWS::CodePipeline::Pipeline', {
'Stages': [
{
'Name': 'Source',
'Actions': [
{
'Name': 'BitBucket',
'Namespace': 'kornicameister',
},
],
},
{
'Name': 'Build',
'Actions': [
{
'Name': 'CodeBuild',
'Configuration': {
'EnvironmentVariables': '[{"name":"CommitId","type":"PLAINTEXT","value":"#{kornicameister.CommitId}"}]',
},
},
],
},
],
});
});

test('fail if variable from unused action is referenced', () => {
const stack = new Stack();
const pipeline = createBitBucketAndCodeBuildPipeline(stack);

const unusedSourceOutput = new codepipeline.Artifact();
const unusedSourceAction = new cpactions.CodeStarConnectionsSourceAction({
actionName: 'UnusedBitBucket',
owner: 'aws',
repo: 'aws-cdk',
output: unusedSourceOutput,
connectionArn: 'arn:aws:codestar-connections:us-east-1:123456789012:connection/12345678-abcd-12ab-34cdef5678gh',
});
const unusedBuildAction = new cpactions.CodeBuildAction({
actionName: 'UnusedCodeBuild',
project: new codebuild.PipelineProject(stack, 'UnusedMyProject'),
input: unusedSourceOutput,
environmentVariables: {
CommitId: { value: unusedSourceAction.variables.commitId },
},
});
pipeline.stage('Build').addAction(unusedBuildAction);

expect(() => {
SynthUtils.synthesize(stack);
}).toThrow(/Cannot reference variables of action 'UnusedBitBucket', as that action was never added to a pipeline/);
});

test('fail if variable from unused action with custom namespace is referenced', () => {
const stack = new Stack();
const pipeline = createBitBucketAndCodeBuildPipeline(stack, {
variablesNamespace: 'kornicameister',
});
const unusedSourceOutput = new codepipeline.Artifact();
const unusedSourceAction = new cpactions.CodeStarConnectionsSourceAction({
actionName: 'UnusedBitBucket',
owner: 'aws',
repo: 'aws-cdk',
output: unusedSourceOutput,
connectionArn: 'arn:aws:codestar-connections:us-east-1:123456789012:connection/12345678-abcd-12ab-34cdef5678gh',
variablesNamespace: 'kornicameister',
});
const unusedBuildAction = new cpactions.CodeBuildAction({
actionName: 'UnusedCodeBuild',
project: new codebuild.PipelineProject(stack, 'UnusedProject'),
input: unusedSourceOutput,
environmentVariables: {
CommitId: { value: unusedSourceAction.variables.commitId },
},
});
pipeline.stage('Build').addAction(unusedBuildAction);

expect(() => {
SynthUtils.synthesize(stack);
}).toThrow(/Cannot reference variables of action 'UnusedBitBucket', as that action was never added to a pipeline/);
});
});

function createBitBucketAndCodeBuildPipeline(stack: Stack, props: Partial<cpactions.BitBucketSourceActionProps>): void {
function createBitBucketAndCodeBuildPipeline(
stack: Stack, props: Partial<cpactions.CodeStarConnectionsSourceActionProps> = {},
): codepipeline.Pipeline {
const sourceOutput = new codepipeline.Artifact();
new codepipeline.Pipeline(stack, 'Pipeline', {
const sourceAction = new cpactions.CodeStarConnectionsSourceAction({
actionName: 'BitBucket',
owner: 'aws',
repo: 'aws-cdk',
output: sourceOutput,
connectionArn: 'arn:aws:codestar-connections:us-east-1:123456789012:connection/12345678-abcd-12ab-34cdef5678gh',
...props,
});

return new codepipeline.Pipeline(stack, 'Pipeline', {
stages: [
{
stageName: 'Source',
actions: [
new cpactions.CodeStarConnectionsSourceAction({
actionName: 'BitBucket',
owner: 'aws',
repo: 'aws-cdk',
output: sourceOutput,
connectionArn: 'arn:aws:codestar-connections:us-east-1:123456789012:connection/12345678-abcd-12ab-34cdef5678gh',
...props,
}),
],
actions: [sourceAction],
},
{
stageName: 'Build',
Expand All @@ -177,6 +290,9 @@ function createBitBucketAndCodeBuildPipeline(stack: Stack, props: Partial<cpacti
project: new codebuild.PipelineProject(stack, 'MyProject'),
input: sourceOutput,
outputs: [new codepipeline.Artifact()],
environmentVariables: {
CommitId: { value: sourceAction.variables.commitId },
},
}),
],
},
Expand Down