Skip to content

feat(api): add merge request approval state #1641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/gl_objects/mr_approvals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ References
+ :class:`gitlab.v4.objects.ProjectMergeRequestApprovalRule`
+ :class:`gitlab.v4.objects.ProjectMergeRequestApprovalRuleManager`
+ :attr:`gitlab.v4.objects.ProjectMergeRequest.approval_rules`
+ :class:`gitlab.v4.objects.ProjectMergeRequestApprovalState`
+ :class:`gitlab.v4.objects.ProjectMergeRequestApprovalStateManager`
+ :attr:`gitlab.v4.objects.ProjectMergeRequest.approval_state`

* GitLab API: https://docs.gitlab.com/ee/api/merge_request_approvals.html

Expand All @@ -46,6 +49,10 @@ Get project-level or MR-level MR approvals settings::

mr_mras = mr.approvals.get()

Get MR-level approval state::

mr_approval_state = mr.approval_state.get()

Change project-level or MR-level MR approvals settings::

p_mras.approvals_before_merge = 2
Expand Down
12 changes: 12 additions & 0 deletions gitlab/v4/objects/merge_request_approvals.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"ProjectMergeRequestApprovalManager",
"ProjectMergeRequestApprovalRule",
"ProjectMergeRequestApprovalRuleManager",
"ProjectMergeRequestApprovalState",
"ProjectMergeRequestApprovalStateManager",
]


Expand Down Expand Up @@ -204,3 +206,13 @@ def create(self, data, **kwargs):
new_data["id"] = self._from_parent_attrs["project_id"]
new_data["merge_request_iid"] = self._from_parent_attrs["mr_iid"]
return CreateMixin.create(self, new_data, **kwargs)


class ProjectMergeRequestApprovalState(RESTObject):
pass


class ProjectMergeRequestApprovalStateManager(GetWithoutIdMixin, RESTManager):
_path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/approval_state"
_obj_cls = ProjectMergeRequestApprovalState
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
2 changes: 2 additions & 0 deletions gitlab/v4/objects/merge_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .merge_request_approvals import ( # noqa: F401
ProjectMergeRequestApprovalManager,
ProjectMergeRequestApprovalRuleManager,
ProjectMergeRequestApprovalStateManager,
)
from .notes import ProjectMergeRequestNoteManager # noqa: F401
from .pipelines import ProjectMergeRequestPipelineManager # noqa: F401
Expand Down Expand Up @@ -140,6 +141,7 @@ class ProjectMergeRequest(
_id_attr = "iid"

approval_rules: ProjectMergeRequestApprovalRuleManager
approval_state: ProjectMergeRequestApprovalStateManager
approvals: ProjectMergeRequestApprovalManager
awardemojis: ProjectMergeRequestAwardEmojiManager
diffs: "ProjectMergeRequestDiffManager"
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/objects/test_project_merge_request_approvals.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,15 @@ def resp_snippet():
}
]

approval_state_rules = copy.deepcopy(mr_ars_content)
approval_state_rules[0]["approved"] = False
approval_state_rules[0]["approved_by"] = []

mr_approval_state_content = {
"approval_rules_overwritten": False,
"rules": approval_state_rules,
}

with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
rsps.add(
method=responses.GET,
Expand All @@ -200,6 +209,13 @@ def resp_snippet():
content_type="application/json",
status=200,
)
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/merge_requests/1/approval_state",
json=mr_approval_state_content,
content_type="application/json",
status=200,
)

new_mr_ars_content = dict(mr_ars_content[0])
new_mr_ars_content["name"] = new_approval_rule_name
Expand Down Expand Up @@ -315,3 +331,18 @@ def test_update_merge_request_approval_rule(project, resp_snippet):
assert ar_1.approvals_required == updated_approval_rule_approvals_required
assert len(ar_1.eligible_approvers) == len(updated_approval_rule_user_ids)
assert ar_1.eligible_approvers[0]["id"] == updated_approval_rule_user_ids[0]


def test_get_merge_request_approval_state(project, resp_snippet):
merge_request = project.mergerequests.get(1)
approval_state = merge_request.approval_state.get()
assert isinstance(
approval_state,
gitlab.v4.objects.merge_request_approvals.ProjectMergeRequestApprovalState,
)
assert not approval_state.approval_rules_overwritten
assert len(approval_state.rules) == 1
assert approval_state.rules[0]["name"] == approval_rule_name
assert approval_state.rules[0]["id"] == approval_rule_id
assert not approval_state.rules[0]["approved"]
assert approval_state.rules[0]["approved_by"] == []