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

Implement PR reviewed checks #116

Merged
merged 17 commits into from
Aug 28, 2020
Merged

Conversation

jameesjohn
Copy link
Contributor

Explanation

This PR implements the checks that are to be done when a PR gets reviewed.

  1. Reviewer reviews and approves
    • Bot unassigns reviewer and assigns next reviewer(s)(if any).
    • If all reviewers have approved, bot checks if the user has merging rights and assigns user if that is the case or otherwise assigns one of the reviewers.
  2. Reviewer reviews and requests changes
    • Bot unassigns reviewer and assigns the user

This functionality has been tested at jameesjohn/comment-on-pr#8 (review)

Checklist

  • I have successfully deployed my own instance of Oppiabot.
    • You can find instructions for doing this here.
  • I have manually tested all the changes made in this PR following the manual tests matrix.

Copy link
Contributor

@ankita240796 ankita240796 left a 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 = [
Copy link
Contributor

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.

Copy link
Contributor Author

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('@');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ -> Constant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

const handleChangesRequested = async (context) => {
// Pause for 3 minutes in case reviewer wants to perform
// the required actions.
await utilityModule.sleep(60 * 1000 * 3);
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

const LGTM_LABEL = 'PR: LGTM';

/**
* This functions handles a changes requested review.
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

*/
const review = context.payload.review;
// Fetch the pull request incase there has been any changes since
// the review was made.
Copy link
Contributor

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?

Copy link
Contributor Author

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.
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

username: pullRequest.user.login,
});

if (membershipCheckResponse.status === 204) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

204 -> constant

Copy link
Contributor Author

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({
Copy link
Contributor

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.

Copy link
Contributor Author

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) {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, my bad.

await context.github.issues.addLabels(
context.repo({
issue_number: pullRequest.number,
labels: [LGTM_LABEL],
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

@ankita240796 ankita240796 left a 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 Show resolved Hide resolved
await context.github.issues.addLabels(
context.repo({
issue_number: pullRequest.number,
labels: [LGTM_LABEL],
Copy link
Contributor

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.

body:
'Hi @' +
reviewer +
', this PR is ready to be merged, PTAL. Thanks!',
Copy link
Contributor

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.

Copy link
Contributor Author

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.

body:
'Hi @' +
pullRequest.user.login +
', this PR is ready to be merged, PTAL. Thanks!',
Copy link
Contributor

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.

Copy link
Contributor Author

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.

await robot.receive(payloadData);
});

it('should check review', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check type of review

Copy link
Contributor Author

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', () => {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

expect(github.issues.addAssignees).not.toHaveBeenCalled();
});

it('should not ping remaining reviewers', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

});

it('should not ping remaining reviewers', () => {
expect(github.issues.createComment).not.toHaveBeenCalledTimes(2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 2 times?

Copy link
Contributor Author

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', () => {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

});
});

describe('when reviewer already unassigns themselves', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the description correct?

Copy link
Contributor Author

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.

issue_number: pullRequest.number,
body:
'Hi @' +
reviewer +
Copy link
Contributor

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...

Copy link
Contributor Author

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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, my bad.

});
});

describe(' when reviewer is not assigned.', () => {
Copy link
Contributor

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.

Copy link
Contributor

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?

Copy link
Contributor Author

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', () => {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@oppiabot
Copy link

oppiabot bot commented Aug 24, 2020

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')
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* @param {import('probot').Octokit.PullsGetResponse} pullRequest
* @param {String} changelogLabel
*/
const canAssignProjectOwner = (pullRequest, changelogLabel) => {
Copy link
Contributor

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?

Copy link
Contributor Author

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) => {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, Removed.

);
}
} else {
// The pull request has been approved, and we need to add the LGTM label.
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 192 to 196
// 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})
Copy link
Contributor

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?

Copy link
Contributor Author

@jameesjohn jameesjohn Aug 25, 2020

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.

);
const pullRequest = pullRequestResponse.data;

if (pullRequest.state === 'closed') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

closed -> constant.

Copy link
Contributor Author

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', () => {
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

});

describe('when all reviewers have approved and none are assigned.', () => {
// Note that when the reviewer is the last reviewer, the list of
Copy link
Contributor

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.

Copy link
Contributor Author

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.

});
});

describe('when all reviewers have approved and none are assigned.', () => {
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@ankita240796 ankita240796 mentioned this pull request Aug 25, 2020
2 tasks
Copy link
Contributor

@ankita240796 ankita240796 left a 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!

const searchResult = await context.github.search.issuesAndPullRequests(
context.repo({
q:
'repo:' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this into constant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

q:
'repo:' +
context.payload.repository.full_name +
' review:approved ' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

})
);
const pullRequest = pullRequestResponse.data;
const CLOSED_STATE = 'closed';
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

body:
'Hi @' +
assignees[0] +
', this PR is ready to be merged. We are assigning you since ' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assigning -> pinging

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

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;
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified to continue check.

Comment on lines 196 to 215
// 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;
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

@ankita240796 ankita240796 left a 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!

* 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
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

} 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
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

});
});

it('should ping one of the reviewers to merge', () => {
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

});

describe(
'when reviewer is the last reviewer and pr author can not merge', () => {
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

@ankita240796 ankita240796 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Thanks @jameesjohn!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants