| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,6 +18,7 @@ API examples | |||
| 18 | 18 | gl_objects/discussions | |
| 19 | 19 | gl_objects/environments | |
| 20 | 20 | gl_objects/events | |
| 21 | + gl_objects/epics | ||
| 21 | 22 | gl_objects/features | |
| 22 | 23 | gl_objects/geo_nodes | |
| 23 | 24 | gl_objects/groups | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,79 @@ | |||
| 1 | + ##### | ||
| 2 | + Epics | ||
| 3 | + ##### | ||
| 4 | + | ||
| 5 | + Epics | ||
| 6 | + ===== | ||
| 7 | + | ||
| 8 | + Reference | ||
| 9 | + --------- | ||
| 10 | + | ||
| 11 | + * v4 API: | ||
| 12 | + | ||
| 13 | + + :class:`gitlab.v4.objects.GroupEpic` | ||
| 14 | + + :class:`gitlab.v4.objects.GroupEpicManager` | ||
| 15 | + + :attr:`gitlab.Gitlab.Group.epics` | ||
| 16 | + | ||
| 17 | + * GitLab API: https://docs.gitlab.com/ee/api/epics.html (EE feature) | ||
| 18 | + | ||
| 19 | + Examples | ||
| 20 | + -------- | ||
| 21 | + | ||
| 22 | + List the epics for a group:: | ||
| 23 | + | ||
| 24 | + epics = groups.epics.list() | ||
| 25 | + | ||
| 26 | + Get a single epic for a group:: | ||
| 27 | + | ||
| 28 | + epic = group.epics.get(epic_iid) | ||
| 29 | + | ||
| 30 | + Create an epic for a group:: | ||
| 31 | + | ||
| 32 | + epic = group.epics.create({'title': 'My Epic'}) | ||
| 33 | + | ||
| 34 | + Edit an epic:: | ||
| 35 | + | ||
| 36 | + epic.title = 'New title' | ||
| 37 | + epic.labels = ['label1', 'label2'] | ||
| 38 | + epic.save() | ||
| 39 | + | ||
| 40 | + Delete an epic:: | ||
| 41 | + | ||
| 42 | + epic.delete() | ||
| 43 | + | ||
| 44 | + Epics issues | ||
| 45 | + ============ | ||
| 46 | + | ||
| 47 | + Reference | ||
| 48 | + --------- | ||
| 49 | + | ||
| 50 | + * v4 API: | ||
| 51 | + | ||
| 52 | + + :class:`gitlab.v4.objects.GroupEpicIssue` | ||
| 53 | + + :class:`gitlab.v4.objects.GroupEpicIssueManager` | ||
| 54 | + + :attr:`gitlab.Gitlab.GroupEpic.issues` | ||
| 55 | + | ||
| 56 | + * GitLab API: https://docs.gitlab.com/ee/api/epic_issues.html (EE feature) | ||
| 57 | + | ||
| 58 | + Examples | ||
| 59 | + -------- | ||
| 60 | + | ||
| 61 | + List the issues associated with an issue:: | ||
| 62 | + | ||
| 63 | + ei = epic.issues.list() | ||
| 64 | + | ||
| 65 | + Associate an issue with an epic:: | ||
| 66 | + | ||
| 67 | + # use the issue id, not its iid | ||
| 68 | + ei = epic.issues.create({'issue_id': 4}) | ||
| 69 | + | ||
| 70 | + Move an issue in the list:: | ||
| 71 | + | ||
| 72 | + ei.move_before_id = epic_issue_id_1 | ||
| 73 | + # or | ||
| 74 | + ei.move_after_id = epic_issue_id_2 | ||
| 75 | + ei.save() | ||
| 76 | + | ||
| 77 | + Delete an issue association:: | ||
| 78 | + | ||
| 79 | + ei.delete() | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -602,6 +602,83 @@ class GroupCustomAttributeManager(RetrieveMixin, SetMixin, DeleteMixin, | |||
| 602 | 602 | _from_parent_attrs = {'group_id': 'id'} | |
| 603 | 603 | ||
| 604 | 604 | ||
| 605 | + class GroupEpicIssue(ObjectDeleteMixin, SaveMixin, RESTObject): | ||
| 606 | + _id_attr = 'epic_issue_id' | ||
| 607 | + | ||
| 608 | + def save(self, **kwargs): | ||
| 609 | + """Save the changes made to the object to the server. | ||
| 610 | + | ||
| 611 | + The object is updated to match what the server returns. | ||
| 612 | + | ||
| 613 | + Args: | ||
| 614 | + **kwargs: Extra options to send to the server (e.g. sudo) | ||
| 615 | + | ||
| 616 | + Raise: | ||
| 617 | + GitlabAuthenticationError: If authentication is not correct | ||
| 618 | + GitlabUpdateError: If the server cannot perform the request | ||
| 619 | + """ | ||
| 620 | + updated_data = self._get_updated_data() | ||
| 621 | + # Nothing to update. Server fails if sent an empty dict. | ||
| 622 | + if not updated_data: | ||
| 623 | + return | ||
| 624 | + | ||
| 625 | + # call the manager | ||
| 626 | + obj_id = self.get_id() | ||
| 627 | + self.manager.update(obj_id, updated_data, **kwargs) | ||
| 628 | + | ||
| 629 | + | ||
| 630 | + class GroupEpicIssueManager(ListMixin, CreateMixin, UpdateMixin, DeleteMixin, | ||
| 631 | + RESTManager): | ||
| 632 | + _path = '/groups/%(group_id)s/epics/%(epic_iid)s/issues' | ||
| 633 | + _obj_cls = GroupEpicIssue | ||
| 634 | + _from_parent_attrs = {'group_id': 'group_id', 'epic_iid': 'iid'} | ||
| 635 | + _create_attrs = (('issue_id',), tuple()) | ||
| 636 | + _update_attrs = (tuple(), ('move_before_id', 'move_after_id')) | ||
| 637 | + | ||
| 638 | + @exc.on_http_error(exc.GitlabCreateError) | ||
| 639 | + def create(self, data, **kwargs): | ||
| 640 | + """Create a new object. | ||
| 641 | + | ||
| 642 | + Args: | ||
| 643 | + data (dict): Parameters to send to the server to create the | ||
| 644 | + resource | ||
| 645 | + **kwargs: Extra data to send to the Gitlab server (e.g. sudo) | ||
| 646 | + | ||
| 647 | + Raises: | ||
| 648 | + GitlabAuthenticationError: If authentication is not correct | ||
| 649 | + GitlabCreateError: If the server cannot perform the request | ||
| 650 | + | ||
| 651 | + Returns: | ||
| 652 | + RESTObject: A new instance of the manage object class build with | ||
| 653 | + the data sent by the server | ||
| 654 | + """ | ||
| 655 | + CreateMixin._check_missing_create_attrs(self, data) | ||
| 656 | + path = '%s/%s' % (self.path, data.pop('issue_id')) | ||
| 657 | + server_data = self.gitlab.http_post(path, **kwargs) | ||
| 658 | + # The epic_issue_id attribute doesn't exist when creating the resource, | ||
| 659 | + # but is used everywhere elese. Let's create it to be consistent client | ||
| 660 | + # side | ||
| 661 | + server_data['epic_issue_id'] = server_data['id'] | ||
| 662 | + return self._obj_cls(self, server_data) | ||
| 663 | + | ||
| 664 | + | ||
| 665 | + class GroupEpic(ObjectDeleteMixin, SaveMixin, RESTObject): | ||
| 666 | + _id_attr = 'iid' | ||
| 667 | + _managers = (('issues', 'GroupEpicIssueManager'),) | ||
| 668 | + | ||
| 669 | + | ||
| 670 | + class GroupEpicManager(CRUDMixin, RESTManager): | ||
| 671 | + _path = '/groups/%(group_id)s/epics' | ||
| 672 | + _obj_cls = GroupEpic | ||
| 673 | + _from_parent_attrs = {'group_id': 'id'} | ||
| 674 | + _list_filters = ('author_id', 'labels', 'order_by', 'sort', 'search') | ||
| 675 | + _create_attrs = (('title',), | ||
| 676 | + ('labels', 'description', 'start_date', 'end_date')) | ||
| 677 | + _update_attrs = (tuple(), ('title', 'labels', 'description', 'start_date', | ||
| 678 | + 'end_date')) | ||
| 679 | + _types = {'labels': types.ListAttribute} | ||
| 680 | + | ||
| 681 | + | ||
| 605 | 682 | class GroupIssue(RESTObject): | |
| 606 | 683 | pass | |
| 607 | 684 | ||
@@ -762,6 +839,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject): | |||
| 762 | 839 | ('badges', 'GroupBadgeManager'), | |
| 763 | 840 | ('boards', 'GroupBoardManager'), | |
| 764 | 841 | ('customattributes', 'GroupCustomAttributeManager'), | |
| 842 | + ('epics', 'GroupEpicManager'), | ||
| 765 | 843 | ('issues', 'GroupIssueManager'), | |
| 766 | 844 | ('members', 'GroupMemberManager'), | |
| 767 | 845 | ('milestones', 'GroupMilestoneManager'), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,6 +8,7 @@ | |||
| 8 | 8 | MR_P1 = 1 | |
| 9 | 9 | I_P1 = 1 | |
| 10 | 10 | I_P2 = 1 | |
| 11 | + EPIC_ISSUES = [4, 5] | ||
| 11 | 12 | G1 = 'group1' | |
| 12 | 13 | LDAP_CN = 'app1' | |
| 13 | 14 | LDAP_PROVIDER = 'ldapmain' | |
@@ -83,7 +84,7 @@ def end_log(): | |||
| 83 | 84 | group1.delete_ldap_group_link(LDAP_CN) | |
| 84 | 85 | end_log() | |
| 85 | 86 | ||
| 86 | - start_log('Boards') | ||
| 87 | + start_log('boards') | ||
| 87 | 88 | # bit of cleanup just in case | |
| 88 | 89 | for board in project1.boards.list(): | |
| 89 | 90 | if board.name == 'testboard': | |
@@ -121,3 +122,23 @@ def end_log(): | |||
| 121 | 122 | except Exception as e: | |
| 122 | 123 | assert('The license key is invalid.' in e.error_message) | |
| 123 | 124 | end_log() | |
| 125 | + | ||
| 126 | + start_log('epics') | ||
| 127 | + epic = group1.epics.create({'title': 'Test epic'}) | ||
| 128 | + epic.title = 'Fixed title' | ||
| 129 | + epic.labels = ['label1', 'label2'] | ||
| 130 | + epic.save() | ||
| 131 | + epic = group1.epics.get(epic.iid) | ||
| 132 | + assert(epic.title == 'Fixed title') | ||
| 133 | + assert(len(group1.epics.list())) | ||
| 134 | + | ||
| 135 | + # issues | ||
| 136 | + assert(not epic.issues.list()) | ||
| 137 | + for i in EPIC_ISSUES: | ||
| 138 | + epic.issues.create({'issue_id': i}) | ||
| 139 | + assert(len(EPIC_ISSUES) == len(epic.issues.list())) | ||
| 140 | + for ei in epic.issues.list(): | ||
| 141 | + ei.delete() | ||
| 142 | + | ||
| 143 | + epic.delete() | ||
| 144 | + end_log() | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments