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 | 15 | - Fix wiki backup skip bug |
| 16 | 16 | - Two Step MR creation process |
| 17 | 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 | 20 | v 6.8.0 |
| 20 | 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 | 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 | 240 | ## Post comment to MR |
| 193 | 241 | |
| 194 | 242 | Adds a comment to a merge request. | ... | ... |
lib/api/merge_requests.rb
| ... | ... | @@ -34,7 +34,7 @@ module API |
| 34 | 34 | when "closed" then user_project.merge_requests.closed |
| 35 | 35 | when "merged" then user_project.merge_requests.merged |
| 36 | 36 | else user_project.merge_requests |
| 37 | - end | |
| 37 | + end | |
| 38 | 38 | |
| 39 | 39 | present paginate(mrs), with: Entities::MergeRequest |
| 40 | 40 | end |
| ... | ... | @@ -111,6 +111,49 @@ module API |
| 111 | 111 | end |
| 112 | 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 | 157 | # Get a merge request's comments |
| 115 | 158 | # |
| 116 | 159 | # Parameters: | ... | ... |
spec/requests/api/merge_requests_spec.rb
| ... | ... | @@ -183,11 +183,33 @@ describe API::API, api: true do |
| 183 | 183 | end |
| 184 | 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 | 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 | 213 | end |
| 192 | 214 | end |
| 193 | 215 | ... | ... |