diff --git a/CHANGELOG b/CHANGELOG index b27291b6f1922f2854d875ed315fc19a3b2d959c..4698bb7bd8b6658c114947d9f9f79568d250f6b9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -8,7 +8,7 @@ v 7.8.0 - Better UI for project services page - Cleaner UI for web editor - Add diff syntax highlighting in email-on-push service notifications (Hannes Rosenögger) - - + - Add API endpoint to fetch all changes on a MergeRequest (Jeroen van Baarsen) - - - Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger) diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 053fc9346be9cee226cb3deda98899cda37a13d5..acae55d07eff1ecafe30b0416c6331a62db56fe9 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -94,6 +94,76 @@ Parameters: } ``` +## Get single MR changes + +Shows information about the merge request including its files and changes + +``` +GET /projects/:id/merge_request/:merge_request_id/changes +``` + +Parameters: + +- `id` (required) - The ID of a project +- `merge_request_id` (required) - The ID of MR + +```json +{ + "id": 21, + "iid": 1, + "project_id": 4, + "title": "Blanditiis beatae suscipit hic assumenda et molestias nisi asperiores repellat et.", + "description": "Qui voluptatibus placeat ipsa alias quasi. Deleniti rem ut sint. Optio velit qui distinctio.", + "state": "reopened", + "created_at": "2015-02-02T19:49:39.159Z", + "updated_at": "2015-02-02T20:08:49.959Z", + "target_branch": "secret_token", + "source_branch": "version-1-9", + "upvotes": 0, + "downvotes": 0, + "author": { + "name": "Chad Hamill", + "username": "jarrett", + "id": 5, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/b95567800f828948baf5f4160ebb2473?s=40&d=identicon" + }, + "assignee": { + "name": "Administrator", + "username": "root", + "id": 1, + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon" + }, + "source_project_id": 4, + "target_project_id": 4, + "labels": [ ], + "milestone": { + "id": 5, + "iid": 1, + "project_id": 4, + "title": "v2.0", + "description": "Assumenda aut placeat expedita exercitationem labore sunt enim earum.", + "state": "closed", + "created_at": "2015-02-02T19:49:26.013Z", + "updated_at": "2015-02-02T19:49:26.013Z", + "due_date": null + }, + "files": [ + { + "old_path": "VERSION", + "new_path": "VERSION", + "a_mode": "100644", + "b_mode": "100644", + "diff": "--- a/VERSION\ +++ b/VERSION\ @@ -1 +1 @@\ -1.9.7\ +1.9.8", + "new_file": false, + "renamed_file": false, + "deleted_file": false + } + ] +} +``` + ## Create MR Creates a new merge request. diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 58339908fd2bdc08feaaca671315c5c19018bb1d..fa76a54c2d89e463c1f87ba2565b39e1272dbee7 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -147,6 +147,11 @@ module API expose :state, :created_at, :updated_at end + class RepoDiff < Grape::Entity + expose :old_path, :new_path, :a_mode, :b_mode, :diff + expose :new_file, :renamed_file, :deleted_file + end + class Milestone < ProjectEntity expose :due_date end @@ -166,6 +171,12 @@ module API expose :milestone, using: Entities::Milestone end + class MergeRequestChanges < MergeRequest + expose :diffs, as: :changes, using: Entities::RepoDiff do |compare, _| + compare.diffs + end + end + class SSHKey < Grape::Entity expose :id, :title, :key, :created_at end @@ -236,11 +247,6 @@ module API expose :name, :color end - class RepoDiff < Grape::Entity - expose :old_path, :new_path, :a_mode, :b_mode, :diff - expose :new_file, :renamed_file, :deleted_file - end - class Compare < Grape::Entity expose :commit, using: Entities::RepoCommit do |compare, options| Commit.decorate(compare.commits).last diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 2a5b10c6f5248f969f585ebaffde03dd46955b5c..a0ebd8d0c1bf27b1e74756b8f5e99e7089798ce4 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -75,6 +75,22 @@ module API present merge_request, with: Entities::MergeRequest end + # Show MR changes + # + # Parameters: + # id (required) - The ID of a project + # merge_request_id (required) - The ID of MR + # + # Example: + # GET /projects/:id/merge_request/:merge_request_id/changes + # + get ':id/merge_request/:merge_request_id/changes' do + merge_request = user_project.merge_requests. + find(params[:merge_request_id]) + authorize! :read_merge_request, merge_request + present merge_request, with: Entities::MergeRequestChanges + end + # Create MR # # Parameters: diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 5ba3a33099154e4d6c917489103b9f96d9c91e54..5795082f5cbc4a780598db9896a7839d3bd24552 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -114,6 +114,19 @@ describe API::API, api: true do end end + describe 'GET /projects/:id/merge_request/:merge_request_id/changes' do + it 'should return the change information of the merge_request' do + get api("/projects/#{project.id}/merge_request/#{merge_request.id}/changes", user) + expect(response.status).to eq 200 + expect(json_response['changes'].size).to eq(merge_request.diffs.size) + end + + it 'returns a 404 when merge_request_id not found' do + get api("/projects/#{project.id}/merge_request/999/changes", user) + expect(response.status).to eq(404) + end + end + describe "POST /projects/:id/merge_requests" do context 'between branches projects' do it "should return merge_request" do