Repository: zulip/zulip

Issue:
github integration: Duplicate requested_reviewer notifications when adding two reviewers in new PR
When you open a new pull request with 2 requested reviewers, GitHub's outgoing webhook API sends you 3 events in immediate succession:
* A new pull request event
* A new reviewer 1 event
* A new reviewer 2 event

GitHub's `pull_request/review_requested` payloads appear to have two copies of the data; one inside the `pull_request` key and the other at top level.  Only the one at top level tells you which one is new; the other is a summary of the overall state of the PR, and appears to have both reviewers in both events.  Our current processing ends up with ugly duplicate output like this:

![image](https://user-images.githubusercontent.com/2746074/117494186-db6f7700-af28-11eb-87cd-d07493e45cf0.png)

Here is our code; I think the bug is that we should be ignoring the `pull_request` part of the event bodies.
```
def get_pull_request_review_requested_body(helper: Helper) -> str:                                   
    payload = helper.payload                                                                         
    include_title = helper.include_title                                                             
    requested_reviewer = [payload["requested_reviewer"]] if "requested_reviewer" in payload else []  
    requested_reviewers = payload["pull_request"]["requested_reviewers"] or requested_reviewer       
                                                                                                     
    requested_team = [payload["requested_team"]] if "requested_team" in payload else []              
    requested_team_reviewers = payload["pull_request"]["requested_teams"] or requested_team          
                                                                                                     
    sender = get_sender_name(payload)                                                                
    pr_number = payload["pull_request"]["number"]                                                    
    pr_url = payload["pull_request"]["html_url"]                                                     
    message = "**{sender}** requested {reviewers} for a review on [PR #{pr_number}]({pr_url})."      
    message_with_title = (                                                                           
        "**{sender}** requested {reviewers} for a review on [PR #{pr_number} {title}]({pr_url})."    
    )                                                                                                
    body = message_with_title if include_title else message                                          
```

Our last functional change to this code was 1b3cfecf2acef7fa2fc0ce5f4eedbb488361af91; 4c0890e8b0e67e9fc38ec11512d45149d89b2924 is also relevant history.  So I think my conclusion is that we can just stop looking at the `pull_request` key and that will fix this bug.


Discussion:
Hello @zulip/server-integrations members, this issue was labeled with the "area: integrations" label, so you may want to check it out!

<!-- areaLabelAddition -->
@zulipbot claim

Resolving patch:
diff --git a/zerver/webhooks/github/view.py b/zerver/webhooks/github/view.py
--- a/zerver/webhooks/github/view.py
+++ b/zerver/webhooks/github/view.py
@@ -466,10 +466,8 @@ def get_pull_request_review_requested_body(helper: Helper) -> str:
     payload = helper.payload
     include_title = helper.include_title
     requested_reviewer = [payload["requested_reviewer"]] if "requested_reviewer" in payload else []
-    requested_reviewers = payload["pull_request"]["requested_reviewers"] or requested_reviewer
 
     requested_team = [payload["requested_team"]] if "requested_team" in payload else []
-    requested_team_reviewers = payload["pull_request"]["requested_teams"] or requested_team
 
     sender = get_sender_name(payload)
     pr_number = payload["pull_request"]["number"]
@@ -482,17 +480,14 @@ def get_pull_request_review_requested_body(helper: Helper) -> str:
 
     all_reviewers = []
 
-    for reviewer in requested_reviewers:
+    for reviewer in requested_reviewer:
         all_reviewers.append("[{login}]({html_url})".format(**reviewer))
 
-    for team_reviewer in requested_team_reviewers:
+    for team_reviewer in requested_team:
         all_reviewers.append("[{name}]({html_url})".format(**team_reviewer))
 
     reviewers = ""
-    if len(all_reviewers) == 1:
-        reviewers = all_reviewers[0]
-    else:
-        reviewers = "{} and {}".format(", ".join(all_reviewers[:-1]), all_reviewers[-1])
+    reviewers = all_reviewers[0]
 
     return body.format(
         sender=sender,


Test patch:
diff --git a/zerver/webhooks/github/tests.py b/zerver/webhooks/github/tests.py
--- a/zerver/webhooks/github/tests.py
+++ b/zerver/webhooks/github/tests.py
@@ -320,24 +320,8 @@ def test_pull_request_review_requested_msg(self) -> None:
             expected_message,
         )
 
-    def test_pull_request_review_requested_singular_key_msg(self) -> None:
-        expected_message = "**eeshangarg** requested [rishig](https://github.com/rishig) for a review on [PR #6](https://github.com/eeshangarg/Scheduler/pull/6)."
-        self.check_webhook(
-            "pull_request__review_requested_singular_key",
-            "Scheduler / PR #6 Mention how awesome this project is in ...",
-            expected_message,
-        )
-
-    def test_pull_request_review_requested_multiple_reviwers_msg(self) -> None:
-        expected_message = "**eeshangarg** requested [showell](https://github.com/showell) and [timabbott](https://github.com/timabbott) for a review on [PR #1](https://github.com/eeshangarg/Scheduler/pull/1)."
-        self.check_webhook(
-            "pull_request__review_requested_multiple_reviewers",
-            "Scheduler / PR #1 This is just a test commit",
-            expected_message,
-        )
-
     def test_pull_request__review_requested_team_reviewer_msg(self) -> None:
-        expected_message = "**singhsourabh** requested [shreyaskargit](https://github.com/shreyaskargit), [bajaj99prashant](https://github.com/bajaj99prashant), [review-team](https://github.com/orgs/test-org965/teams/review-team), [authority](https://github.com/orgs/test-org965/teams/authority) and [management](https://github.com/orgs/test-org965/teams/management) for a review on [PR #4](https://github.com/test-org965/webhook-test/pull/4)."
+        expected_message = "**singhsourabh** requested [authority](https://github.com/orgs/test-org965/teams/authority) for a review on [PR #4](https://github.com/test-org965/webhook-test/pull/4)."
         self.check_webhook(
             "pull_request__review_requested_team_reviewer",
             "webhook-test / PR #4 testing webhook",