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 SuggestedApprovers []*BasicUser `json:"suggested_approvers"`
37}
38
39func (m MergeRequestApprovals) String() string {
40 return Stringify(m)
41}
42
43// MergeRequestApproverGroup represents GitLab project level merge request approver group.
44//
45// GitLab API docs:
46// https://docs.gitlab.com/ee/api/merge_request_approvals.html#project-level-mr-approvals
47type MergeRequestApproverGroup struct {
48 Group struct {
49 ID int `json:"id"`
50 Name string `json:"name"`
51 Path string `json:"path"`
52 Description string `json:"description"`
53 Visibility string `json:"visibility"`
54 AvatarURL string `json:"avatar_url"`
55 WebURL string `json:"web_url"`
56 FullName string `json:"full_name"`
57 FullPath string `json:"full_path"`
58 LFSEnabled bool `json:"lfs_enabled"`
59 RequestAccessEnabled bool `json:"request_access_enabled"`
60 }
61}
62
63// MergeRequestApproverUser represents GitLab project level merge request approver user.
64//
65// GitLab API docs:
66// https://docs.gitlab.com/ee/api/merge_request_approvals.html#project-level-mr-approvals
67type MergeRequestApproverUser struct {
68 User *BasicUser
69}
70
71// ApproveMergeRequestOptions represents the available ApproveMergeRequest() options.
72//
73// GitLab API docs:
74// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request
75type ApproveMergeRequestOptions struct {
76 SHA *string `url:"sha,omitempty" json:"sha,omitempty"`
77}
78
79// ApproveMergeRequest approves a merge request on GitLab. If a non-empty sha
80// is provided then it must match the sha at the HEAD of the MR.
81//
82// GitLab API docs:
83// https://docs.gitlab.com/ee/api/merge_request_approvals.html#approve-merge-request
84func (s *MergeRequestApprovalsService) ApproveMergeRequest(pid interface{}, mr int, opt *ApproveMergeRequestOptions, options ...OptionFunc) (*MergeRequestApprovals, *Response, error) {
85 project, err := parseID(pid)
86 if err != nil {
87 return nil, nil, err
88 }
89 u := fmt.Sprintf("projects/%s/merge_requests/%d/approve", pathEscape(project), mr)
90
91 req, err := s.client.NewRequest("POST", u, opt, options)
92 if err != nil {
93 return nil, nil, err
94 }
95
96 m := new(MergeRequestApprovals)
97 resp, err := s.client.Do(req, m)
98 if err != nil {
99 return nil, resp, err
100 }
101
102 return m, resp, err
103}
104
105// UnapproveMergeRequest unapproves a previously approved merge request on GitLab.
106//
107// GitLab API docs:
108// https://docs.gitlab.com/ee/api/merge_request_approvals.html#unapprove-merge-request
109func (s *MergeRequestApprovalsService) UnapproveMergeRequest(pid interface{}, mr int, options ...OptionFunc) (*Response, error) {
110 project, err := parseID(pid)
111 if err != nil {
112 return nil, err
113 }
114 u := fmt.Sprintf("projects/%s/merge_requests/%d/unapprove", pathEscape(project), mr)
115
116 req, err := s.client.NewRequest("POST", u, nil, options)
117 if err != nil {
118 return nil, err
119 }
120
121 return s.client.Do(req, nil)
122}
123
124// ChangeMergeRequestApprovalConfigurationOptions represents the available
125// ChangeMergeRequestApprovalConfiguration() options.
126//
127// GitLab API docs:
128// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-approval-configuration
129type ChangeMergeRequestApprovalConfigurationOptions struct {
130 ApprovalsRequired *int `url:"approvals_required,omitempty" json:"approvals_required,omitempty"`
131}
132
133// ChangeApprovalConfiguration updates the approval configuration of a merge request.
134//
135// GitLab API docs:
136// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-approval-configuration
137func (s *MergeRequestApprovalsService) ChangeApprovalConfiguration(pid interface{}, mergeRequestIID int, opt *ChangeMergeRequestApprovalConfigurationOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
138 project, err := parseID(pid)
139 if err != nil {
140 return nil, nil, err
141 }
142 u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", pathEscape(project), mergeRequestIID)
143
144 req, err := s.client.NewRequest("POST", u, opt, options)
145 if err != nil {
146 return nil, nil, err
147 }
148
149 m := new(MergeRequest)
150 resp, err := s.client.Do(req, m)
151 if err != nil {
152 return nil, resp, err
153 }
154
155 return m, resp, err
156}
157
158// ChangeMergeRequestAllowedApproversOptions represents the available
159// ChangeMergeRequestAllowedApprovers() options.
160//
161// GitLab API docs:
162// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-allowed-approvers-for-merge-request
163type ChangeMergeRequestAllowedApproversOptions struct {
164 ApproverIDs []int `url:"approver_ids" json:"approver_ids"`
165 ApproverGroupIDs []int `url:"approver_group_ids" json:"approver_group_ids"`
166}
167
168// ChangeAllowedApprovers updates the approvers for a merge request.
169//
170// GitLab API docs:
171// https://docs.gitlab.com/ee/api/merge_request_approvals.html#change-allowed-approvers-for-merge-request
172func (s *MergeRequestApprovalsService) ChangeAllowedApprovers(pid interface{}, mergeRequestIID int, opt *ChangeMergeRequestAllowedApproversOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
173 project, err := parseID(pid)
174 if err != nil {
175 return nil, nil, err
176 }
177 u := fmt.Sprintf("projects/%s/merge_requests/%d/approvers", pathEscape(project), mergeRequestIID)
178
179 req, err := s.client.NewRequest("PUT", u, opt, options)
180 if err != nil {
181 return nil, nil, err
182 }
183
184 m := new(MergeRequest)
185 resp, err := s.client.Do(req, m)
186 if err != nil {
187 return nil, resp, err
188 }
189
190 return m, resp, err
191}