merge_requests.rb 5.22 KB
Newer Older
1
module API
Valeriy Sizov's avatar
Valeriy Sizov committed
2
  # MergeRequest API
3 4 5
  class MergeRequests < Grape::API
    before { authenticate! }

Hiroyuki Sato's avatar
Hiroyuki Sato committed
6
    resource :projects do
7
      helpers do
8 9 10
        def handle_merge_request_errors!(errors)
          if errors[:project_access].any?
            error!(errors[:project_access], 422)
11 12
          elsif errors[:branch_conflict].any?
            error!(errors[:branch_conflict], 422)
13
          end
14
          not_found!
15
        end
Izaak Alpert's avatar
Izaak Alpert committed
16 17 18 19 20 21 22 23

        def not_fork?(target_project_id, user_project)
          target_project_id.nil? || target_project_id == user_project.id.to_s
        end

        def target_matches_fork(target_project_id,user_project)
          user_project.forked? && user_project.forked_from_project.id.to_s == target_project_id
        end
24 25
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
26
      # List merge requests
27
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
28
      # Parameters:
29
      #   id (required) - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
30 31
      #
      # Example:
32
      #   GET /projects/:id/merge_requests
Valeriy Sizov's avatar
Valeriy Sizov committed
33
      #
34
      get ":id/merge_requests" do
35
        authorize! :read_merge_request, user_project
36

Valeriy Sizov's avatar
Valeriy Sizov committed
37
        present paginate(user_project.merge_requests), with: Entities::MergeRequest
38
      end
39

Valeriy Sizov's avatar
Valeriy Sizov committed
40
      # Show MR
41
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
42
      # Parameters:
43
      #   id (required)               - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
44
      #   merge_request_id (required) - The ID of MR
45
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
46
      # Example:
47
      #   GET /projects/:id/merge_request/:merge_request_id
Valeriy Sizov's avatar
Valeriy Sizov committed
48
      #
49
      get ":id/merge_request/:merge_request_id" do
50
        merge_request = user_project.merge_requests.find(params[:merge_request_id])
51

52
        authorize! :read_merge_request, merge_request
53

54
        present merge_request, with: Entities::MergeRequest
55 56
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
57 58 59 60
      # Create MR
      #
      # Parameters:
      #
61
      #   id (required)            - The ID of a project - this will be the source of the merge request
Valeriy Sizov's avatar
Valeriy Sizov committed
62 63
      #   source_branch (required) - The source branch
      #   target_branch (required) - The target branch
64
      #   target_project           - The target project of the merge request defaults to the :id of the project
Valeriy Sizov's avatar
Valeriy Sizov committed
65 66
      #   assignee_id              - Assignee user ID
      #   title (required)         - Title of MR
67
      #
Valeriy Sizov's avatar
Valeriy Sizov committed
68
      # Example:
69
      #   POST /projects/:id/merge_requests
Valeriy Sizov's avatar
Valeriy Sizov committed
70
      #
71
      post ":id/merge_requests" do
72 73 74 75 76 77 78 79 80 81
        set_current_user_for_thread do
          authorize! :write_merge_request, user_project
          required_attributes! [:source_branch, :target_branch, :title]
          attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id]
          merge_request = user_project.merge_requests.new(attrs)
          merge_request.author = current_user
          merge_request.source_project = user_project
          target_project_id = attrs[:target_project_id]
          if not_fork?(target_project_id, user_project)
            merge_request.target_project = user_project
Izaak Alpert's avatar
Izaak Alpert committed
82
          else
83
            if target_matches_fork(target_project_id,user_project)
skv's avatar
skv committed
84
              merge_request.target_project = Project.find_by(id: attrs[:target_project_id])
85 86 87
            else
              render_api_error!('(Bad Request) Specified target project that is not the source project, or the source fork of the project.', 400)
            end
Izaak Alpert's avatar
Izaak Alpert committed
88 89
          end

90 91 92 93 94
          if merge_request.save
            present merge_request, with: Entities::MergeRequest
          else
            handle_merge_request_errors! merge_request.errors
          end
Valeriy Sizov's avatar
Valeriy Sizov committed
95
        end
96 97
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
98 99 100
      # Update MR
      #
      # Parameters:
101
      #   id (required)               - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
102 103 104 105 106
      #   merge_request_id (required) - ID of MR
      #   source_branch               - The source branch
      #   target_branch               - The target branch
      #   assignee_id                 - Assignee user ID
      #   title                       - Title of MR
107
      #   state_event                 - Status of MR. (close|reopen|merge)
Valeriy Sizov's avatar
Valeriy Sizov committed
108
      # Example:
109
      #   PUT /projects/:id/merge_request/:merge_request_id
Valeriy Sizov's avatar
Valeriy Sizov committed
110
      #
111
      put ":id/merge_request/:merge_request_id" do
112 113 114
        set_current_user_for_thread do
          attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :state_event]
          merge_request = user_project.merge_requests.find(params[:merge_request_id])
115

116
          authorize! :modify_merge_request, merge_request
117

118 119 120 121 122
          if merge_request.update_attributes attrs
            present merge_request, with: Entities::MergeRequest
          else
            handle_merge_request_errors! merge_request.errors
          end
123
        end
124 125
      end

Valeriy Sizov's avatar
Valeriy Sizov committed
126 127 128
      # Post comment to merge request
      #
      # Parameters:
129
      #   id (required) - The ID of a project
Valeriy Sizov's avatar
Valeriy Sizov committed
130 131
      #   merge_request_id (required) - ID of MR
      #   note (required) - Text of comment
132
      # Examples:
133
      #   POST /projects/:id/merge_request/:merge_request_id/comments
Valeriy Sizov's avatar
Valeriy Sizov committed
134
      #
135
      post ":id/merge_request/:merge_request_id/comments" do
136 137
        set_current_user_for_thread do
          required_attributes! [:note]
138

139 140 141
          merge_request = user_project.merge_requests.find(params[:merge_request_id])
          note = merge_request.notes.new(note: params[:note], project_id: user_project.id)
          note.author = current_user
Valeriy Sizov's avatar
Valeriy Sizov committed
142

143 144 145 146 147
          if note.save
            present note, with: Entities::MRNote
          else
            not_found!
          end
148 149 150
        end
      end

151 152 153
    end
  end
end