Commit 0c621708658da4b3cf88d805da5dbad920f3d27f
Exists in
spb-stable
and in
2 other branches
Merge branch 'api-mr-merge' into 'master'
Accept merge request API This MR adds new endpoint `PUT /projects/:id/merge_request/:merge_request_id/merge`. After this change you can merge branches using API. Fixes internal issue #1166
Showing
4 changed files
with
119 additions
and
5 deletions
Show diff stats
CHANGELOG
@@ -15,6 +15,7 @@ v 6.9.0 | @@ -15,6 +15,7 @@ v 6.9.0 | ||
15 | - Fix wiki backup skip bug | 15 | - Fix wiki backup skip bug |
16 | - Two Step MR creation process | 16 | - Two Step MR creation process |
17 | - Remove unwanted files from satellite working directory with git clean -fdx | 17 | - Remove unwanted files from satellite working directory with git clean -fdx |
18 | + - Accept merge request via API (sponsored by O'Reilly Media) | ||
18 | 19 | ||
19 | v 6.8.0 | 20 | v 6.8.0 |
20 | - Ability to at mention users that are participating in issue and merge req. discussion | 21 | - Ability to at mention users that are participating in issue and merge req. discussion |
doc/api/merge_requests.md
@@ -189,6 +189,54 @@ Parameters: | @@ -189,6 +189,54 @@ Parameters: | ||
189 | ``` | 189 | ``` |
190 | 190 | ||
191 | 191 | ||
192 | +## Accept MR | ||
193 | + | ||
194 | +Merge changes submitted with MR usign this API. | ||
195 | +If merge success you get 200 OK. | ||
196 | +If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged' | ||
197 | +If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed' | ||
198 | +If you dont have permissions to accept this merge request - you get 401 | ||
199 | + | ||
200 | +``` | ||
201 | +PUT /projects/:id/merge_request/:merge_request_id/merge | ||
202 | +``` | ||
203 | + | ||
204 | +Parameters: | ||
205 | + | ||
206 | ++ `id` (required) - The ID of a project | ||
207 | ++ `merge_request_id` (required) - ID of MR | ||
208 | ++ `merge_commit_message` (optional) - Custom merge commit message | ||
209 | + | ||
210 | +```json | ||
211 | +{ | ||
212 | + "id": 1, | ||
213 | + "target_branch": "master", | ||
214 | + "source_branch": "test1", | ||
215 | + "project_id": 3, | ||
216 | + "title": "test1", | ||
217 | + "state": "merged", | ||
218 | + "upvotes": 0, | ||
219 | + "downvotes": 0, | ||
220 | + "author": { | ||
221 | + "id": 1, | ||
222 | + "username": "admin", | ||
223 | + "email": "admin@local.host", | ||
224 | + "name": "Administrator", | ||
225 | + "state": "active", | ||
226 | + "created_at": "2012-04-29T08:46:00Z" | ||
227 | + }, | ||
228 | + "assignee": { | ||
229 | + "id": 1, | ||
230 | + "username": "admin", | ||
231 | + "email": "admin@local.host", | ||
232 | + "name": "Administrator", | ||
233 | + "state": "active", | ||
234 | + "created_at": "2012-04-29T08:46:00Z" | ||
235 | + } | ||
236 | +} | ||
237 | +``` | ||
238 | + | ||
239 | + | ||
192 | ## Post comment to MR | 240 | ## Post comment to MR |
193 | 241 | ||
194 | Adds a comment to a merge request. | 242 | Adds a comment to a merge request. |
lib/api/merge_requests.rb
@@ -34,7 +34,7 @@ module API | @@ -34,7 +34,7 @@ module API | ||
34 | when "closed" then user_project.merge_requests.closed | 34 | when "closed" then user_project.merge_requests.closed |
35 | when "merged" then user_project.merge_requests.merged | 35 | when "merged" then user_project.merge_requests.merged |
36 | else user_project.merge_requests | 36 | else user_project.merge_requests |
37 | - end | 37 | + end |
38 | 38 | ||
39 | present paginate(mrs), with: Entities::MergeRequest | 39 | present paginate(mrs), with: Entities::MergeRequest |
40 | end | 40 | end |
@@ -111,6 +111,49 @@ module API | @@ -111,6 +111,49 @@ module API | ||
111 | end | 111 | end |
112 | end | 112 | end |
113 | 113 | ||
114 | + # Merge MR | ||
115 | + # | ||
116 | + # Parameters: | ||
117 | + # id (required) - The ID of a project | ||
118 | + # merge_request_id (required) - ID of MR | ||
119 | + # merge_commit_message (optional) - Custom merge commit message | ||
120 | + # Example: | ||
121 | + # PUT /projects/:id/merge_request/:merge_request_id/merge | ||
122 | + # | ||
123 | + put ":id/merge_request/:merge_request_id/merge" do | ||
124 | + merge_request = user_project.merge_requests.find(params[:merge_request_id]) | ||
125 | + | ||
126 | + action = if user_project.protected_branch?(merge_request.target_branch) | ||
127 | + :push_code_to_protected_branches | ||
128 | + else | ||
129 | + :push_code | ||
130 | + end | ||
131 | + | ||
132 | + if can?(current_user, action, user_project) | ||
133 | + if merge_request.unchecked? | ||
134 | + merge_request.check_if_can_be_merged | ||
135 | + end | ||
136 | + | ||
137 | + if merge_request.open? | ||
138 | + if merge_request.can_be_merged? | ||
139 | + merge_request.automerge!(current_user, params[:merge_commit_message] || merge_request.merge_commit_message) | ||
140 | + present merge_request, with: Entities::MergeRequest | ||
141 | + else | ||
142 | + render_api_error!('Branch cannot be merged', 405) | ||
143 | + end | ||
144 | + else | ||
145 | + # Merge request can not be merged | ||
146 | + # because it is already closed/merged | ||
147 | + not_allowed! | ||
148 | + end | ||
149 | + else | ||
150 | + # Merge request can not be merged | ||
151 | + # because user dont have permissions to push into target branch | ||
152 | + unauthorized! | ||
153 | + end | ||
154 | + end | ||
155 | + | ||
156 | + | ||
114 | # Get a merge request's comments | 157 | # Get a merge request's comments |
115 | # | 158 | # |
116 | # Parameters: | 159 | # Parameters: |
spec/requests/api/merge_requests_spec.rb
@@ -183,11 +183,33 @@ describe API::API, api: true do | @@ -183,11 +183,33 @@ describe API::API, api: true do | ||
183 | end | 183 | end |
184 | end | 184 | end |
185 | 185 | ||
186 | - describe "PUT /projects/:id/merge_request/:merge_request_id to merge MR" do | ||
187 | - it "should return merge_request" do | ||
188 | - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), state_event: "merge" | 186 | + describe "PUT /projects/:id/merge_request/:merge_request_id/merge" do |
187 | + it "should return merge_request in case of success" do | ||
188 | + MergeRequest.any_instance.stub(can_be_merged?: true, automerge!: true) | ||
189 | + put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) | ||
189 | response.status.should == 200 | 190 | response.status.should == 200 |
190 | - json_response['state'].should == 'merged' | 191 | + end |
192 | + | ||
193 | + it "should return 405 if branch can't be merged" do | ||
194 | + MergeRequest.any_instance.stub(can_be_merged?: false) | ||
195 | + put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) | ||
196 | + response.status.should == 405 | ||
197 | + json_response['message'].should == 'Branch cannot be merged' | ||
198 | + end | ||
199 | + | ||
200 | + it "should return 405 if merge_request is not open" do | ||
201 | + merge_request.close | ||
202 | + put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user) | ||
203 | + response.status.should == 405 | ||
204 | + json_response['message'].should == 'Method Not Allowed' | ||
205 | + end | ||
206 | + | ||
207 | + it "should return 401 if user has no permissions to merge" do | ||
208 | + user2 = create(:user) | ||
209 | + project.team << [user2, :reporter] | ||
210 | + put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user2) | ||
211 | + response.status.should == 401 | ||
212 | + json_response['message'].should == '401 Unauthorized' | ||
191 | end | 213 | end |
192 | end | 214 | end |
193 | 215 |