summaryrefslogtreecommitdiff
path: root/lib/gitlab/quick_actions/merge_request_actions.rb
blob: c8c949a93631909ae1c4bb2597c91b8805e52071 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# frozen_string_literal: true

module Gitlab
  module QuickActions
    module MergeRequestActions
      extend ActiveSupport::Concern
      include Gitlab::QuickActions::Dsl

      included do
        # MergeRequest only quick actions definitions
        desc do
          if Feature.enabled?(:merge_orchestration_service, quick_action_target.project, default_enabled: true)
            if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
              _("Merge automatically (%{strategy})") % { strategy: preferred_strategy.humanize }
            else
              _("Merge immediately")
            end
          else
            _('Merge (when the pipeline succeeds)')
          end
        end
        explanation do
          if Feature.enabled?(:merge_orchestration_service, quick_action_target.project, default_enabled: true)
            if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
              _("Schedules to merge this merge request (%{strategy}).") % { strategy: preferred_strategy.humanize }
            else
              _('Merges this merge request immediately.')
            end
          else
            _('Merges this merge request when the pipeline succeeds.')
          end
        end
        execution_message do
          if Feature.enabled?(:merge_orchestration_service, quick_action_target.project, default_enabled: true)
            if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
              _("Scheduled to merge this merge request (%{strategy}).") % { strategy: preferred_strategy.humanize }
            else
              _('Merged this merge request.')
            end
          else
            _('Scheduled to merge this merge request when the pipeline succeeds.')
          end
        end
        types MergeRequest
        condition do
          if Feature.enabled?(:merge_orchestration_service, quick_action_target.project, default_enabled: true)
            quick_action_target.persisted? &&
              merge_orchestration_service.can_merge?(quick_action_target)
          else
            last_diff_sha = params && params[:merge_request_diff_head_sha]
            quick_action_target.persisted? &&
              quick_action_target.mergeable_with_quick_action?(current_user, autocomplete_precheck: !last_diff_sha, last_diff_sha: last_diff_sha)
          end
        end
        command :merge do
          @updates[:merge] = params[:merge_request_diff_head_sha]
        end

        desc 'Toggle the Work In Progress status'
        explanation do
          noun = quick_action_target.to_ability_name.humanize(capitalize: false)
          if quick_action_target.work_in_progress?
            _("Unmarks this %{noun} as Work In Progress.")
          else
            _("Marks this %{noun} as Work In Progress.")
          end % { noun: noun }
        end
        execution_message do
          noun = quick_action_target.to_ability_name.humanize(capitalize: false)
          if quick_action_target.work_in_progress?
            _("Unmarked this %{noun} as Work In Progress.")
          else
            _("Marked this %{noun} as Work In Progress.")
          end % { noun: noun }
        end

        types MergeRequest
        condition do
          quick_action_target.respond_to?(:work_in_progress?) &&
            # Allow it to mark as WIP on MR creation page _or_ through MR notes.
            (quick_action_target.new_record? || current_user.can?(:"update_#{quick_action_target.to_ability_name}", quick_action_target))
        end
        command :wip do
          @updates[:wip_event] = quick_action_target.work_in_progress? ? 'unwip' : 'wip'
        end

        desc _('Set target branch')
        explanation do |branch_name|
          _('Sets target branch to %{branch_name}.') % { branch_name: branch_name }
        end
        execution_message do |branch_name|
          _('Set target branch to %{branch_name}.') % { branch_name: branch_name }
        end
        params '<Local branch name>'
        types MergeRequest
        condition do
          quick_action_target.respond_to?(:target_branch) &&
            (current_user.can?(:"update_#{quick_action_target.to_ability_name}", quick_action_target) ||
              quick_action_target.new_record?)
        end
        parse_params do |target_branch_param|
          target_branch_param.strip
        end
        command :target_branch do |branch_name|
          @updates[:target_branch] = branch_name if project.repository.branch_exists?(branch_name)
        end

        desc _('Submit a review')
        explanation _('Submit the current review.')
        types MergeRequest
        condition do
          quick_action_target.persisted?
        end
        command :submit_review do
          next if params[:review_id]

          result = DraftNotes::PublishService.new(quick_action_target, current_user).execute
          @execution_message[:submit_review] = if result[:status] == :success
                                                 _('Submitted the current review.')
                                               else
                                                 result[:message]
                                               end
        end

        desc _('Approve a merge request')
        explanation _('Approve the current merge request.')
        types MergeRequest
        condition do
          quick_action_target.persisted? && quick_action_target.can_be_approved_by?(current_user)
        end
        command :approve do
          success = MergeRequests::ApprovalService.new(quick_action_target.project, current_user).execute(quick_action_target)

          next unless success

          @execution_message[:approve] = _('Approved the current merge request.')
        end
      end

      def merge_orchestration_service
        @merge_orchestration_service ||= MergeRequests::MergeOrchestrationService.new(project, current_user)
      end

      def preferred_auto_merge_strategy(merge_request)
        merge_orchestration_service.preferred_auto_merge_strategy(merge_request)
      end
    end
  end
end