[llvm] [GitHub][workflows] Ask reviewers to merge PRs when author can not (PR #81142)

David Spickett via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 9 01:18:31 PST 2024


================
@@ -298,6 +299,76 @@ def run(self) -> bool:
         return True
 
 
+class PRMergeOnBehalfInformation:
+    COMMENT_TAG = "<!--LLVM MERGE ON BEHALF INFORMATION COMMENT-->\n"
+
+    def __init__(self, token: str, repo: str, pr_number: int, author: str):
+        repo = github.Github(token).get_repo(repo)
+        self.pr = repo.get_issue(pr_number).as_pull_request()
+        self.author = author
+        self.repo = repo
+        self.token = token
+
+    def author_has_push_permission(self):
+        # https://docs.github.com/en/rest/collaborators/collaborators?apiVersion=2022-11-28#get-repository-permissions-for-a-user
+        response = requests.get(
+            # Where repo is "owner/repo-name".
+            f"https://api.github.com/repos/{self.repo}/collaborators/{self.author}/permission",
+            headers={
+                "Accept": "application/vnd.github+json",
+                "Authorization": f"Bearer {self.token}",
+                "X-GitHub-Api-Version": "2022-11-28",
+            },
+        )
+
+        # 404 means this user is not a collaborator.
+        if response.status_code == 404:
+            # Does not have push permission if not a collaborator.
+            return False
+        # User is a collaborator.
+        elif response.status_code == 200:
+            user_details = json.loads(response.text)
+            user = user_details["user"]
+
+            # We may have a list of permissions.
+            if permissions := user.get("permissions"):
+                return permissions["pull"]
+            else:
+                # Otherwise we can always fall back to the permission
+                # on the top level object. The other permissions "read" and
+                # "none" cannot push changes.
+                return user_details["permisson"] in ["admin", "write"]
+        else:
+            # Something went wrong, log and carry on.
+            print("Unexpected response code", response.status_code)
+            # Assume they do have push permissions, so that we don't spam
+            # PRs with comments if there are API problems.
+            return True
+
+    def run(self) -> bool:
+        # A review can be approved more than once, only comment the first time.
+        # Doing this check first as I'm assuming we get the comment data "free" in
+        # terms of API cost.
----------------
DavidSpickett wrote:

> Why do you think this is free?

I forgot that the comments are actually being retrieved by the REST API anyway, via the python wrapper. Instead of being part of the event data we get when the workflow is triggered.

https://github.com/llvm/llvm-project/pull/81142


More information about the llvm-commits mailing list