@@ -602,6 +602,83 @@ class GroupCustomAttributeManager(RetrieveMixin, SetMixin, DeleteMixin,
602602 _from_parent_attrs = {'group_id' : 'id' }
603603
604604
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+
605682class GroupIssue (RESTObject ):
606683 pass
607684
@@ -762,6 +839,7 @@ class Group(SaveMixin, ObjectDeleteMixin, RESTObject):
762839 ('badges' , 'GroupBadgeManager' ),
763840 ('boards' , 'GroupBoardManager' ),
764841 ('customattributes' , 'GroupCustomAttributeManager' ),
842+ ('epics' , 'GroupEpicManager' ),
765843 ('issues' , 'GroupIssueManager' ),
766844 ('members' , 'GroupMemberManager' ),
767845 ('milestones' , 'GroupMilestoneManager' ),
0 commit comments