summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelogs/unreleased/expose-commits-mr-api.yml5
-rw-r--r--doc/api/commits.md68
-rw-r--r--lib/api/commits.rb14
-rw-r--r--spec/requests/api/commits_spec.rb29
4 files changed, 116 insertions, 0 deletions
diff --git a/changelogs/unreleased/expose-commits-mr-api.yml b/changelogs/unreleased/expose-commits-mr-api.yml
new file mode 100644
index 00000000000..77ea2f27431
--- /dev/null
+++ b/changelogs/unreleased/expose-commits-mr-api.yml
@@ -0,0 +1,5 @@
+---
+title: Allow merge requests related to a commit to be found via API
+merge_request:
+author:
+type: added
diff --git a/doc/api/commits.md b/doc/api/commits.md
index 55c673fd06a..a6b96ba539f 100644
--- a/doc/api/commits.md
+++ b/doc/api/commits.md
@@ -536,6 +536,74 @@ Example response:
}
```
+## List Merge Requests associated with a commit
+
+Get a list of Merge Requests related to the specified commit.
+
+```
+GET /projects/:id/repository/commits/:sha/merge_requests
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
+| `sha` | string | yes | The commit SHA
+
+
+```bash
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/5/repository/commits/af5b13261899fb2c0db30abdd0af8b07cb44fdc5/merge_requests"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id":45,
+ "iid":1,
+ "project_id":35,
+ "title":"Add new file",
+ "description":"",
+ "state":"opened",
+ "created_at":"2018-03-26T17:26:30.916Z",
+ "updated_at":"2018-03-26T17:26:30.916Z",
+ "target_branch":"master",
+ "source_branch":"test-branch",
+ "upvotes":0,
+ "downvotes":0,
+ "author" : {
+ "web_url" : "https://gitlab.example.com/thedude",
+ "name" : "Jeff Lebowski",
+ "avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png",
+ "username" : "thedude",
+ "state" : "active",
+ "id" : 28
+ },
+ "assignee":null,
+ "source_project_id":35,
+ "target_project_id":35,
+ "labels":[ ],
+ "work_in_progress":false,
+ "milestone":null,
+ "merge_when_pipeline_succeeds":false,
+ "merge_status":"can_be_merged",
+ "sha":"af5b13261899fb2c0db30abdd0af8b07cb44fdc5",
+ "merge_commit_sha":null,
+ "user_notes_count":0,
+ "discussion_locked":null,
+ "should_remove_source_branch":null,
+ "force_remove_source_branch":false,
+ "web_url":"http://https://gitlab.example.com/root/test-project/merge_requests/1",
+ "time_stats":{
+ "time_estimate":0,
+ "total_time_spent":0,
+ "human_time_estimate":null,
+ "human_total_time_spent":null
+ }
+ }
+]
+```
+
[ce-6096]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6096 "Multi-file commit"
[ce-8047]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8047
[ce-15026]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/15026
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 982f45425a3..684955a1b24 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -231,6 +231,20 @@ module API
render_api_error!("Failed to save note #{note.errors.messages}", 400)
end
end
+
+ desc 'Get Merge Requests associated with a commit' do
+ success Entities::MergeRequestBasic
+ end
+ params do
+ requires :sha, type: String, desc: 'A commit sha, or the name of a branch or tag on which to find Merge Requests'
+ use :pagination
+ end
+ get ':id/repository/commits/:sha/merge_requests', requirements: API::COMMIT_ENDPOINT_REQUIREMENTS do
+ commit = user_project.commit(params[:sha])
+ not_found! 'Commit' unless commit
+
+ present paginate(commit.merge_requests), with: Entities::MergeRequestBasic
+ end
end
end
end
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 852f67db958..8ad19e3f0f5 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -1141,4 +1141,33 @@ describe API::Commits do
end
end
end
+
+ describe 'GET /projects/:id/repository/commits/:sha/merge_requests' do
+ let!(:project) { create(:project, :repository, :private) }
+ let!(:merged_mr) { create(:merge_request, source_project: project, source_branch: 'master', target_branch: 'feature') }
+ let(:commit) { merged_mr.merge_request_diff.commits.last }
+
+ it 'returns the correct merge request' do
+ get api("/projects/#{project.id}/repository/commits/#{commit.id}/merge_requests", user)
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response.length).to eq(1)
+ expect(json_response[0]['id']).to eq(merged_mr.id)
+ end
+
+ it 'returns 403 for an unauthorized user' do
+ project.add_guest(user)
+
+ get api("/projects/#{project.id}/repository/commits/#{commit.id}/merge_requests", user)
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+
+ it 'responds 404 when the commit does not exist' do
+ get api("/projects/#{project.id}/repository/commits/a7d26f00c35b/merge_requests", user)
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
end