Repository: zulip/zulip

Issue:
GitHub integration can send ref deletion events with no `sender.login`
We assume there's a `sender` key with a `login`, in that some authenticated user was responsible for the ref deletion:
https://github.com/zulip/zulip/blob/e0cb3c6908c33957b8f42a5313b801419b016446/zerver/webhooks/github/view.py#L626-L627

But some events -- possibly only those from [Merge Queues](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue) -- don't have such a key:
```json
{
  "after": "0000000000000000000000000000000000000000",
  "base_ref": null,
  "before": "3a9808b22742d5bd906ef5d1a562f2f1ae57406d",
  "created": false,
  "deleted": true,
  "forced": false,
  "organization": {
    "events_url": "https://api.github.com/orgs/nvim-treesitter/events",
    "hooks_url": "https://api.github.com/orgs/nvim-treesitter/hooks",
    "id": 63916357,
    "issues_url": "https://api.github.com/orgs/nvim-treesitter/issues",
    "login": "nvim-treesitter",
    "members_url": "https://api.github.com/orgs/nvim-treesitter/members{/member}",
    "node_id": "MDEyOk9yZ2FuaXphdGlvbjYzOTE2MzU3",
    "public_members_url": "https://api.github.com/orgs/nvim-treesitter/public_members{/member}",
    "repos_url": "https://api.github.com/orgs/nvim-treesitter/repos",
    "url": "https://api.github.com/orgs/nvim-treesitter"
  },
  "pusher": {
    "name": "none"
  },
  "ref": "refs/heads/gh-readonly-queue/master/pr-24-e97504446f14f529d5a8e649667d3d60391e4dfd",
  "repository": {
    "description": "A Tree-sitter parser for tree-sitter queries.",
    "fork": false,
    "full_name": "nvim-treesitter/tree-sitter-query",
    "html_url": "https://github.com/nvim-treesitter/tree-sitter-query",
    "id": 283011708,
    "name": "tree-sitter-query",
    "node_id": "MDEwOlJlcG9zaXRvcnkyODMwMTE3MDg=",
    "owner": {},
    "private": false,
    "url": "https://github.com/nvim-treesitter/tree-sitter-query"
  }
}
```

[Stack trace here](https://zulip.sentry.io/share/issue/9c1cd1aac5924010ba13bcc1480d6daf/).

We should adjust the integration to ignore these instead of 500'ing, or output something more specific to merge queues.


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

<!-- areaLabelAddition -->

Thanks for assigning the issue to me. 

Giving this a first look makes me feel that we can for sure send a specific message for the case when the sender's info is not present in the webhook. I am not sure if ignoring the event would be a good idea.

Also, will need to verify if this is only happening for Merge Queues or if are there any other event types that can have such kind of behavior.

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
@@ -639,6 +639,10 @@ def is_commit_push_event(payload: WildValue) -> bool:
     return bool(re.match(r"^refs/heads/", payload["ref"].tame(check_string)))
 
 
+def is_merge_queue_push_event(payload: WildValue) -> bool:
+    return bool(re.match(r"^refs/heads/gh-readonly-queue/", payload["ref"].tame(check_string)))
+
+
 def get_subject_based_on_type(payload: WildValue, event: str) -> str:
     if "pull_request" in event:
         return TOPIC_WITH_PR_OR_ISSUE_INFO_TEMPLATE.format(
@@ -733,6 +737,7 @@ def get_subject_based_on_type(payload: WildValue, event: str) -> str:
     "milestone",
     "organization",
     "project_card",
+    "push__merge_queue",
     "repository_vulnerability_alert",
 ]
 
@@ -827,6 +832,8 @@ def get_zulip_event_name(
         if action in IGNORED_PULL_REQUEST_ACTIONS:
             return None
     elif header_event == "push":
+        if is_merge_queue_push_event(payload):
+            return None
         if is_commit_push_event(payload):
             if branches is not None:
                 branch = get_branch_name_from_ref(payload["ref"].tame(check_string))


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
@@ -51,6 +51,11 @@ def test_push_local_branch_without_commits(self) -> None:
             "push__local_branch_without_commits", "public-repo / feature", expected_message
         )
 
+    def test_push_merege_queue_ignore(self) -> None:
+        self.url = self.build_webhook_url()
+        payload = self.get_body("push__merge_queue")
+        self.verify_post_is_ignored(payload, "push")
+
     def test_push_1_commit(self) -> None:
         expected_message = "baxterthehacker [pushed](https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f) 1 commit to branch changes.\n\n* Update README.md ([0d1a26e67d8](https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c))"
         self.check_webhook("push__1_commit", TOPIC_BRANCH, expected_message)