in functions/src/plugins/merge.ts [269:310]
async getPendingReviews(context: Context, pr: CachedPullRequest): Promise<number> {
const {owner, repo} = context.repo();
// We can have a lot of reviews on a PR, we need to paginate to get all of them
const reviews = (await context.github.paginate(context.github.pullRequests.listReviews({
owner,
repo,
number: pr.number,
per_page: 100
}), pages => (pages as any).data) as Review[])
// We only want reviews with state: PENDING, APPROVED, CHANGES_REQUESTED, DISMISSED.
// We ignore comments because they can be done after a review was approved / refused, and also because
// anyone can add comments, it doesn't mean that it's someone who is actually reviewing the PR
.filter(review => review.state !== REVIEW_STATE.Commented)
// We ignore reviews from individuals who aren't members of the repository
.filter(review => review.author_association !== AUTHOR_ASSOCIATION.None)
// Order by latest review first
.sort((review1, review2) => new Date(review2.submitted_at).getTime() - new Date(review1.submitted_at).getTime());
// The list of requested reviewers only contains people that have been requested for review but have not
// given the review yet. Once they do, they disappear from this list, and we need to check the reviews.
// We only take the reviews from users and ignore team reviews so that we don't conflict with Github code owners
// that automatically add team to the reviewers list
const reviewRequests =(await context.github.pullRequests.listReviewRequests({owner, repo, number: pr.number})).data.users || [];
const usersReviews: number[] = [];
const finalReviews: any[] = [];
// For each individual that reviewed this PR, we only keep the latest review (it can either be pending, approved,
// changes_requested or dismissed)
reviews.forEach(review => {
const reviewUser = review.user.id;
if(!usersReviews.includes(reviewUser)) {
usersReviews.push(reviewUser);
finalReviews.push(review);
}
});
// We want the list of "non-approved" reviews, so we only keep the reviews that are pending / requested changes
const nonApprovedReviews = finalReviews.filter(review => review.state === REVIEW_STATE.Pending || review.state === REVIEW_STATE.ChangesRequest);
return reviewRequests.length + nonApprovedReviews.length;
}