summaryrefslogtreecommitdiff
path: root/lib/gitlab/quick_actions/merge_request_actions.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/quick_actions/merge_request_actions.rb')
-rw-r--r--lib/gitlab/quick_actions/merge_request_actions.rb183
1 files changed, 154 insertions, 29 deletions
diff --git a/lib/gitlab/quick_actions/merge_request_actions.rb b/lib/gitlab/quick_actions/merge_request_actions.rb
index 1986b7a1789..b56fd8278a1 100644
--- a/lib/gitlab/quick_actions/merge_request_actions.rb
+++ b/lib/gitlab/quick_actions/merge_request_actions.rb
@@ -9,53 +9,72 @@ module Gitlab
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
+ if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
+ _("Merge automatically (%{strategy})") % { strategy: preferred_strategy.humanize }
else
- _('Merge (when the pipeline succeeds)')
+ _("Merge immediately")
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
+ 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 when the pipeline succeeds.')
+ _('Merges this merge request immediately.')
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
+ if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
+ _("Scheduled to merge this merge request (%{strategy}).") % { strategy: preferred_strategy.humanize }
else
- _('Scheduled to merge this merge request when the pipeline succeeds.')
+ _('Merged this merge request.')
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
+ quick_action_target.persisted? &&
+ merge_orchestration_service.can_merge?(quick_action_target)
end
command :merge do
@updates[:merge] = params[:merge_request_diff_head_sha]
end
+ types MergeRequest
+ desc do
+ _('Rebase source branch')
+ end
+ explanation do
+ _('Rebase source branch on the target branch.')
+ end
+ condition do
+ merge_request = quick_action_target
+
+ next false unless merge_request.open?
+ next false unless merge_request.source_branch_exists?
+
+ access_check = ::Gitlab::UserAccess
+ .new(current_user, container: merge_request.source_project)
+
+ access_check.can_push_to_branch?(merge_request.source_branch)
+ end
+ command :rebase do
+ if quick_action_target.cannot_be_merged?
+ @execution_message[:rebase] = _('This merge request cannot be rebased while there are conflicts.')
+ next
+ end
+
+ if quick_action_target.rebase_in_progress?
+ @execution_message[:rebase] = _('A rebase is already in progress.')
+ next
+ end
+
+ # This will be used to avoid simultaneous "/merge" and "/rebase" actions
+ @updates[:rebase] = true
+
+ branch = quick_action_target.source_branch
+
+ @execution_message[:rebase] = _('Scheduled a rebase of branch %{branch}.') % { branch: branch }
+ end
+
desc 'Toggle the Draft status'
explanation do
noun = quick_action_target.to_ability_name.humanize(capitalize: false)
@@ -135,6 +154,112 @@ module Gitlab
@execution_message[:approve] = _('Approved the current merge request.')
end
+
+ desc do
+ if quick_action_target.allows_multiple_reviewers?
+ _('Assign reviewer(s)')
+ else
+ _('Assign reviewer')
+ end
+ end
+ explanation do |users|
+ reviewers = reviewers_to_add(users)
+ _('Assigns %{reviewer_users_sentence} as %{reviewer_text}.') % { reviewer_users_sentence: reviewer_users_sentence(users),
+ reviewer_text: 'reviewer'.pluralize(reviewers.size) }
+ end
+ execution_message do |users = nil|
+ reviewers = reviewers_to_add(users)
+ if reviewers.blank?
+ _("Failed to assign a reviewer because no user was found.")
+ else
+ _('Assigned %{reviewer_users_sentence} as %{reviewer_text}.') % { reviewer_users_sentence: reviewer_users_sentence(users),
+ reviewer_text: 'reviewer'.pluralize(reviewers.size) }
+ end
+ end
+ params do
+ quick_action_target.allows_multiple_reviewers? ? '@user1 @user2' : '@user'
+ end
+ types MergeRequest
+ condition do
+ Feature.enabled?(:merge_request_reviewers, project, default_enabled: :yaml) &&
+ current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
+ end
+ parse_params do |reviewer_param|
+ extract_users(reviewer_param)
+ end
+ command :assign_reviewer, :reviewer do |users|
+ next if users.empty?
+
+ if quick_action_target.allows_multiple_reviewers?
+ @updates[:reviewer_ids] ||= quick_action_target.reviewers.map(&:id)
+ @updates[:reviewer_ids] |= users.map(&:id)
+ else
+ @updates[:reviewer_ids] = [users.first.id]
+ end
+ end
+
+ desc do
+ if quick_action_target.allows_multiple_reviewers?
+ _('Remove all or specific reviewer(s)')
+ else
+ _('Remove reviewer')
+ end
+ end
+ explanation do |users = nil|
+ reviewers = reviewers_for_removal(users)
+ _("Removes %{reviewer_text} %{reviewer_references}.") %
+ { reviewer_text: 'reviewer'.pluralize(reviewers.size), reviewer_references: reviewers.map(&:to_reference).to_sentence }
+ end
+ execution_message do |users = nil|
+ reviewers = reviewers_for_removal(users)
+ _("Removed %{reviewer_text} %{reviewer_references}.") %
+ { reviewer_text: 'reviewer'.pluralize(reviewers.size), reviewer_references: reviewers.map(&:to_reference).to_sentence }
+ end
+ params do
+ quick_action_target.allows_multiple_reviewers? ? '@user1 @user2' : ''
+ end
+ types MergeRequest
+ condition do
+ quick_action_target.persisted? &&
+ Feature.enabled?(:merge_request_reviewers, project, default_enabled: :yaml) &&
+ quick_action_target.reviewers.any? &&
+ current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
+ end
+ parse_params do |unassign_reviewer_param|
+ # When multiple users are assigned, all will be unassigned if multiple reviewers are no longer allowed
+ extract_users(unassign_reviewer_param) if quick_action_target.allows_multiple_reviewers?
+ end
+ command :unassign_reviewer, :remove_reviewer do |users = nil|
+ if quick_action_target.allows_multiple_reviewers? && users&.any?
+ @updates[:reviewer_ids] ||= quick_action_target.reviewers.map(&:id)
+ @updates[:reviewer_ids] -= users.map(&:id)
+ else
+ @updates[:reviewer_ids] = []
+ end
+ end
+ end
+
+ def reviewer_users_sentence(users)
+ reviewers_to_add(users).map(&:to_reference).to_sentence
+ end
+
+ def reviewers_for_removal(users)
+ reviewers = quick_action_target.reviewers
+ if users.present? && quick_action_target.allows_multiple_reviewers?
+ users
+ else
+ reviewers
+ end
+ end
+
+ def reviewers_to_add(users)
+ return if users.blank?
+
+ if quick_action_target.allows_multiple_reviewers?
+ users
+ else
+ [users.first]
+ end
end
def merge_orchestration_service