summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-05-13 11:27:19 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2014-05-13 11:27:19 +0000
commit0c621708658da4b3cf88d805da5dbad920f3d27f (patch)
tree99ae5d61a368da3cc7f1470d135f5c1aa2a2751c
parent17858d49f6b189c922c7a69e94b5d8aa96fb48ad (diff)
parent2d2b2da45a586bdf29e115dcb4b4f66f9a1feed0 (diff)
downloadgitlab-ce-0c621708658da4b3cf88d805da5dbad920f3d27f.tar.gz
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
-rw-r--r--CHANGELOG1
-rw-r--r--doc/api/merge_requests.md48
-rw-r--r--lib/api/merge_requests.rb45
-rw-r--r--spec/requests/api/merge_requests_spec.rb30
4 files changed, 119 insertions, 5 deletions
diff --git a/CHANGELOG b/CHANGELOG
index e44aa452e2a..be5da8bebfa 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -15,6 +15,7 @@ v 6.9.0
- Fix wiki backup skip bug
- Two Step MR creation process
- Remove unwanted files from satellite working directory with git clean -fdx
+ - Accept merge request via API (sponsored by O'Reilly Media)
v 6.8.0
- Ability to at mention users that are participating in issue and merge req. discussion
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index d5b106729c9..d68f34971f1 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -189,6 +189,54 @@ Parameters:
```
+## Accept MR
+
+Merge changes submitted with MR usign this API.
+If merge success you get 200 OK.
+If it has some conflicts and can not be merged - you get 405 and error message 'Branch cannot be merged'
+If merge request is already merged or closed - you get 405 and error message 'Method Not Allowed'
+If you dont have permissions to accept this merge request - you get 401
+
+```
+PUT /projects/:id/merge_request/:merge_request_id/merge
+```
+
+Parameters:
+
++ `id` (required) - The ID of a project
++ `merge_request_id` (required) - ID of MR
++ `merge_commit_message` (optional) - Custom merge commit message
+
+```json
+{
+ "id": 1,
+ "target_branch": "master",
+ "source_branch": "test1",
+ "project_id": 3,
+ "title": "test1",
+ "state": "merged",
+ "upvotes": 0,
+ "downvotes": 0,
+ "author": {
+ "id": 1,
+ "username": "admin",
+ "email": "admin@local.host",
+ "name": "Administrator",
+ "state": "active",
+ "created_at": "2012-04-29T08:46:00Z"
+ },
+ "assignee": {
+ "id": 1,
+ "username": "admin",
+ "email": "admin@local.host",
+ "name": "Administrator",
+ "state": "active",
+ "created_at": "2012-04-29T08:46:00Z"
+ }
+}
+```
+
+
## Post comment to MR
Adds a comment to a merge request.
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 4b88b0f84c1..7fb135b37b8 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -34,7 +34,7 @@ module API
when "closed" then user_project.merge_requests.closed
when "merged" then user_project.merge_requests.merged
else user_project.merge_requests
- end
+ end
present paginate(mrs), with: Entities::MergeRequest
end
@@ -111,6 +111,49 @@ module API
end
end
+ # Merge MR
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # merge_request_id (required) - ID of MR
+ # merge_commit_message (optional) - Custom merge commit message
+ # Example:
+ # PUT /projects/:id/merge_request/:merge_request_id/merge
+ #
+ put ":id/merge_request/:merge_request_id/merge" do
+ merge_request = user_project.merge_requests.find(params[:merge_request_id])
+
+ action = if user_project.protected_branch?(merge_request.target_branch)
+ :push_code_to_protected_branches
+ else
+ :push_code
+ end
+
+ if can?(current_user, action, user_project)
+ if merge_request.unchecked?
+ merge_request.check_if_can_be_merged
+ end
+
+ if merge_request.open?
+ if merge_request.can_be_merged?
+ merge_request.automerge!(current_user, params[:merge_commit_message] || merge_request.merge_commit_message)
+ present merge_request, with: Entities::MergeRequest
+ else
+ render_api_error!('Branch cannot be merged', 405)
+ end
+ else
+ # Merge request can not be merged
+ # because it is already closed/merged
+ not_allowed!
+ end
+ else
+ # Merge request can not be merged
+ # because user dont have permissions to push into target branch
+ unauthorized!
+ end
+ end
+
+
# Get a merge request's comments
#
# Parameters:
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index db7c30e1ab8..2fb3684fdf0 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -183,11 +183,33 @@ describe API::API, api: true do
end
end
- describe "PUT /projects/:id/merge_request/:merge_request_id to merge MR" do
- it "should return merge_request" do
- put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), state_event: "merge"
+ describe "PUT /projects/:id/merge_request/:merge_request_id/merge" do
+ it "should return merge_request in case of success" do
+ MergeRequest.any_instance.stub(can_be_merged?: true, automerge!: true)
+ put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
response.status.should == 200
- json_response['state'].should == 'merged'
+ end
+
+ it "should return 405 if branch can't be merged" do
+ MergeRequest.any_instance.stub(can_be_merged?: false)
+ put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
+ response.status.should == 405
+ json_response['message'].should == 'Branch cannot be merged'
+ end
+
+ it "should return 405 if merge_request is not open" do
+ merge_request.close
+ put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
+ response.status.should == 405
+ json_response['message'].should == 'Method Not Allowed'
+ end
+
+ it "should return 401 if user has no permissions to merge" do
+ user2 = create(:user)
+ project.team << [user2, :reporter]
+ put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user2)
+ response.status.should == 401
+ json_response['message'].should == '401 Unauthorized'
end
end