merge_requests.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. //
  2. // Copyright 2017, Sander van Harmelen
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. package gitlab
  17. import (
  18. "fmt"
  19. "net/url"
  20. "time"
  21. )
  22. // MergeRequestsService handles communication with the merge requests related
  23. // methods of the GitLab API.
  24. //
  25. // GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html
  26. type MergeRequestsService struct {
  27. client *Client
  28. timeStats *timeStatsService
  29. }
  30. // MergeRequest represents a GitLab merge request.
  31. //
  32. // GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html
  33. type MergeRequest struct {
  34. ID int `json:"id"`
  35. IID int `json:"iid"`
  36. TargetBranch string `json:"target_branch"`
  37. SourceBranch string `json:"source_branch"`
  38. ProjectID int `json:"project_id"`
  39. Title string `json:"title"`
  40. State string `json:"state"`
  41. CreatedAt *time.Time `json:"created_at"`
  42. UpdatedAt *time.Time `json:"updated_at"`
  43. Upvotes int `json:"upvotes"`
  44. Downvotes int `json:"downvotes"`
  45. Author struct {
  46. ID int `json:"id"`
  47. Username string `json:"username"`
  48. Name string `json:"name"`
  49. State string `json:"state"`
  50. CreatedAt *time.Time `json:"created_at"`
  51. } `json:"author"`
  52. Assignee struct {
  53. ID int `json:"id"`
  54. Username string `json:"username"`
  55. Name string `json:"name"`
  56. State string `json:"state"`
  57. CreatedAt *time.Time `json:"created_at"`
  58. } `json:"assignee"`
  59. SourceProjectID int `json:"source_project_id"`
  60. TargetProjectID int `json:"target_project_id"`
  61. Labels []string `json:"labels"`
  62. Description string `json:"description"`
  63. WorkInProgress bool `json:"work_in_progress"`
  64. Milestone *Milestone `json:"milestone"`
  65. MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"`
  66. MergeStatus string `json:"merge_status"`
  67. MergedBy struct {
  68. ID int `json:"id"`
  69. Username string `json:"username"`
  70. Name string `json:"name"`
  71. State string `json:"state"`
  72. CreatedAt *time.Time `json:"created_at"`
  73. } `json:"merged_by"`
  74. MergedAt *time.Time `json:"merged_at"`
  75. ClosedBy struct {
  76. ID int `json:"id"`
  77. Username string `json:"username"`
  78. Name string `json:"name"`
  79. State string `json:"state"`
  80. CreatedAt *time.Time `json:"created_at"`
  81. } `json:"closed_by"`
  82. ClosedAt *time.Time `json:"closed_at"`
  83. Subscribed bool `json:"subscribed"`
  84. SHA string `json:"sha"`
  85. MergeCommitSHA string `json:"merge_commit_sha"`
  86. UserNotesCount int `json:"user_notes_count"`
  87. ChangesCount string `json:"changes_count"`
  88. ShouldRemoveSourceBranch bool `json:"should_remove_source_branch"`
  89. ForceRemoveSourceBranch bool `json:"force_remove_source_branch"`
  90. WebURL string `json:"web_url"`
  91. DiscussionLocked bool `json:"discussion_locked"`
  92. Changes []struct {
  93. OldPath string `json:"old_path"`
  94. NewPath string `json:"new_path"`
  95. AMode string `json:"a_mode"`
  96. BMode string `json:"b_mode"`
  97. Diff string `json:"diff"`
  98. NewFile bool `json:"new_file"`
  99. RenamedFile bool `json:"renamed_file"`
  100. DeletedFile bool `json:"deleted_file"`
  101. } `json:"changes"`
  102. TimeStats *TimeStats `json:"time_stats"`
  103. Squash bool `json:"squash"`
  104. Pipeline struct {
  105. ID int `json:"id"`
  106. Ref string `json:"ref"`
  107. SHA string `json:"sha"`
  108. Status string `json:"status"`
  109. } `json:"pipeline"`
  110. }
  111. func (m MergeRequest) String() string {
  112. return Stringify(m)
  113. }
  114. // MergeRequestDiffVersion represents Gitlab merge request version.
  115. //
  116. // Gitlab API docs:
  117. // https://docs.gitlab.com/ce/api/merge_requests.html#get-a-single-mr-diff-version
  118. type MergeRequestDiffVersion struct {
  119. ID int `json:"id"`
  120. HeadCommitSHA string `json:"head_commit_sha,omitempty"`
  121. BaseCommitSHA string `json:"base_commit_sha,omitempty"`
  122. StartCommitSHA string `json:"start_commit_sha,omitempty"`
  123. CreatedAt *time.Time `json:"created_at,omitempty"`
  124. MergeRequestID int `json:"merge_request_id,omitempty"`
  125. State string `json:"state,omitempty"`
  126. RealSize string `json:"real_size,omitempty"`
  127. Commits []*Commit `json:"commits,omitempty"`
  128. Diffs []*Diff `json:"diffs,omitempty"`
  129. }
  130. func (m MergeRequestDiffVersion) String() string {
  131. return Stringify(m)
  132. }
  133. // ListMergeRequestsOptions represents the available ListMergeRequests()
  134. // options.
  135. //
  136. // GitLab API docs:
  137. // https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests
  138. type ListMergeRequestsOptions struct {
  139. ListOptions
  140. State *string `url:"state,omitempty" json:"state,omitempty"`
  141. OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
  142. Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
  143. Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
  144. View *string `url:"view,omitempty" json:"view,omitempty"`
  145. Labels Labels `url:"labels,omitempty" json:"labels,omitempty"`
  146. CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
  147. CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
  148. UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
  149. UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
  150. Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
  151. AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
  152. AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
  153. MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
  154. SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"`
  155. TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"`
  156. Search *string `url:"search,omitempty" json:"search,omitempty"`
  157. }
  158. // ListMergeRequests gets all merge requests. The state parameter can be used
  159. // to get only merge requests with a given state (opened, closed, or merged)
  160. // or all of them (all). The pagination parameters page and per_page can be
  161. // used to restrict the list of merge requests.
  162. //
  163. // GitLab API docs:
  164. // https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests
  165. func (s *MergeRequestsService) ListMergeRequests(opt *ListMergeRequestsOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
  166. req, err := s.client.NewRequest("GET", "merge_requests", opt, options)
  167. if err != nil {
  168. return nil, nil, err
  169. }
  170. var m []*MergeRequest
  171. resp, err := s.client.Do(req, &m)
  172. if err != nil {
  173. return nil, resp, err
  174. }
  175. return m, resp, err
  176. }
  177. // ListGroupMergeRequestsOptions represents the available ListGroupMergeRequests()
  178. // options.
  179. //
  180. // GitLab API docs:
  181. // https://docs.gitlab.com/ce/api/merge_requests.html#list-group-merge-requests
  182. type ListGroupMergeRequestsOptions struct {
  183. ListOptions
  184. State *string `url:"state,omitempty" json:"state,omitempty"`
  185. OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
  186. Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
  187. Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
  188. View *string `url:"view,omitempty" json:"view,omitempty"`
  189. Labels Labels `url:"labels,omitempty" json:"labels,omitempty"`
  190. CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
  191. CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
  192. UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
  193. UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
  194. Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
  195. AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
  196. AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
  197. MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
  198. SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"`
  199. TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"`
  200. Search *string `url:"search,omitempty" json:"search,omitempty"`
  201. }
  202. // ListGroupMergeRequests gets all merge requests for this group.
  203. //
  204. // GitLab API docs:
  205. // https://docs.gitlab.com/ce/api/merge_requests.html#list-group-merge-requests
  206. func (s *MergeRequestsService) ListGroupMergeRequests(gid interface{}, opt *ListGroupMergeRequestsOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
  207. group, err := parseID(gid)
  208. if err != nil {
  209. return nil, nil, err
  210. }
  211. u := fmt.Sprintf("groups/%s/merge_requests", url.QueryEscape(group))
  212. req, err := s.client.NewRequest("GET", u, opt, options)
  213. if err != nil {
  214. return nil, nil, err
  215. }
  216. var m []*MergeRequest
  217. resp, err := s.client.Do(req, &m)
  218. if err != nil {
  219. return nil, resp, err
  220. }
  221. return m, resp, err
  222. }
  223. // ListProjectMergeRequestsOptions represents the available ListMergeRequests()
  224. // options.
  225. //
  226. // GitLab API docs:
  227. // https://docs.gitlab.com/ce/api/merge_requests.html#list-project-merge-requests
  228. type ListProjectMergeRequestsOptions struct {
  229. ListOptions
  230. IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"`
  231. State *string `url:"state,omitempty" json:"state,omitempty"`
  232. OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
  233. Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
  234. Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
  235. View *string `url:"view,omitempty" json:"view,omitempty"`
  236. Labels Labels `url:"labels,omitempty" json:"labels,omitempty"`
  237. CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
  238. CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
  239. UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
  240. UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
  241. Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
  242. AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
  243. AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
  244. MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
  245. SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"`
  246. TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"`
  247. Search *string `url:"search,omitempty" json:"search,omitempty"`
  248. }
  249. // ListProjectMergeRequests gets all merge requests for this project.
  250. //
  251. // GitLab API docs:
  252. // https://docs.gitlab.com/ce/api/merge_requests.html#list-project-merge-requests
  253. func (s *MergeRequestsService) ListProjectMergeRequests(pid interface{}, opt *ListProjectMergeRequestsOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
  254. project, err := parseID(pid)
  255. if err != nil {
  256. return nil, nil, err
  257. }
  258. u := fmt.Sprintf("projects/%s/merge_requests", url.QueryEscape(project))
  259. req, err := s.client.NewRequest("GET", u, opt, options)
  260. if err != nil {
  261. return nil, nil, err
  262. }
  263. var m []*MergeRequest
  264. resp, err := s.client.Do(req, &m)
  265. if err != nil {
  266. return nil, resp, err
  267. }
  268. return m, resp, err
  269. }
  270. // GetMergeRequest shows information about a single merge request.
  271. //
  272. // GitLab API docs:
  273. // https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr
  274. func (s *MergeRequestsService) GetMergeRequest(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) {
  275. project, err := parseID(pid)
  276. if err != nil {
  277. return nil, nil, err
  278. }
  279. u := fmt.Sprintf("projects/%s/merge_requests/%d", url.QueryEscape(project), mergeRequest)
  280. req, err := s.client.NewRequest("GET", u, nil, options)
  281. if err != nil {
  282. return nil, nil, err
  283. }
  284. m := new(MergeRequest)
  285. resp, err := s.client.Do(req, m)
  286. if err != nil {
  287. return nil, resp, err
  288. }
  289. return m, resp, err
  290. }
  291. // GetMergeRequestApprovals gets information about a merge requests approvals
  292. //
  293. // GitLab API docs:
  294. // https://docs.gitlab.com/ee/api/merge_request_approvals.html#merge-request-level-mr-approvals
  295. func (s *MergeRequestsService) GetMergeRequestApprovals(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequestApprovals, *Response, error) {
  296. project, err := parseID(pid)
  297. if err != nil {
  298. return nil, nil, err
  299. }
  300. u := fmt.Sprintf("projects/%s/merge_requests/%d/approvals", url.QueryEscape(project), mergeRequest)
  301. req, err := s.client.NewRequest("GET", u, nil, options)
  302. if err != nil {
  303. return nil, nil, err
  304. }
  305. a := new(MergeRequestApprovals)
  306. resp, err := s.client.Do(req, a)
  307. if err != nil {
  308. return nil, resp, err
  309. }
  310. return a, resp, err
  311. }
  312. // GetMergeRequestCommitsOptions represents the available GetMergeRequestCommits()
  313. // options.
  314. //
  315. // GitLab API docs:
  316. // https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-commits
  317. type GetMergeRequestCommitsOptions ListOptions
  318. // GetMergeRequestCommits gets a list of merge request commits.
  319. //
  320. // GitLab API docs:
  321. // https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-commits
  322. func (s *MergeRequestsService) GetMergeRequestCommits(pid interface{}, mergeRequest int, opt *GetMergeRequestCommitsOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
  323. project, err := parseID(pid)
  324. if err != nil {
  325. return nil, nil, err
  326. }
  327. u := fmt.Sprintf("projects/%s/merge_requests/%d/commits", url.QueryEscape(project), mergeRequest)
  328. req, err := s.client.NewRequest("GET", u, opt, options)
  329. if err != nil {
  330. return nil, nil, err
  331. }
  332. var c []*Commit
  333. resp, err := s.client.Do(req, &c)
  334. if err != nil {
  335. return nil, resp, err
  336. }
  337. return c, resp, err
  338. }
  339. // GetMergeRequestChanges shows information about the merge request including
  340. // its files and changes.
  341. //
  342. // GitLab API docs:
  343. // https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-changes
  344. func (s *MergeRequestsService) GetMergeRequestChanges(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) {
  345. project, err := parseID(pid)
  346. if err != nil {
  347. return nil, nil, err
  348. }
  349. u := fmt.Sprintf("projects/%s/merge_requests/%d/changes", url.QueryEscape(project), mergeRequest)
  350. req, err := s.client.NewRequest("GET", u, nil, options)
  351. if err != nil {
  352. return nil, nil, err
  353. }
  354. m := new(MergeRequest)
  355. resp, err := s.client.Do(req, m)
  356. if err != nil {
  357. return nil, resp, err
  358. }
  359. return m, resp, err
  360. }
  361. // ListMergeRequestPipelines gets all pipelines for the provided merge request.
  362. //
  363. // GitLab API docs:
  364. // https://docs.gitlab.com/ce/api/merge_requests.html#list-mr-pipelines
  365. func (s *MergeRequestsService) ListMergeRequestPipelines(pid interface{}, mergeRequest int, options ...OptionFunc) (PipelineList, *Response, error) {
  366. project, err := parseID(pid)
  367. if err != nil {
  368. return nil, nil, err
  369. }
  370. u := fmt.Sprintf("projects/%s/merge_requests/%d/pipelines", url.QueryEscape(project), mergeRequest)
  371. req, err := s.client.NewRequest("GET", u, nil, options)
  372. if err != nil {
  373. return nil, nil, err
  374. }
  375. var p PipelineList
  376. resp, err := s.client.Do(req, &p)
  377. if err != nil {
  378. return nil, resp, err
  379. }
  380. return p, resp, err
  381. }
  382. // GetIssuesClosedOnMergeOptions represents the available GetIssuesClosedOnMerge()
  383. // options.
  384. //
  385. // GitLab API docs:
  386. // https://docs.gitlab.com/ce/api/merge_requests.html#list-issues-that-will-close-on-merge
  387. type GetIssuesClosedOnMergeOptions ListOptions
  388. // GetIssuesClosedOnMerge gets all the issues that would be closed by merging the
  389. // provided merge request.
  390. //
  391. // GitLab API docs:
  392. // https://docs.gitlab.com/ce/api/merge_requests.html#list-issues-that-will-close-on-merge
  393. func (s *MergeRequestsService) GetIssuesClosedOnMerge(pid interface{}, mergeRequest int, opt *GetIssuesClosedOnMergeOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
  394. project, err := parseID(pid)
  395. if err != nil {
  396. return nil, nil, err
  397. }
  398. u := fmt.Sprintf("/projects/%s/merge_requests/%d/closes_issues", url.QueryEscape(project), mergeRequest)
  399. req, err := s.client.NewRequest("GET", u, opt, options)
  400. if err != nil {
  401. return nil, nil, err
  402. }
  403. var i []*Issue
  404. resp, err := s.client.Do(req, &i)
  405. if err != nil {
  406. return nil, resp, err
  407. }
  408. return i, resp, err
  409. }
  410. // CreateMergeRequestOptions represents the available CreateMergeRequest()
  411. // options.
  412. //
  413. // GitLab API docs:
  414. // https://docs.gitlab.com/ce/api/merge_requests.html#create-mr
  415. type CreateMergeRequestOptions struct {
  416. Title *string `url:"title,omitempty" json:"title,omitempty"`
  417. Description *string `url:"description,omitempty" json:"description,omitempty"`
  418. SourceBranch *string `url:"source_branch,omitempty" json:"source_branch,omitempty"`
  419. TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"`
  420. Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
  421. AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
  422. TargetProjectID *int `url:"target_project_id,omitempty" json:"target_project_id,omitempty"`
  423. MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
  424. RemoveSourceBranch *bool `url:"remove_source_branch,omitempty" json:"remove_source_branch,omitempty"`
  425. Squash *bool `url:"squash,omitempty" json:"squash,omitempty"`
  426. AllowCollaboration *bool `url:"allow_collaboration,omitempty" json:"allow_collaboration,omitempty"`
  427. }
  428. // CreateMergeRequest creates a new merge request.
  429. //
  430. // GitLab API docs:
  431. // https://docs.gitlab.com/ce/api/merge_requests.html#create-mr
  432. func (s *MergeRequestsService) CreateMergeRequest(pid interface{}, opt *CreateMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
  433. project, err := parseID(pid)
  434. if err != nil {
  435. return nil, nil, err
  436. }
  437. u := fmt.Sprintf("projects/%s/merge_requests", url.QueryEscape(project))
  438. req, err := s.client.NewRequest("POST", u, opt, options)
  439. if err != nil {
  440. return nil, nil, err
  441. }
  442. m := new(MergeRequest)
  443. resp, err := s.client.Do(req, m)
  444. if err != nil {
  445. return nil, resp, err
  446. }
  447. return m, resp, err
  448. }
  449. // UpdateMergeRequestOptions represents the available UpdateMergeRequest()
  450. // options.
  451. //
  452. // GitLab API docs:
  453. // https://docs.gitlab.com/ce/api/merge_requests.html#update-mr
  454. type UpdateMergeRequestOptions struct {
  455. Title *string `url:"title,omitempty" json:"title,omitempty"`
  456. Description *string `url:"description,omitempty" json:"description,omitempty"`
  457. TargetBranch *string `url:"target_branch,omitempty" json:"target_branch,omitempty"`
  458. AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
  459. Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
  460. MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
  461. StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
  462. }
  463. // UpdateMergeRequest updates an existing project milestone.
  464. //
  465. // GitLab API docs:
  466. // https://docs.gitlab.com/ce/api/merge_requests.html#update-mr
  467. func (s *MergeRequestsService) UpdateMergeRequest(pid interface{}, mergeRequest int, opt *UpdateMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
  468. project, err := parseID(pid)
  469. if err != nil {
  470. return nil, nil, err
  471. }
  472. u := fmt.Sprintf("projects/%s/merge_requests/%d", url.QueryEscape(project), mergeRequest)
  473. req, err := s.client.NewRequest("PUT", u, opt, options)
  474. if err != nil {
  475. return nil, nil, err
  476. }
  477. m := new(MergeRequest)
  478. resp, err := s.client.Do(req, m)
  479. if err != nil {
  480. return nil, resp, err
  481. }
  482. return m, resp, err
  483. }
  484. // DeleteMergeRequest deletes a merge request.
  485. //
  486. // GitLab API docs:
  487. // https://docs.gitlab.com/ce/api/merge_requests.html#delete-a-merge-request
  488. func (s *MergeRequestsService) DeleteMergeRequest(pid interface{}, mergeRequest int, options ...OptionFunc) (*Response, error) {
  489. project, err := parseID(pid)
  490. if err != nil {
  491. return nil, err
  492. }
  493. u := fmt.Sprintf("projects/%s/merge_requests/%d", url.QueryEscape(project), mergeRequest)
  494. req, err := s.client.NewRequest("DELETE", u, nil, options)
  495. if err != nil {
  496. return nil, err
  497. }
  498. return s.client.Do(req, nil)
  499. }
  500. // AcceptMergeRequestOptions represents the available AcceptMergeRequest()
  501. // options.
  502. //
  503. // GitLab API docs:
  504. // https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr
  505. type AcceptMergeRequestOptions struct {
  506. MergeCommitMessage *string `url:"merge_commit_message,omitempty" json:"merge_commit_message,omitempty"`
  507. ShouldRemoveSourceBranch *bool `url:"should_remove_source_branch,omitempty" json:"should_remove_source_branch,omitempty"`
  508. MergeWhenPipelineSucceeds *bool `url:"merge_when_pipeline_succeeds,omitempty" json:"merge_when_pipeline_succeeds,omitempty"`
  509. Sha *string `url:"sha,omitempty" json:"sha,omitempty"`
  510. }
  511. // AcceptMergeRequest merges changes submitted with MR using this API. If merge
  512. // success you get 200 OK. If it has some conflicts and can not be merged - you
  513. // get 405 and error message 'Branch cannot be merged'. If merge request is
  514. // already merged or closed - you get 405 and error message 'Method Not Allowed'
  515. //
  516. // GitLab API docs:
  517. // https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr
  518. func (s *MergeRequestsService) AcceptMergeRequest(pid interface{}, mergeRequest int, opt *AcceptMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
  519. project, err := parseID(pid)
  520. if err != nil {
  521. return nil, nil, err
  522. }
  523. u := fmt.Sprintf("projects/%s/merge_requests/%d/merge", url.QueryEscape(project), mergeRequest)
  524. req, err := s.client.NewRequest("PUT", u, opt, options)
  525. if err != nil {
  526. return nil, nil, err
  527. }
  528. m := new(MergeRequest)
  529. resp, err := s.client.Do(req, m)
  530. if err != nil {
  531. return nil, resp, err
  532. }
  533. return m, resp, err
  534. }
  535. // CancelMergeWhenPipelineSucceeds cancels a merge when pipeline succeeds. If
  536. // you don't have permissions to accept this merge request - you'll get a 401.
  537. // If the merge request is already merged or closed - you get 405 and error
  538. // message 'Method Not Allowed'. In case the merge request is not set to be
  539. // merged when the pipeline succeeds, you'll also get a 406 error.
  540. //
  541. // GitLab API docs:
  542. // https://docs.gitlab.com/ce/api/merge_requests.html#cancel-merge-when-pipeline-succeeds
  543. func (s *MergeRequestsService) CancelMergeWhenPipelineSucceeds(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) {
  544. project, err := parseID(pid)
  545. if err != nil {
  546. return nil, nil, err
  547. }
  548. u := fmt.Sprintf("projects/%s/merge_requests/%d/cancel_merge_when_pipeline_succeeds", url.QueryEscape(project), mergeRequest)
  549. req, err := s.client.NewRequest("PUT", u, nil, options)
  550. if err != nil {
  551. return nil, nil, err
  552. }
  553. m := new(MergeRequest)
  554. resp, err := s.client.Do(req, m)
  555. if err != nil {
  556. return nil, resp, err
  557. }
  558. return m, resp, err
  559. }
  560. // GetMergeRequestDiffVersionsOptions represents the available
  561. // GetMergeRequestDiffVersions() options.
  562. //
  563. // GitLab API docs:
  564. // https://docs.gitlab.com/ce/api/merge_requests.html#get-mr-diff-versions
  565. type GetMergeRequestDiffVersionsOptions ListOptions
  566. // GetMergeRequestDiffVersions get a list of merge request diff versions.
  567. //
  568. // GitLab API docs:
  569. // https://docs.gitlab.com/ce/api/merge_requests.html#get-mr-diff-versions
  570. func (s *MergeRequestsService) GetMergeRequestDiffVersions(pid interface{}, mergeRequest int, opt *GetMergeRequestDiffVersionsOptions, options ...OptionFunc) ([]*MergeRequestDiffVersion, *Response, error) {
  571. project, err := parseID(pid)
  572. if err != nil {
  573. return nil, nil, err
  574. }
  575. u := fmt.Sprintf("projects/%s/merge_requests/%d/versions", url.QueryEscape(project), mergeRequest)
  576. req, err := s.client.NewRequest("GET", u, opt, options)
  577. if err != nil {
  578. return nil, nil, err
  579. }
  580. var v []*MergeRequestDiffVersion
  581. resp, err := s.client.Do(req, &v)
  582. if err != nil {
  583. return nil, resp, err
  584. }
  585. return v, resp, err
  586. }
  587. // GetSingleMergeRequestDiffVersion get a single MR diff version
  588. //
  589. // GitLab API docs:
  590. // https://docs.gitlab.com/ce/api/merge_requests.html#get-a-single-mr-diff-version
  591. func (s *MergeRequestsService) GetSingleMergeRequestDiffVersion(pid interface{}, mergeRequest, version int, options ...OptionFunc) (*MergeRequestDiffVersion, *Response, error) {
  592. project, err := parseID(pid)
  593. if err != nil {
  594. return nil, nil, err
  595. }
  596. u := fmt.Sprintf("projects/%s/merge_requests/%d/versions/%d", url.QueryEscape(project), mergeRequest, version)
  597. req, err := s.client.NewRequest("GET", u, nil, options)
  598. if err != nil {
  599. return nil, nil, err
  600. }
  601. var v = new(MergeRequestDiffVersion)
  602. resp, err := s.client.Do(req, v)
  603. if err != nil {
  604. return nil, resp, err
  605. }
  606. return v, resp, err
  607. }
  608. // SubscribeToMergeRequest subscribes the authenticated user to the given merge
  609. // request to receive notifications. If the user is already subscribed to the
  610. // merge request, the status code 304 is returned.
  611. //
  612. // GitLab API docs:
  613. // https://docs.gitlab.com/ce/api/merge_requests.html#subscribe-to-a-merge-request
  614. func (s *MergeRequestsService) SubscribeToMergeRequest(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) {
  615. project, err := parseID(pid)
  616. if err != nil {
  617. return nil, nil, err
  618. }
  619. u := fmt.Sprintf("projects/%s/merge_requests/%d/subscribe", url.QueryEscape(project), mergeRequest)
  620. req, err := s.client.NewRequest("POST", u, nil, options)
  621. if err != nil {
  622. return nil, nil, err
  623. }
  624. m := new(MergeRequest)
  625. resp, err := s.client.Do(req, m)
  626. if err != nil {
  627. return nil, resp, err
  628. }
  629. return m, resp, err
  630. }
  631. // UnsubscribeFromMergeRequest unsubscribes the authenticated user from the
  632. // given merge request to not receive notifications from that merge request.
  633. // If the user is not subscribed to the merge request, status code 304 is
  634. // returned.
  635. //
  636. // GitLab API docs:
  637. // https://docs.gitlab.com/ce/api/merge_requests.html#unsubscribe-from-a-merge-request
  638. func (s *MergeRequestsService) UnsubscribeFromMergeRequest(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) {
  639. project, err := parseID(pid)
  640. if err != nil {
  641. return nil, nil, err
  642. }
  643. u := fmt.Sprintf("projects/%s/merge_requests/%d/unsubscribe", url.QueryEscape(project), mergeRequest)
  644. req, err := s.client.NewRequest("POST", u, nil, options)
  645. if err != nil {
  646. return nil, nil, err
  647. }
  648. m := new(MergeRequest)
  649. resp, err := s.client.Do(req, m)
  650. if err != nil {
  651. return nil, resp, err
  652. }
  653. return m, resp, err
  654. }
  655. // CreateTodo manually creates a todo for the current user on a merge request.
  656. // If there already exists a todo for the user on that merge request,
  657. // status code 304 is returned.
  658. //
  659. // GitLab API docs:
  660. // https://docs.gitlab.com/ce/api/merge_requests.html#create-a-todo
  661. func (s *MergeRequestsService) CreateTodo(pid interface{}, mergeRequest int, options ...OptionFunc) (*Todo, *Response, error) {
  662. project, err := parseID(pid)
  663. if err != nil {
  664. return nil, nil, err
  665. }
  666. u := fmt.Sprintf("projects/%s/merge_requests/%d/todo", url.QueryEscape(project), mergeRequest)
  667. req, err := s.client.NewRequest("POST", u, nil, options)
  668. if err != nil {
  669. return nil, nil, err
  670. }
  671. t := new(Todo)
  672. resp, err := s.client.Do(req, t)
  673. if err != nil {
  674. return nil, resp, err
  675. }
  676. return t, resp, err
  677. }
  678. // SetTimeEstimate sets the time estimate for a single project merge request.
  679. //
  680. // GitLab API docs:
  681. // https://docs.gitlab.com/ce/api/merge_requests.html#set-a-time-estimate-for-a-merge-request
  682. func (s *MergeRequestsService) SetTimeEstimate(pid interface{}, mergeRequest int, opt *SetTimeEstimateOptions, options ...OptionFunc) (*TimeStats, *Response, error) {
  683. return s.timeStats.setTimeEstimate(pid, "merge_requests", mergeRequest, opt, options...)
  684. }
  685. // ResetTimeEstimate resets the time estimate for a single project merge request.
  686. //
  687. // GitLab API docs:
  688. // https://docs.gitlab.com/ce/api/merge_requests.html#reset-the-time-estimate-for-a-merge-request
  689. func (s *MergeRequestsService) ResetTimeEstimate(pid interface{}, mergeRequest int, options ...OptionFunc) (*TimeStats, *Response, error) {
  690. return s.timeStats.resetTimeEstimate(pid, "merge_requests", mergeRequest, options...)
  691. }
  692. // AddSpentTime adds spent time for a single project merge request.
  693. //
  694. // GitLab API docs:
  695. // https://docs.gitlab.com/ce/api/merge_requests.html#add-spent-time-for-a-merge-request
  696. func (s *MergeRequestsService) AddSpentTime(pid interface{}, mergeRequest int, opt *AddSpentTimeOptions, options ...OptionFunc) (*TimeStats, *Response, error) {
  697. return s.timeStats.addSpentTime(pid, "merge_requests", mergeRequest, opt, options...)
  698. }
  699. // ResetSpentTime resets the spent time for a single project merge request.
  700. //
  701. // GitLab API docs:
  702. // https://docs.gitlab.com/ce/api/merge_requests.html#reset-spent-time-for-a-merge-request
  703. func (s *MergeRequestsService) ResetSpentTime(pid interface{}, mergeRequest int, options ...OptionFunc) (*TimeStats, *Response, error) {
  704. return s.timeStats.resetSpentTime(pid, "merge_requests", mergeRequest, options...)
  705. }
  706. // GetTimeSpent gets the spent time for a single project merge request.
  707. //
  708. // GitLab API docs:
  709. // https://docs.gitlab.com/ce/api/merge_requests.html#get-time-tracking-stats
  710. func (s *MergeRequestsService) GetTimeSpent(pid interface{}, mergeRequest int, options ...OptionFunc) (*TimeStats, *Response, error) {
  711. return s.timeStats.getTimeSpent(pid, "merge_requests", mergeRequest, options...)
  712. }