integrations: Handle approval/unapproval for GitLab MRs.

Fixes: #34222
This commit is contained in:
Sumit Bhanushali 2025-04-26 13:27:48 +05:30 committed by Tim Abbott
parent 0b3f0273e6
commit facbdf08fc
5 changed files with 310 additions and 1 deletions

View File

@ -206,9 +206,14 @@ def get_pull_request_event_message(
type: str = "PR",
title: str | None = None,
) -> str:
action_messages = {
"approval": "added their approval for",
"unapproval": "removed their approval for",
}
kwargs = {
"user_name": user_name,
"action": action,
"action": action_messages.get(action, action),
"type": type,
"url": url,
"id": f" #{number}" if number is not None else "",

View File

@ -0,0 +1,142 @@
{
"object_kind": "merge_request",
"event_type": "merge_request",
"user": {
"id": 587951,
"name": "Sumit Bhanushali",
"username": "sumitbhanu",
"avatar_url": "https://secure.gravatar.com/avatar/432182d26b23e4b0b2f89bf21263bf321215f562258f2f31dfcd6372789a10a2?s=80&d=identicon",
"email": "[REDACTED]"
},
"project": {
"id": 68500871,
"name": "my-awesome-project",
"description": null,
"web_url": "https://gitlab.com/sumitb16/my-awesome-project",
"avatar_url": null,
"git_ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"git_http_url": "https://gitlab.com/sumitb16/my-awesome-project.git",
"namespace": "sumitb16",
"visibility_level": 0,
"path_with_namespace": "sumitb16/my-awesome-project",
"default_branch": "main",
"ci_config_path": "",
"homepage": "https://gitlab.com/sumitb16/my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"http_url": "https://gitlab.com/sumitb16/my-awesome-project.git"
},
"object_attributes": {
"assignee_id": null,
"author_id": 26939388,
"created_at": "2025-03-30 07:38:58 UTC",
"description": "",
"draft": false,
"head_pipeline_id": null,
"id": 373098278,
"iid": 1,
"last_edited_at": null,
"last_edited_by_id": null,
"merge_commit_sha": null,
"merge_error": null,
"merge_params": {
"force_remove_source_branch": "1"
},
"merge_status": "can_be_merged",
"merge_user_id": null,
"merge_when_pipeline_succeeds": false,
"milestone_id": null,
"source_branch": "t3",
"source_project_id": 68500871,
"state_id": 1,
"target_branch": "main",
"target_project_id": 68500871,
"time_estimate": 0,
"title": "Update the README",
"updated_at": "2025-03-30 08:13:27 UTC",
"updated_by_id": 26939388,
"prepared_at": "2025-03-30 07:38:59 UTC",
"assignee_ids": [],
"blocking_discussions_resolved": true,
"detailed_merge_status": "not_approved",
"first_contribution": false,
"human_time_change": null,
"human_time_estimate": null,
"human_total_time_spent": null,
"labels": [],
"last_commit": {
"id": "f61e5631699e3b869180fea166fd0968ec2c3992",
"message": "Update file README.md",
"title": "Update file README.md",
"timestamp": "2025-03-30T07:38:04+00:00",
"url": "https://gitlab.com/sumitb16/my-awesome-project/-/commit/f61e5631699e3b869180fea166fd0968ec2c3992",
"author": {
"name": "Sumit Bhanushali",
"email": "[REDACTED]"
}
},
"reviewer_ids": [
26939388
],
"source": {
"id": 68500871,
"name": "my-awesome-project",
"description": null,
"web_url": "https://gitlab.com/sumitb16/my-awesome-project",
"avatar_url": null,
"git_ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"git_http_url": "https://gitlab.com/sumitb16/my-awesome-project.git",
"namespace": "sumitb16",
"visibility_level": 0,
"path_with_namespace": "sumitb16/my-awesome-project",
"default_branch": "main",
"ci_config_path": "",
"homepage": "https://gitlab.com/sumitb16/my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"http_url": "https://gitlab.com/sumitb16/my-awesome-project.git"
},
"state": "opened",
"target": {
"id": 68500871,
"name": "my-awesome-project",
"description": null,
"web_url": "https://gitlab.com/sumitb16/my-awesome-project",
"avatar_url": null,
"git_ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"git_http_url": "https://gitlab.com/sumitb16/my-awesome-project.git",
"namespace": "sumitb16",
"visibility_level": 0,
"path_with_namespace": "sumitb16/my-awesome-project",
"default_branch": "main",
"ci_config_path": "",
"homepage": "https://gitlab.com/sumitb16/my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"http_url": "https://gitlab.com/sumitb16/my-awesome-project.git"
},
"time_change": 0,
"total_time_spent": 0,
"url": "https://gitlab.com/sumitb16/my-awesome-project/merge_requests/1",
"work_in_progress": false,
"approval_rules": [],
"action": "approval"
},
"labels": [],
"changes": {},
"repository": {
"name": "my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"description": null,
"homepage": "https://gitlab.com/sumitb16/my-awesome-project"
},
"reviewers": [
{
"id": 26939388,
"name": "Sumit Bhanushali",
"username": "logancodes16",
"avatar_url": "https://secure.gravatar.com/avatar/83f4e0baf47f363b6064bf8376d12baabf2ab6b38c1f41a6b1fa41b6d038f254?s=80&d=identicon",
"email": "[REDACTED]"
}
]
}

View File

@ -0,0 +1,142 @@
{
"object_kind": "merge_request",
"event_type": "merge_request",
"user": {
"id": 26939734,
"name": "Sumit Bhanushali",
"username": "gunner.sumit",
"avatar_url": "https://secure.gravatar.com/avatar/62375142d03eb8b07a511a443f8d2af36497e8f36f24b71b6ffabecadda41598?s=80&d=identicon",
"email": "[REDACTED]"
},
"project": {
"id": 68500871,
"name": "my-awesome-project",
"description": null,
"web_url": "https://gitlab.com/sumitb16/my-awesome-project",
"avatar_url": null,
"git_ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"git_http_url": "https://gitlab.com/sumitb16/my-awesome-project.git",
"namespace": "sumitb16",
"visibility_level": 0,
"path_with_namespace": "sumitb16/my-awesome-project",
"default_branch": "main",
"ci_config_path": "",
"homepage": "https://gitlab.com/sumitb16/my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"http_url": "https://gitlab.com/sumitb16/my-awesome-project.git"
},
"object_attributes": {
"assignee_id": null,
"author_id": 26939388,
"created_at": "2025-03-30 07:38:58 UTC",
"description": "",
"draft": false,
"head_pipeline_id": null,
"id": 373098278,
"iid": 1,
"last_edited_at": null,
"last_edited_by_id": null,
"merge_commit_sha": null,
"merge_error": null,
"merge_params": {
"force_remove_source_branch": "1"
},
"merge_status": "can_be_merged",
"merge_user_id": null,
"merge_when_pipeline_succeeds": false,
"milestone_id": null,
"source_branch": "t3",
"source_project_id": 68500871,
"state_id": 1,
"target_branch": "main",
"target_project_id": 68500871,
"time_estimate": 0,
"title": "Update the README",
"updated_at": "2025-03-30 08:22:36 UTC",
"updated_by_id": 26939388,
"prepared_at": "2025-03-30 07:38:59 UTC",
"assignee_ids": [],
"blocking_discussions_resolved": true,
"detailed_merge_status": "not_approved",
"first_contribution": false,
"human_time_change": null,
"human_time_estimate": null,
"human_total_time_spent": null,
"labels": [],
"last_commit": {
"id": "f61e5631699e3b869180fea166fd0968ec2c3992",
"message": "Update file README.md",
"title": "Update file README.md",
"timestamp": "2025-03-30T07:38:04+00:00",
"url": "https://gitlab.com/sumitb16/my-awesome-project/-/commit/f61e5631699e3b869180fea166fd0968ec2c3992",
"author": {
"name": "Sumit Bhanushali",
"email": "[REDACTED]"
}
},
"reviewer_ids": [
26939388
],
"source": {
"id": 68500871,
"name": "my-awesome-project",
"description": null,
"web_url": "https://gitlab.com/sumitb16/my-awesome-project",
"avatar_url": null,
"git_ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"git_http_url": "https://gitlab.com/sumitb16/my-awesome-project.git",
"namespace": "sumitb16",
"visibility_level": 0,
"path_with_namespace": "sumitb16/my-awesome-project",
"default_branch": "main",
"ci_config_path": "",
"homepage": "https://gitlab.com/sumitb16/my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"http_url": "https://gitlab.com/sumitb16/my-awesome-project.git"
},
"state": "opened",
"target": {
"id": 68500871,
"name": "my-awesome-project",
"description": null,
"web_url": "https://gitlab.com/sumitb16/my-awesome-project",
"avatar_url": null,
"git_ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"git_http_url": "https://gitlab.com/sumitb16/my-awesome-project.git",
"namespace": "sumitb16",
"visibility_level": 0,
"path_with_namespace": "sumitb16/my-awesome-project",
"default_branch": "main",
"ci_config_path": "",
"homepage": "https://gitlab.com/sumitb16/my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"ssh_url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"http_url": "https://gitlab.com/sumitb16/my-awesome-project.git"
},
"time_change": 0,
"total_time_spent": 0,
"url": "https://gitlab.com/sumitb16/my-awesome-project/merge_requests/1",
"work_in_progress": false,
"approval_rules": [],
"action": "unapproval"
},
"labels": [],
"changes": {},
"repository": {
"name": "my-awesome-project",
"url": "git@gitlab.com:sumitb16/my-awesome-project.git",
"description": null,
"homepage": "https://gitlab.com/sumitb16/my-awesome-project"
},
"reviewers": [
{
"id": 26939388,
"name": "Sumit Bhanushali",
"username": "logancodes16",
"avatar_url": "https://secure.gravatar.com/avatar/83f4e0baf47f363b6064bf8376d12baabf2ab6b38c1f41a6b1fa41b6d038f254?s=80&d=identicon",
"email": "[REDACTED]"
}
]
}

View File

@ -388,6 +388,22 @@ A trivial change that should probably be ignored.
"merge_request_hook__merge_request_approved", expected_topic_name, expected_message
)
def test_merge_request_approval_event_message(self) -> None:
expected_topic_name = "my-awesome-project / MR #1 Update the README"
expected_message = "Sumit Bhanushali added their approval for [MR #1](https://gitlab.com/sumitb16/my-awesome-project/merge_requests/1)."
self.check_webhook(
"merge_request_hook__merge_request_approval", expected_topic_name, expected_message
)
def test_merge_request_unapproval_event_message(self) -> None:
expected_topic_name = "my-awesome-project / MR #1 Update the README"
expected_message = "Sumit Bhanushali removed their approval for [MR #1](https://gitlab.com/sumitb16/my-awesome-project/merge_requests/1)."
self.check_webhook(
"merge_request_hook__merge_request_unapproval", expected_topic_name, expected_message
)
def test_merge_request_updated_event_message(self) -> None:
expected_topic_name = "my-awesome-project / MR #3 New Merge Request"
expected_message = "Tomasz Kolek updated [MR #3](https://gitlab.com/tomaszkolek0/my-awesome-project/merge_requests/3) (assigned to Tomasz Kolek):\n\n~~~ quote\nupdated desc\n~~~"

View File

@ -480,6 +480,10 @@ EVENT_FUNCTION_MAPPER: dict[str, EventFunction] = {
"Note Hook Snippet": get_commented_snippet_event_body,
"Merge Request Hook approved": partial(get_merge_request_event_body, "approved"),
"Merge Request Hook unapproved": partial(get_merge_request_event_body, "unapproved"),
# approval and unapproval events are triggered only if there's more than one required approver
# ref: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/8742
"Merge Request Hook approval": partial(get_merge_request_event_body, "approval"),
"Merge Request Hook unapproval": partial(get_merge_request_event_body, "unapproval"),
"Merge Request Hook open": partial(get_merge_request_open_or_updated_body, "created"),
"Merge Request Hook update": get_merge_request_updated_event_body,
"Merge Request Hook merge": partial(get_merge_request_event_body, "merged"),