summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter B. Robinson <robinson96@llnl.gov>2020-09-30 08:45:40 -0700
committerPeter B. Robinson <robinson96@llnl.gov>2020-09-30 08:45:40 -0700
commitc6fbf399ec5cbc92f995a5d61342f295be68bd79 (patch)
tree49c9cd55c1a33f7534306523514083c9cb3ae09c
parent266030a67480aaf305069e8fea15b1528fa99d31 (diff)
downloadgitlab-c6fbf399ec5cbc92f995a5d61342f295be68bd79.tar.gz
feat: adds support for project merge request approval rules (#1199)
-rw-r--r--gitlab/v4/objects/__init__.py97
1 files changed, 89 insertions, 8 deletions
diff --git a/gitlab/v4/objects/__init__.py b/gitlab/v4/objects/__init__.py
index 016caec..c90d18a 100644
--- a/gitlab/v4/objects/__init__.py
+++ b/gitlab/v4/objects/__init__.py
@@ -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:
@@ -3012,18 +3017,93 @@ class ProjectMergeRequestApprovalManager(GetWithoutIdMixin, UpdateMixin, RESTMan
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):
@@ -3149,6 +3229,7 @@ class ProjectMergeRequest(
_managers = (
("approvals", "ProjectMergeRequestApprovalManager"),
+ ("approval_rules", "ProjectMergeRequestApprovalRuleManager"),
("awardemojis", "ProjectMergeRequestAwardEmojiManager"),
("diffs", "ProjectMergeRequestDiffManager"),
("discussions", "ProjectMergeRequestDiscussionManager"),