-
Notifications
You must be signed in to change notification settings - Fork 67
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
Implement PR reviewed checks #116
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jameesjohn, thanks for the PR! This looks great, took a pass at the main module, will be checking the specs in some time. PTAL, Thanks!
@@ -17,6 +17,9 @@ | |||
*/ | |||
|
|||
const DATASTORE_LABEL = 'PR: Affects datastore layer'; | |||
const LABELS_EXCLUDED_FROM_CODEOWNER_ASSIGNMENT = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a brief comment to explain why we excluded them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/utils.js
Outdated
* @param {String} changelogLabel | ||
*/ | ||
const getProjectOwnerFromLabel = (changelogLabel) => { | ||
const labelSubstrings = changelogLabel.split('@'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@
-> Constant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
const handleChangesRequested = async (context) => { | ||
// Pause for 3 minutes in case reviewer wants to perform | ||
// the required actions. | ||
await utilityModule.sleep(60 * 1000 * 3); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declare 3 minutes as constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
const LGTM_LABEL = 'PR: LGTM'; | ||
|
||
/** | ||
* This functions handles a changes requested review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explain what the function does to handle the changes requested review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
*/ | ||
const review = context.payload.review; | ||
// Fetch the pull request incase there has been any changes since | ||
// the review was made. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What changes, do you mean in the 3 minutes we pause?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes
); | ||
} | ||
|
||
// Check if pull request has been approved by all reviewers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment as to why we can't directly check from the pull request payload that it is approved by all reviewers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
username: pullRequest.user.login, | ||
}); | ||
|
||
if (membershipCheckResponse.status === 204) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
204 -> constant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
if (membershipCheckResponse.status === 204) { | ||
// Assign author. | ||
await context.github.issues.addAssignees( | ||
context.repo({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should create comment here too asking author to merge the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* @type {import('probot').Octokit.PullsGetReviewResponse} review | ||
*/ | ||
const review = context.payload.review; | ||
if (review.state === CHANGES_REQUESTED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make the states as constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are set as constants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, my bad.
lib/checkPullRequestReview.js
Outdated
await context.github.issues.addLabels( | ||
context.repo({ | ||
issue_number: pullRequest.number, | ||
labels: [LGTM_LABEL], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other thing - there are cases some times when the reviewer approves the PR but requests a minor change along with it (As I do sometimes on your PR :P). Is there any way to check that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we may not be able to check this accurately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, let us do one thing then - Add a note in comment for whoever is the final assignee to merge the PR: Please ensure that no comments are pending from the author's end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @jameesjohn, took a full pass, PTAL.
lib/checkPullRequestReview.js
Outdated
await context.github.issues.addLabels( | ||
context.repo({ | ||
issue_number: pullRequest.number, | ||
labels: [LGTM_LABEL], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, let us do one thing then - Add a note in comment for whoever is the final assignee to merge the PR: Please ensure that no comments are pending from the author's end.
lib/checkPullRequestReview.js
Outdated
body: | ||
'Hi @' + | ||
reviewer + | ||
', this PR is ready to be merged, PTAL. Thanks!', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure you merge the PR since the author does not have merging rights.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure about this considering the author/reviewer might need to wait for CI checks to be complete before merge.
lib/checkPullRequestReview.js
Outdated
body: | ||
'Hi @' + | ||
pullRequest.user.login + | ||
', this PR is ready to be merged, PTAL. Thanks!', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure you merge the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure about this considering the author/reviewer might need to wait for CI checks to be complete before merge.
spec/checkPullRequestReviewSpec.js
Outdated
await robot.receive(payloadData); | ||
}); | ||
|
||
it('should check review', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check type of review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
}); | ||
}); | ||
|
||
it('should ping remaining reviewers', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more - should not assign pr author.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
spec/checkPullRequestReviewSpec.js
Outdated
expect(github.issues.addAssignees).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not ping remaining reviewers', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
spec/checkPullRequestReviewSpec.js
Outdated
}); | ||
|
||
it('should not ping remaining reviewers', () => { | ||
expect(github.issues.createComment).not.toHaveBeenCalledTimes(2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 2 times?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only one comment should be added (that of the PR author).
}); | ||
}); | ||
|
||
it('should ping remaining reviewers', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not assign author case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
spec/checkPullRequestReviewSpec.js
Outdated
}); | ||
}); | ||
|
||
describe('when reviewer already unassigns themselves', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the description correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe so. I can modify it to when reviewer is not assigned.
lib/checkPullRequestReview.js
Outdated
issue_number: pullRequest.number, | ||
body: | ||
'Hi @' + | ||
reviewer + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...this PR is ready to be merged. We are assigning you since the author does not have merging rights. Please make sure...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* @type {import('probot').Octokit.PullsGetReviewResponse} review | ||
*/ | ||
const review = context.payload.review; | ||
if (review.state === CHANGES_REQUESTED) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, my bad.
spec/checkPullRequestReviewSpec.js
Outdated
}); | ||
}); | ||
|
||
describe(' when reviewer is not assigned.', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extra space after starting quote.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, shouldn't this be: when all reviewers have approved and none are assigned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Updated.
}); | ||
|
||
describe( | ||
'when reviewer is last reviewer and already adds the lgtm label', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more case - LGTM label is not added, but one of the reviewers is already assigned - are we handling that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the LGTM label is not added, we add the label. If one of the reviewers is already assigned, I'll update the code to not assign any other person.
Hi @jameesjohn. Due to recent changes in the "develop" branch, this PR now has a merge conflict. Please follow this link if you need help resolving the conflict, so that the PR can be merged. Thanks! |
lib/utils.js
Outdated
*/ | ||
const getChangelogLabelFromPullRequest = (pullRequest) => { | ||
const label = pullRequest.labels.find((label) => | ||
label.name.toUpperCase().startsWith('PR CHANGELOG') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make PR CHANGELOG
a constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestLabels.js
Outdated
* @param {import('probot').Octokit.PullsGetResponse} pullRequest | ||
* @param {String} changelogLabel | ||
*/ | ||
const canAssignProjectOwner = (pullRequest, changelogLabel) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we moving this to utils?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this was done before I decided to assign the last reviewer. I'll move it back here.
lib/utils.js
Outdated
* @param {import('probot').Octokit.PullsGetResponse} pullRequest | ||
* @param {String} changelogLabel | ||
*/ | ||
const canAssignProjectOwner = (pullRequest, changelogLabel) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this function being used anywhere else other than check pull req label module?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, Removed.
lib/checkPullRequestReview.js
Outdated
); | ||
} | ||
} else { | ||
// The pull request has been approved, and we need to add the LGTM label. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the pull request has been approved, we add the LGTM label.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
// The last reviewer got unassigned, but the pull request assignees list | ||
// does not reflect that since we did not refetch the pull request data, | ||
// hence if any other person is assigned to the pull request, they are | ||
// likely the one to merge it. | ||
console.log({assignees}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove the console.log, I think.
Also, we should add a comment before returning, asking the assignee for merging.
And why not just check membership of the assignees instead of comparing them to reviewer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove the console.log, I think.
Removed.
And why not just check membership of the assignees instead of comparing them to reviewer?
I believe all reviewers should have merging rights, right?
Also, we should add a comment before returning, asking the assignee for merging.
Comment added.
lib/checkPullRequestReview.js
Outdated
); | ||
const pullRequest = pullRequestResponse.data; | ||
|
||
if (pullRequest.state === 'closed') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
closed -> constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
}); | ||
}); | ||
|
||
it('should not assign remaining reviewers', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more case - not assign PR author.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
spec/checkPullRequestReviewSpec.js
Outdated
}); | ||
|
||
describe('when all reviewers have approved and none are assigned.', () => { | ||
// Note that when the reviewer is the last reviewer, the list of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add an example - comment isn't that clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how the example to add since this can only be noticed from the payload. I've modified the comment though.
spec/checkPullRequestReviewSpec.js
Outdated
}); | ||
}); | ||
|
||
describe('when all reviewers have approved and none are assigned.', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and pr author cannot merge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final comments, Thanks @jameesjohn!
lib/checkPullRequestReview.js
Outdated
const searchResult = await context.github.search.issuesAndPullRequests( | ||
context.repo({ | ||
q: | ||
'repo:' + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this into constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/checkPullRequestReview.js
Outdated
q: | ||
'repo:' + | ||
context.payload.repository.full_name + | ||
' review:approved ' + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
}) | ||
); | ||
const pullRequest = pullRequestResponse.data; | ||
const CLOSED_STATE = 'closed'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it a top level constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
body: | ||
'Hi @' + | ||
assignees[0] + | ||
', this PR is ready to be merged. We are assigning you since ' + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assigning -> pinging
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
const labels = pullRequest.labels.map((label) => label.name); | ||
if (labels.includes(LGTM_LABEL)) { | ||
// Do nothing and end execution if label has already been added. | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if label is added but no one is assigned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modified to continue check.
lib/checkPullRequestReview.js
Outdated
// The last reviewer got unassigned, but the pull request assignees list | ||
// does not reflect that since we did not refetch the pull request data, | ||
// hence if any other person is assigned to the pull request, they are | ||
// likely the one to merge it. | ||
|
||
if (assignees.some((user) => user !== reviewer)) { | ||
const remainingAssignee = assignees.find(user => user !== reviewer); | ||
await context.github.issues.createComment( | ||
context.repo({ | ||
issue_number: pullRequest.number, | ||
body: | ||
'Hi @' + | ||
remainingAssignee + | ||
', this PR is ready to be merged. We are pinging you since ' + | ||
'you are the remaining assingee on this PR. Please make sure ' + | ||
"there are no pending comments from the author's end before " + | ||
'merge. Thanks!', | ||
}) | ||
); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit confusing - can we be sure that the assignee has merging rights?
Why not do this instead - get list of assignees and check if any one of them has merging rights.
If yes - leave a comment asking them to do the merge.
If no - assign the reviewer.
This is simpler and more readable as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following discussions offline, we resolved to only assign the project owner if the author does not have merging rights since we are sure that all pull requests will have a changelog label.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments, no major concerns now. PTAL, Thanks @jameesjohn!
lib/checkPullRequestReview.js
Outdated
* 5. Assign other reviewers if any. | ||
* 5. If reviewer was the last reviewer, check if pull request has been | ||
* approved, and add the LGTM Label. | ||
* 6. If pull request has been approved, assign PR author or last reviewer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has been approved -> has LGTM label
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/checkPullRequestReview.js
Outdated
} else { | ||
// Assign project owner to merge the pull request. | ||
// A pull request will always have a changelog label because we are | ||
// assigning the PR author to the pull request on creation if created |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assigning the PR author to the pull request on creation if created without a changelog label --> assigning the PR author to the pull request if it is created without changelog label
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
spec/checkPullRequestReviewSpec.js
Outdated
}); | ||
}); | ||
|
||
it('should ping one of the reviewers to merge', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one of the reviewers -> project owner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
spec/checkPullRequestReviewSpec.js
Outdated
}); | ||
|
||
describe( | ||
'when reviewer is the last reviewer and pr author can not merge', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this different from previous case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was part of the previous implementation.
Removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, Thanks @jameesjohn!
Explanation
This PR implements the checks that are to be done when a PR gets reviewed.
This functionality has been tested at jameesjohn/comment-on-pr#8 (review)
Checklist