-
Notifications
You must be signed in to change notification settings - Fork 3.9k
/
source-action.ts
156 lines (134 loc) · 4.82 KB
/
source-action.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import * as codecommit from '@aws-cdk/aws-codecommit';
import * as codepipeline from '@aws-cdk/aws-codepipeline';
import * as targets from '@aws-cdk/aws-events-targets';
import * as iam from '@aws-cdk/aws-iam';
import { Construct } from '@aws-cdk/core';
import { Action } from '../action';
import { sourceArtifactBounds } from '../common';
/**
* How should the CodeCommit Action detect changes.
* This is the type of the {@link CodeCommitSourceAction.trigger} property.
*/
export enum CodeCommitTrigger {
/**
* The Action will never detect changes -
* the Pipeline it's part of will only begin a run when explicitly started.
*/
NONE = 'None',
/**
* CodePipeline will poll the repository to detect changes.
*/
POLL = 'Poll',
/**
* CodePipeline will use CloudWatch Events to be notified of changes.
* This is the default method of detecting changes.
*/
EVENTS = 'Events',
}
/**
* The CodePipeline variables emitted by the CodeCommit source Action.
*/
export interface CodeCommitSourceVariables {
/** The name of the repository this action points to. */
readonly repositoryName: 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 date the currently last commit on the tracked branch was committed, in ISO-8601 format. */
readonly committerDate: 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;
}
/**
* Construction properties of the {@link CodeCommitSourceAction CodeCommit source CodePipeline Action}.
*/
export interface CodeCommitSourceActionProps extends codepipeline.CommonAwsActionProps {
/**
*
*/
readonly output: codepipeline.Artifact;
/**
* @default 'master'
*/
readonly branch?: string;
/**
* How should CodePipeline detect source changes for this Action.
*
* @default CodeCommitTrigger.EVENTS
*/
readonly trigger?: CodeCommitTrigger;
/**
* The CodeCommit repository.
*/
readonly repository: codecommit.IRepository;
}
/**
* CodePipeline Source that is provided by an AWS CodeCommit repository.
*/
export class CodeCommitSourceAction extends Action {
private readonly branch: string;
private readonly props: CodeCommitSourceActionProps;
constructor(props: CodeCommitSourceActionProps) {
const branch = props.branch ?? 'master';
if (!branch) {
throw new Error("'branch' parameter cannot be an empty string");
}
super({
...props,
resource: props.repository,
category: codepipeline.ActionCategory.SOURCE,
provider: 'CodeCommit',
artifactBounds: sourceArtifactBounds(),
outputs: [props.output],
});
this.branch = branch;
this.props = props;
}
/** The variables emitted by this action. */
public get variables(): CodeCommitSourceVariables {
return {
repositoryName: this.variableExpression('RepositoryName'),
branchName: this.variableExpression('BranchName'),
authorDate: this.variableExpression('AuthorDate'),
committerDate: this.variableExpression('CommitterDate'),
commitId: this.variableExpression('CommitId'),
commitMessage: this.variableExpression('CommitMessage'),
};
}
protected bound(_scope: Construct, stage: codepipeline.IStage, options: codepipeline.ActionBindOptions):
codepipeline.ActionConfig {
const createEvent = this.props.trigger === undefined ||
this.props.trigger === CodeCommitTrigger.EVENTS;
if (createEvent) {
const branchIdDisambiguator = this.branch === 'master' ? '' : `-${this.branch}-`;
this.props.repository.onCommit(`${stage.pipeline.node.uniqueId}${branchIdDisambiguator}EventRule`, {
target: new targets.CodePipeline(stage.pipeline),
branches: [this.branch],
});
}
// the Action will write the contents of the Git repository to the Bucket,
// so its Role needs write permissions to the Pipeline Bucket
options.bucket.grantReadWrite(options.role);
// https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control-permissions-reference.html#aa-acp
options.role.addToPolicy(new iam.PolicyStatement({
resources: [this.props.repository.repositoryArn],
actions: [
'codecommit:GetBranch',
'codecommit:GetCommit',
'codecommit:UploadArchive',
'codecommit:GetUploadArchiveStatus',
'codecommit:CancelUploadArchive',
],
}));
return {
configuration: {
RepositoryName: this.props.repository.repositoryName,
BranchName: this.branch,
PollForSourceChanges: this.props.trigger === CodeCommitTrigger.POLL,
},
};
}
}