Skip to content

Commit 6255af7

Browse files
trivikrjoyeecheung
authored andcommitted
git-node: wait time for PR with single approval
One Collaborator approval is enough only if the pull request has been open for more than 7 days Refs: nodejs/node#22255
1 parent 93286f2 commit 6255af7

File tree

3 files changed

+103
-7
lines changed

3 files changed

+103
-7
lines changed

lib/pr_checker.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const MINUTE = SECOND * 60;
55
const HOUR = MINUTE * 60;
66

77
const WAIT_TIME = 48;
8+
const WAIT_TIME_SINGLE_APPROVAL = 168;
89

910
const {
1011
REVIEW_SOURCES: { FROM_COMMENT, FROM_REVIEW_COMMENT }
@@ -132,12 +133,16 @@ class PRChecker {
132133
*/
133134
getWait(now) {
134135
const createTime = new Date(this.pr.createdAt);
135-
const timeLeft = WAIT_TIME - Math.ceil(
136+
const hoursFromCreateTime = Math.ceil(
136137
(now.getTime() - createTime.getTime()) / HOUR
137138
);
139+
const timeLeft = WAIT_TIME - hoursFromCreateTime;
140+
const timeLeftSingleApproval =
141+
WAIT_TIME_SINGLE_APPROVAL - hoursFromCreateTime;
138142

139143
return {
140-
timeLeft
144+
timeLeft,
145+
timeLeftSingleApproval
141146
};
142147
}
143148

@@ -149,12 +154,12 @@ class PRChecker {
149154
const {
150155
pr, cli, reviewers, CIStatus
151156
} = this;
157+
const { approved } = reviewers;
152158
const labels = pr.labels.nodes;
153159

154160
const fast =
155161
labels.some((l) => ['fast-track'].includes(l.name));
156162
if (fast) {
157-
const { approved } = reviewers;
158163
if (approved.length > 1 && CIStatus) {
159164
cli.info('This PR is being fast-tracked');
160165
return true;
@@ -171,14 +176,25 @@ class PRChecker {
171176
return false;
172177
}
173178

179+
const dateStr = new Date(pr.createdAt).toDateString();
180+
cli.info(`This PR was created on ${dateStr}`);
181+
174182
const wait = this.getWait(now);
175-
if (wait.timeLeft > 0) {
176-
const dateStr = new Date(pr.createdAt).toDateString();
177-
cli.info(`This PR was created on ${dateStr}`);
183+
if (approved.length > 1 && wait.timeLeft > 0) {
178184
cli.warn(`Wait at least ${wait.timeLeft} more hours before landing`);
179185
return false;
186+
} else if (approved.length === 1 && wait.timeLeftSingleApproval > 0) {
187+
const waitMsg = wait.timeLeft > 0
188+
? ` and ${wait.timeLeft} more hours`
189+
: '';
190+
cli.warn('Wait at one of the following:');
191+
cli.warn(`* another approval${waitMsg}`);
192+
cli.warn(`* ${wait.timeLeftSingleApproval} more hours` +
193+
' with existing single approval');
194+
return false;
180195
}
181196

197+
cli.info('No more waiting required');
182198
return true;
183199
}
184200

test/fixtures/data.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ const allGreenReviewers = {
1515
approved,
1616
requestedChanges: []
1717
};
18+
const singleGreenReviewer = {
19+
approved: [approved[0]],
20+
requestedChanges: []
21+
};
1822
const requestedChangesReviewers = {
1923
requestedChanges,
2024
approved: []
@@ -76,6 +80,7 @@ module.exports = {
7680
approved,
7781
requestedChanges,
7882
allGreenReviewers,
83+
singleGreenReviewer,
7984
requestedChangesReviewers,
8085
approvingReviews,
8186
requestingChangesReviews,

test/unit/pr_checker.test.js

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const PRChecker = require('../../lib/pr_checker');
1010

1111
const {
1212
allGreenReviewers,
13+
singleGreenReviewer,
1314
requestedChangesReviewers,
1415
approvingReviews,
1516
requestingChangesReviews,
@@ -169,7 +170,9 @@ describe('PRChecker', () => {
169170
const cli = new TestCLI();
170171

171172
const expectedLogs = {
172-
warn: [['Wait at least 22 more hours before landing']],
173+
warn: [
174+
['Wait at least 22 more hours before landing']
175+
],
173176
info: [['This PR was created on Tue Oct 31 2017']]
174177
};
175178

@@ -197,6 +200,78 @@ describe('PRChecker', () => {
197200
cli.assertCalledWith(expectedLogs);
198201
});
199202

203+
it('should warn about PR with single approval (<48h)', () => {
204+
const cli = new TestCLI();
205+
206+
const expectedLogs = {
207+
warn: [
208+
['Wait at one of the following:'],
209+
['* another approval and 22 more hours'],
210+
['* 142 more hours with existing single approval']
211+
],
212+
info: [['This PR was created on Tue Oct 31 2017']]
213+
};
214+
215+
const now = new Date('2017-11-01T14:25:41.682Z');
216+
const youngPR = Object.assign({}, firstTimerPR, {
217+
createdAt: '2017-10-31T13:00:41.682Z'
218+
});
219+
220+
const data = {
221+
pr: youngPR,
222+
reviewers: singleGreenReviewer,
223+
comments: commentsWithLGTM,
224+
reviews: approvingReviews,
225+
commits: simpleCommits,
226+
collaborators,
227+
authorIsNew: () => true,
228+
getThread() {
229+
return PRData.prototype.getThread.call(this);
230+
}
231+
};
232+
const checker = new PRChecker(cli, data, argv);
233+
234+
const status = checker.checkPRWait(now);
235+
assert(!status);
236+
cli.assertCalledWith(expectedLogs);
237+
});
238+
239+
it('should warn about PR with single approval (>48h)', () => {
240+
const cli = new TestCLI();
241+
242+
const expectedLogs = {
243+
warn: [
244+
['Wait at one of the following:'],
245+
['* another approval'],
246+
['* 94 more hours with existing single approval']
247+
],
248+
info: [['This PR was created on Tue Oct 31 2017']]
249+
};
250+
251+
const now = new Date('2017-11-03T14:25:41.682Z');
252+
const youngPR = Object.assign({}, firstTimerPR, {
253+
createdAt: '2017-10-31T13:00:41.682Z'
254+
});
255+
256+
const data = {
257+
pr: youngPR,
258+
reviewers: singleGreenReviewer,
259+
comments: commentsWithLGTM,
260+
reviews: approvingReviews,
261+
commits: simpleCommits,
262+
collaborators,
263+
authorIsNew: () => true,
264+
getThread() {
265+
return PRData.prototype.getThread.call(this);
266+
}
267+
};
268+
const checker = new PRChecker(cli, data, argv);
269+
270+
const status = checker.checkPRWait(now);
271+
assert(!status);
272+
cli.assertCalledWith(expectedLogs);
273+
});
274+
200275
it('should log as expected if PR can be fast-tracked', () => {
201276
const cli = new TestCLI();
202277

0 commit comments

Comments
 (0)