-
Notifications
You must be signed in to change notification settings - Fork 0
/
pullRequest.js
204 lines (190 loc) · 6.41 KB
/
pullRequest.js
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
const { getOctokit } = require("./octokit");
const { isBranchNameValid } = require("../branch");
const {
isPullRequestTitleValid: isPullRequestTitleValid,
} = require("../pullRequest");
const { getAmplifyURIs } = require("./amplify");
exports.validatePR = async function validatePR({ pullRequest, issue }) {
const octokit = getOctokit();
if (pullRequest) {
const {
number: pullNumber,
commits,
base: {
ref: baseRef,
repo: {
owner: { login: owner },
name: repo,
},
user: { login: committer },
},
head: { ref: headRef, sha: headSha },
title,
} = pullRequest;
if (
["main", "master", "preprod", "prod"].indexOf(baseRef) === -1 &&
headRef.slice(0, baseRef.length) !== baseRef &&
!headRef.slice(baseRef.length).match(/^--/) &&
!baseRef.match(/^hotfix\//)
) {
throw new Error(
`As this pull request is based on “${baseRef}”, its name should start with “${baseRef}--”. See https://www.notion.so/mobsuccess/Git-Guidelines-41996ef576cb4f29b7737772b74289c5#f9cadc10d949498dbe38c0eed08fd4f8`
);
}
if (!isBranchNameValid(headRef)) {
throw new Error(
`This pull request is based on a branch with in invalid name: “${headRef}”. See https://www.notion.so/mobsuccess/Git-Guidelines-41996ef576cb4f29b7737772b74289c5#f9cadc10d949498dbe38c0eed08fd4f8`
);
}
if (!isPullRequestTitleValid(title)) {
throw new Error(
`The title of this pull request is invalid, please edit: “${title}”. See https://www.notion.so/mobsuccess/Git-Guidelines-41996ef576cb4f29b7737772b74289c5#4ac148fd42a04141a528a87013ea5c57`
);
}
const branches = await octokit.paginate(
"GET /repos/{owner}/{repo}/branches",
{ owner, repo }
);
let oneBranchIsOk = false;
let nokBranch;
for (const { name: branchName } of branches) {
if (headRef === branchName) {
continue;
}
const prefix = headRef.substr(0, branchName.length);
const postfix = headRef.substr(branchName.length);
if (prefix === branchName && prefix.length === branchName.length) {
if (postfix.match(/^--[a-z]/)) {
oneBranchIsOk = true;
console.log(`Found OK branch: “${branchName}” matches “${headRef}”`);
} else {
nokBranch = branchName;
console.log(
`Found NOK branch: “${branchName}” does not match “${headRef}”`
);
}
}
}
if (!oneBranchIsOk && nokBranch) {
throw new Error(
`This pull request is based on the branch “${headRef}”, which starts like “${nokBranch}”. Use double dashes (“--”) to separate sub-branches. See https://app.gitbook.com/@mobsuccess/s/mobsuccess/git`
);
}
if (
commits === 1 &&
!title.match(/^Revert ".*"/) &&
!title.match(/^Bump .*/) &&
!committer === "ms-bot" &&
!committer === "ms-upgrade-aws"
) {
// we have only one commit, make sure its name match the name of the PR
const {
data: { message: commitMessage },
} = await octokit.rest.git.getCommit({
owner,
repo,
commit_sha: headSha,
});
if (commitMessage !== title) {
throw new Error(
`This pull request has only one commit, and its message doesn't match the title of the PR. If you'd like to keep the title of the PR as it is, please add an empty commit.`
);
} else {
console.log(
"This pull request has only one commit, and its message matches the title of the PR."
);
}
}
// everything seems valid: add the label if it exists
const branchTag = headRef.split("/")[0];
try {
await octokit.issues.addLabels({
owner,
repo,
issue_number: pullNumber,
labels: [branchTag],
});
} catch (e) {
// ignore error
console.log(`Could not apply label: ${e}`);
}
}
// do we have an AWS Amplify URI? If so, make sure that at least one comment
// exists with a link to it
const {
links: amplifyUris,
hiddenLinks: hiddenAmplifyUris,
} = await getAmplifyURIs();
const hiddenAmplifyText =
hiddenAmplifyUris && hiddenAmplifyUris.length > 0
? `\n<details><summary>More uris</summary>
- ${hiddenAmplifyUris.join("\n - ")}
</details>`
: "";
if (
(!amplifyUris || amplifyUris.length === 0) &&
(!hiddenAmplifyUris || hiddenAmplifyUris.length === 0)
) {
console.log("No AWS Amplify URI for this repository");
} else {
console.log("AWS Amplify URIs: ", amplifyUris, "hidden", hiddenAmplifyUris);
const pullNumber = pullRequest?.number || issue?.number;
const owner =
pullRequest?.base.repo.owner.login ||
issue?.repository_url?.split("/")[4];
const repo =
pullRequest?.base.repo.name || issue?.repository_url?.split("/")[5];
const comments = await octokit.paginate(
"GET /repos/{owner}/{repo}/issues/{issue_number}/comments",
{ owner, repo, issue_number: pullNumber }
);
// add a comment with the PR
const body =
"AWS Amplify live test URI:\n" +
"- " +
amplifyUris.join("\n- ") +
hiddenAmplifyText;
const previousComments = comments.filter(({ body }) =>
body.match(/AWS Amplify live/)
);
if (previousComments.length > 0) {
console.log(
"A comment already exists with a link to AWS Amplify, editing it"
);
const firstComment = previousComments[0];
await octokit.request(
"PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}",
{
owner,
repo,
comment_id: firstComment.id,
body,
}
);
} else {
console.log("Comment with link to Amplify URI missing, creating it");
await octokit.request(
"POST /repos/{owner}/{repo}/issues/{issue_number}/comments",
{
owner,
repo,
issue_number: pullNumber,
body,
}
);
}
// delete the bogus comments by the aws-amplify robot
const bogusComments = comments.filter(({ user: { login } }) =>
login.match(/^aws-amplify-/)
);
for (const bogusComment of bogusComments) {
const { id: commentId } = bogusComment;
console.log("Deleting comment", bogusComment);
await octokit.issues.deleteComment({
owner,
repo,
comment_id: commentId,
});
}
}
};