[GHF] Add pagination support for reviews (#77274)

Fixes issue when PR can not be merged if it has more than 100 reviews

Test it on #76123 that has 100+ review comments

Pull Request resolved: https://github.com/pytorch/pytorch/pull/77274
Approved by: https://github.com/suo, https://github.com/seemethere
This commit is contained in:
Nikita Shulga
2022-05-11 21:00:35 +00:00
committed by PyTorch MergeBot
parent 225b037df8
commit c656e61b67
3 changed files with 9765 additions and 8201 deletions

View File

@ -111,7 +111,10 @@ query ($owner: String!, $name: String!, $number: Int!) {
}
state
}
totalCount
pageInfo {
startCursor
hasPreviousPage
}
}
comments(last: 5) {
nodes {
@ -269,6 +272,27 @@ query ($owner: String!, $name: String!, $number: Int!, $cursor: String) {
}
"""
GH_GET_PR_PREV_REVIEWS_QUERY = """
query ($owner: String!, $name: String!, $number: Int!, $cursor: String!) {
repository(name: $name, owner: $owner) {
pullRequest(number: $number) {
reviews(last: 100, before: $cursor) {
nodes {
author {
login
}
state
}
pageInfo {
startCursor
hasPreviousPage
}
}
}
}
}
"""
RE_GHSTACK_HEAD_REF = re.compile(r"^(gh/[^/]+/[0-9]+/)head$")
RE_GHSTACK_SOURCE_ID = re.compile(r'^ghstack-source-id: (.+)\n?', re.MULTILINE)
RE_PULL_REQUEST_RESOLVED = re.compile(
@ -381,6 +405,7 @@ class GitHubPR:
self.conclusions: Optional[Dict[str, str]] = None
self.comments: Optional[List[GitHubComment]] = None
self._authors: Optional[List[Tuple[str, str]]] = None
self._reviews: Optional[List[Tuple[str, str]]] = None
def is_closed(self) -> bool:
return bool(self.info["closed"])
@ -426,21 +451,29 @@ class GitHubPR:
raise RuntimeError("Changed file count mismatch")
return self.changed_files
def _get_reviewers(self) -> List[Tuple[str, str]]:
reviews_count = int(self.info["reviews"]["totalCount"])
nodes = self.info["reviews"]["nodes"]
if len(nodes) != reviews_count:
raise RuntimeError("Can't fetch all PR reviews")
def _get_reviews(self) -> List[Tuple[str, str]]:
if self._reviews is None:
self._reviews = []
info = self.info
for _ in range(100):
nodes = info["reviews"]["nodes"]
self._reviews = [(node["author"]["login"], node["state"]) for node in nodes] + self._reviews
if not info["reviews"]["pageInfo"]["hasPreviousPage"]:
break
rc = gh_graphql(GH_GET_PR_PREV_REVIEWS_QUERY,
name=self.project,
owner=self.org,
number=self.pr_num,
cursor=info["reviews"]["pageInfo"]["startCursor"])
info = rc["data"]["repository"]["pullRequest"]
reviews = {}
for node in nodes:
author = node["author"]["login"]
state = node["state"]
for (author, state) in self._reviews:
if state != "COMMENTED":
reviews[author] = state
return list(reviews.items())
def get_approved_by(self) -> List[str]:
return [login for (login, state) in self._get_reviewers() if state == "APPROVED"]
return [login for (login, state) in self._get_reviews() if state == "APPROVED"]
def get_commit_count(self) -> int:
return int(self.info["commits_with_authors"]["totalCount"])