Skip to content

Commit

Permalink
feat: adds support for project merge request approval rules (#1199)
Browse files Browse the repository at this point in the history
  • Loading branch information
robinson96 committed Sep 30, 2020
1 parent 266030a commit c6fbf39
Showing 1 changed file with 89 additions and 8 deletions.
97 changes: 89 additions & 8 deletions gitlab/v4/objects/__init__.py
Expand Up @@ -2996,13 +2996,18 @@ class ProjectMergeRequestApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTMan

@exc.on_http_error(exc.GitlabUpdateError)
def set_approvers(
self, approvals_required, approver_ids=None, approver_group_ids=None, **kwargs
self,
approvals_required,
approver_ids=None,
approver_group_ids=None,
approval_rule_name="name",
**kwargs
):
"""Change MR-level allowed approvers and approver groups.
Args:
approvals_required (integer): The number of required approvals for this rule
approver_ids (list): User IDs that can approve MRs
approver_ids (list of integers): User IDs that can approve MRs
approver_group_ids (list): Group IDs whose members can approve MRs
Raises:
Expand All @@ -3012,18 +3017,93 @@ def set_approvers(
approver_ids = approver_ids or []
approver_group_ids = approver_group_ids or []

path = "%s/%s/approval_rules" % (
self._parent.manager.path,
self._parent.get_id(),
)
data = {
"name": "name",
"name": approval_rule_name,
"approvals_required": approvals_required,
"rule_type": "regular",
"user_ids": approver_ids,
"group_ids": approver_group_ids,
}
self.gitlab.http_post(path, post_data=data, **kwargs)
approval_rules = self._parent.approval_rules
""" update any existing approval rule matching the name"""
existing_approval_rules = approval_rules.list()
for ar in existing_approval_rules:
if ar.name == approval_rule_name:
ar.user_ids = data["user_ids"]
ar.approvals_required = data["approvals_required"]
ar.group_ids = data["group_ids"]
ar.save()
return
""" if there was no rule matching the rule name, create a new one"""
approval_rules.create(data=data)


class ProjectMergeRequestApprovalRule(SaveMixin, RESTObject):
_id_attr = "approval_rule_id"
_short_print_attr = "approval_rule"

@exc.on_http_error(exc.GitlabUpdateError)
def save(self, **kwargs):
"""Save the changes made to the object to the server.
The object is updated to match what the server returns.
Args:
**kwargs: Extra options to send to the server (e.g. sudo)
Raise:
GitlabAuthenticationError: If authentication is not correct
GitlabUpdateError: If the server cannot perform the request
"""
# There is a mismatch between the name of our id attribute and the put REST API name for the
# project_id, so we override it here.
self.approval_rule_id = self.id
self.merge_request_iid = self._parent_attrs["mr_iid"]
self.id = self._parent_attrs["project_id"]
# save will update self.id with the result from the server, so no need to overwrite with
# what it was before we overwrote it."""
SaveMixin.save(self, **kwargs)


class ProjectMergeRequestApprovalRuleManager(
ListMixin, UpdateMixin, CreateMixin, RESTManager
):
_path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/approval_rules"
_obj_cls = ProjectMergeRequestApprovalRule
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
_list_filters = ("name", "rule_type")
_update_attrs = (
("id", "merge_request_iid", "approval_rule_id", "name", "approvals_required"),
("user_ids", "group_ids"),
)
# Important: When approval_project_rule_id is set, the name, users and groups of
# project-level rule will be copied. The approvals_required specified will be used. """
_create_attrs = (
("id", "merge_request_iid", "name", "approvals_required"),
("approval_project_rule_id", "user_ids", "group_ids"),
)

def create(self, data, **kwargs):
"""Create a new object.
Args:
data (dict): Parameters to send to the server to create the
resource
**kwargs: Extra options to send to the server (e.g. sudo or
'ref_name', 'stage', 'name', 'all')
Raises:
GitlabAuthenticationError: If authentication is not correct
GitlabCreateError: If the server cannot perform the request
Returns:
RESTObject: A new instance of the manage object class build with
the data sent by the server
"""
new_data = data.copy()
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 ProjectMergeRequestAwardEmoji(ObjectDeleteMixin, RESTObject):
Expand Down Expand Up @@ -3149,6 +3229,7 @@ class ProjectMergeRequest(

_managers = (
("approvals", "ProjectMergeRequestApprovalManager"),
("approval_rules", "ProjectMergeRequestApprovalRuleManager"),
("awardemojis", "ProjectMergeRequestAwardEmojiManager"),
("diffs", "ProjectMergeRequestDiffManager"),
("discussions", "ProjectMergeRequestDiscussionManager"),
Expand Down

0 comments on commit c6fbf39

Please sign in to comment.