1package gitlab
2
3import (
4 "fmt"
5 "time"
6)
7
8// MergeRequestApprovalsService handles communication with the merge request
9// approvals related methods of the GitLab API. This includes reading/updating
10// approval settings and approve/unapproving merge requests
11//
12// GitLab API docs: https://docs.gitlab.com/ee/api/merge_request_approvals.html
13type MergeRequestApprovalsService struct {
14 client *Client
15}
16
17// MergeRequestApprovals represents GitLab merge request approvals.
18//
19// GitLab API docs:
20// https://docs.gitlab.com/ee/api/merge_request_approvals.html#merge-request-level-mr-approvals
21type MergeRequestApprovals struct {
22 ID int `json:"id"`
23 ProjectID int `json:"project_id"`
24 Title string `json:"title"`
25 Description string `json:"description"`
26 State string `json:"state"`
27 CreatedAt *time.Time `json:"created_at"`
28 UpdatedAt *time.Time `json:"updated_at"`
29 MergeStatus string `json:"merge_status"`
30 ApprovalsBeforeMerge int `json:"approvals_before_merge"`
31 ApprovalsRequired int `json:"approvals_required"`
32 ApprovalsLeft int `json:"approvals_left"`
33 ApprovedBy []*MergeRequestApproverUser `json:"approved_by"`
34 Approvers []*MergeRequestApproverUser `json:"approvers"`
35 ApproverGroups []*MergeRequestApproverGroup `json:"approver_groups"`
36}
37
38// MergeRequestApproverGroup represents GitLab project level merge request approver group.
39//
40// GitLab API docs:
41// https://docs.gitlab.com/ee/api/merge_request_approvals.html#project-level-mr-approvals
42type MergeRequestApproverGroup struct {
43 Group struct {
44 ID int `json:"id"`
45 Name string `json:"name"`
46 Path string `json:"path"`
47 Description string `json:"description"`
48 Visibility string `json:"visibility"`
49 AvatarURL string `json:"avatar_url"`
50 WebURL string `json:"web_url"`
51 FullName string `json:"full_name"`
52 FullPath string `json:"full_path"`
53 LFSEnabled bool `json:"lfs_enabled"`
54 RequestAccessEnabled bool `json:"request_access_enabled"`
55 }
56}
57
58// MergeRequestApproverUser represents GitLab project level merge request approver user.
59//
60// GitLab API docs:
61// https://docs.gitlab.com/ee/api/merge_request_approvals.html#project-level-mr-approvals
62type MergeRequestApproverUser struct {
63 User struct {
64 ID int `json:"id"`
65 Name string `json:"name"`
66 Username string `json:"username"`
67 State string `json:"state"`
68 AvatarURL string `json:"avatar_url"`
69 WebURL string `json:"web_url"`
70 }
71}
72
73func (m MergeRequestApprovals) String() string {
74 return Stringify(m)
75}
76
77// ApproveMergeRequestOptions represents the available ApproveMergeRequest() options.
78//
79// GitLab API docs:
80// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request
81type ApproveMergeRequestOptions struct {
82 SHA *string `url:"sha,omitempty" json:"sha,omitempty"`
83}
84
85// ApproveMergeRequest approves a merge request on GitLab. If a non-empty sha
86// is provided then it must match the sha at the HEAD of the MR.
87//
88// GitLab API docs:
89// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request
90func (s *MergeRequestApprovalsService) ApproveMergeRequest(pid interface{}, mr int, opt *ApproveMergeRequestOptions, options ...OptionFunc) (*MergeRequestApprovals, *Response, error) {
91 project, err := parseID(pid)
92 if err != nil {
93 return nil, nil, err
94 }
95 u := fmt.Sprintf("projects/%s/merge_requests/%d/approve", pathEscape(project), mr)
96
97 req, err := s.client.NewRequest("POST", u, opt, options)
98 if err != nil {
99 return nil, nil, err
100 }
101
102 m := new(MergeRequestApprovals)
103 resp, err := s.client.Do(req, m)
104 if err != nil {
105 return nil, resp, err
106 }
107
108 return m, resp, err
109}
110
111// UnapproveMergeRequest unapproves a previously approved merge request on GitLab.
112//
113// GitLab API docs:
114// https://docs.gitlab.com/ee/api/merge_request_approvals.html#unapprove-merge-request
115func (s *MergeRequestApprovalsService) UnapproveMergeRequest(pid interface{}, mr int, options ...OptionFunc) (*Response, error) {
116 project, err := parseID(pid)
117 if err != nil {
118 return nil, err
119 }
120 u := fmt.Sprintf("projects/%s/merge_requests/%d/unapprove", pathEscape(project), mr)
121
122 req, err := s.client.NewRequest("POST", u, nil, options)
123 if err != nil {
124 return nil, err
125 }
126
127 return s.client.Do(req, nil)
128}