diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | doc/api/merge_requests.md | 11 | ||||
-rw-r--r-- | lib/api/merge_requests.rb | 5 | ||||
-rw-r--r-- | spec/requests/api/merge_requests_spec.rb | 13 |
4 files changed, 26 insertions, 4 deletions
diff --git a/CHANGELOG b/CHANGELOG index 848aaa8506e..eb037e1ab8b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,7 @@ v 8.9.0 (unreleased) - Fix groups API to list only user's accessible projects - Redesign account and email confirmation emails - Use gitlab-shell v3.0.0 + - Add `sha` parameter to MR merge API, to ensure only reviewed changes are merged - Add DB index on users.state - Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database - Changed the Slack build message to use the singular duration if necessary (Aran Koning) diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 8217e30fe25..16b892dc3b7 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -413,11 +413,13 @@ curl -X DELETE -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.c Merge changes submitted with MR using this API. -If merge success you get `200 OK`. +If the merge succeeds you'll get a `200 OK`. -If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged' +If it has some conflicts and can not be merged - you'll get a 405 and the error message 'Branch cannot be merged' -If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed' +If merge request is already merged or closed - you'll get a 406 and the error message 'Method Not Allowed' + +If the `sha` parameter is passed and does not match the HEAD of the source - you'll get a 409 and the error message 'SHA does not match HEAD of source branch' If you don't have permissions to accept this merge request - you'll get a 401 @@ -431,7 +433,8 @@ Parameters: - `merge_request_id` (required) - ID of MR - `merge_commit_message` (optional) - Custom merge commit message - `should_remove_source_branch` (optional) - if `true` removes the source branch -- `merged_when_build_succeeds` (optional) - if `true` the MR is merge when the build succeeds +- `merged_when_build_succeeds` (optional) - if `true` the MR is merged when the build succeeds +- `sha` (optional) - if present, then this SHA must match the HEAD of the source branch, otherwise the merge will fail ```json { diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 4e7de8867b4..50baf4c09ad 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -218,6 +218,7 @@ module API # merge_commit_message (optional) - Custom merge commit message # should_remove_source_branch (optional) - When true, the source branch will be deleted if possible # merge_when_build_succeeds (optional) - When true, this MR will be merged when the build succeeds + # sha (optional) - When present, must have the HEAD SHA of the source branch # Example: # PUT /projects/:id/merge_requests/:merge_request_id/merge # @@ -233,6 +234,10 @@ module API render_api_error!('Branch cannot be merged', 406) unless merge_request.can_be_merged? + if params[:sha] && merge_request.source_sha != params[:sha] + render_api_error!("SHA does not match HEAD of source branch: #{merge_request.target_sha}", 409) + end + merge_params = { commit_message: params[:merge_commit_message], should_remove_source_branch: params[:should_remove_source_branch] diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 4b0111df149..5aa98ec4014 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -428,6 +428,19 @@ describe API::API, api: true do expect(json_response['message']).to eq('401 Unauthorized') end + it "returns 409 if the SHA parameter doesn't match" do + put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), sha: merge_request.source_sha.succ + + expect(response.status).to eq(409) + expect(json_response['message']).to start_with('SHA does not match HEAD of source branch') + end + + it "succeeds if the SHA parameter matches" do + put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), sha: merge_request.source_sha + + expect(response.status).to eq(200) + end + it "enables merge when build succeeds if the ci is active" do allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit) allow(ci_commit).to receive(:active?).and_return(true) |