debian-mirror-gitlab/lib/gitlab/quick_actions/merge_request_actions.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

400 lines
15 KiB
Ruby
Raw Normal View History

2019-07-07 11:18:12 +05:30
# frozen_string_literal: true
module Gitlab
module QuickActions
module MergeRequestActions
extend ActiveSupport::Concern
include Gitlab::QuickActions::Dsl
included do
# MergeRequest only quick actions definitions
2020-04-22 19:07:51 +05:30
desc do
2021-03-08 18:12:59 +05:30
if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
_("Merge automatically (%{strategy})") % { strategy: preferred_strategy.humanize }
2020-04-22 19:07:51 +05:30
else
2021-03-08 18:12:59 +05:30
_("Merge immediately")
2020-04-22 19:07:51 +05:30
end
end
explanation do
2021-03-08 18:12:59 +05:30
if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
_("Schedules to merge this merge request (%{strategy}).") % { strategy: preferred_strategy.humanize }
2020-04-22 19:07:51 +05:30
else
2021-03-08 18:12:59 +05:30
_('Merges this merge request immediately.')
2020-04-22 19:07:51 +05:30
end
end
execution_message do
2022-05-07 20:08:51 +05:30
if params[:merge_request_diff_head_sha].blank?
2022-06-21 17:19:12 +05:30
_("The `/merge` quick action requires the SHA of the head of the branch.")
2022-05-07 20:08:51 +05:30
elsif params[:merge_request_diff_head_sha] != quick_action_target.diff_head_sha
_("Branch has been updated since the merge was requested.")
elsif preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
2021-03-08 18:12:59 +05:30
_("Scheduled to merge this merge request (%{strategy}).") % { strategy: preferred_strategy.humanize }
2020-04-22 19:07:51 +05:30
else
2021-03-08 18:12:59 +05:30
_('Merged this merge request.')
2020-04-22 19:07:51 +05:30
end
end
2019-07-07 11:18:12 +05:30
types MergeRequest
condition do
2021-03-08 18:12:59 +05:30
quick_action_target.persisted? &&
merge_orchestration_service.can_merge?(quick_action_target)
2019-07-07 11:18:12 +05:30
end
command :merge do
2022-05-07 20:08:51 +05:30
next unless params[:merge_request_diff_head_sha].present?
next unless params[:merge_request_diff_head_sha] == quick_action_target.diff_head_sha
2019-07-07 11:18:12 +05:30
@updates[:merge] = params[:merge_request_diff_head_sha]
end
2021-03-08 18:12:59 +05:30
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
2022-04-04 11:22:00 +05:30
unless quick_action_target.permits_force_push?
@execution_message[:rebase] = _('This merge request branch is protected from force push.')
next
end
2021-03-08 18:12:59 +05:30
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
2022-07-23 23:45:48 +05:30
desc { _('Toggle the Draft status') }
2019-07-07 11:18:12 +05:30
explanation do
noun = quick_action_target.to_ability_name.humanize(capitalize: false)
2022-07-23 23:45:48 +05:30
if quick_action_target.draft?
_("Marks this %{noun} as ready.")
2019-10-12 21:52:04 +05:30
else
2021-01-29 00:20:46 +05:30
_("Marks this %{noun} as a draft.")
2019-10-12 21:52:04 +05:30
end % { noun: noun }
2019-07-07 11:18:12 +05:30
end
2019-10-12 21:52:04 +05:30
execution_message do
noun = quick_action_target.to_ability_name.humanize(capitalize: false)
2022-07-23 23:45:48 +05:30
if quick_action_target.draft?
_("Marked this %{noun} as ready.")
2019-10-12 21:52:04 +05:30
else
2021-01-29 00:20:46 +05:30
_("Marked this %{noun} as a draft.")
2019-10-12 21:52:04 +05:30
end % { noun: noun }
end
2019-07-07 11:18:12 +05:30
types MergeRequest
condition do
2022-07-23 23:45:48 +05:30
quick_action_target.respond_to?(:draft?) &&
# Allow it to mark as draft on MR creation page or through MR notes
#
2019-07-07 11:18:12 +05:30
(quick_action_target.new_record? || current_user.can?(:"update_#{quick_action_target.to_ability_name}", quick_action_target))
end
2021-09-04 01:27:46 +05:30
command :draft do
2022-07-23 23:45:48 +05:30
@updates[:wip_event] = quick_action_target.draft? ? 'ready' : 'draft'
2019-07-07 11:18:12 +05:30
end
2022-07-23 23:45:48 +05:30
desc { _('Set the Ready status') }
explanation do
noun = quick_action_target.to_ability_name.humanize(capitalize: false)
if quick_action_target.draft?
_("Marks this %{noun} as ready.")
else
_("No change to this %{noun}'s draft status.")
end % { noun: noun }
end
execution_message do
noun = quick_action_target.to_ability_name.humanize(capitalize: false)
if quick_action_target.draft?
_("Marked this %{noun} as ready.")
else
_("No change to this %{noun}'s draft status.")
end % { noun: noun }
end
types MergeRequest
condition do
# Allow it to mark as draft on MR creation page or through MR notes
#
quick_action_target.respond_to?(:draft?) &&
(quick_action_target.new_record? || current_user.can?(:"update_#{quick_action_target.to_ability_name}", quick_action_target))
end
command :ready do
@updates[:wip_event] = 'ready' if quick_action_target.draft?
end
desc { _('Set target branch') }
2019-07-07 11:18:12 +05:30
explanation do |branch_name|
2019-10-12 21:52:04 +05:30
_('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 }
2019-07-07 11:18:12 +05:30
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
2020-06-23 00:09:42 +05:30
2022-07-23 23:45:48 +05:30
desc { _('Submit a review') }
explanation { _('Submit the current review.') }
2020-06-23 00:09:42 +05:30
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
2021-01-03 14:25:43 +05:30
2022-07-23 23:45:48 +05:30
desc { _('Approve a merge request') }
explanation { _('Approve the current merge request.') }
2021-01-03 14:25:43 +05:30
types MergeRequest
condition do
quick_action_target.persisted? && quick_action_target.can_be_approved_by?(current_user)
end
command :approve do
2021-11-18 22:05:49 +05:30
success = ::MergeRequests::ApprovalService.new(project: quick_action_target.project, current_user: current_user).execute(quick_action_target)
2021-01-03 14:25:43 +05:30
next unless success
@execution_message[:approve] = _('Approved the current merge request.')
end
2021-03-08 18:12:59 +05:30
2022-07-23 23:45:48 +05:30
desc { _('Unapprove a merge request') }
explanation { _('Unapprove the current merge request.') }
2021-11-11 11:23:49 +05:30
types MergeRequest
condition do
quick_action_target.persisted? && quick_action_target.can_be_unapproved_by?(current_user)
end
command :unapprove do
2021-11-18 22:05:49 +05:30
success = ::MergeRequests::RemoveApprovalService.new(project: quick_action_target.project, current_user: current_user).execute(quick_action_target)
2021-11-11 11:23:49 +05:30
next unless success
@execution_message[:unapprove] = _('Unapproved the current merge request.')
end
2021-03-08 18:12:59 +05:30
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?
2022-04-04 11:22:00 +05:30
_("Failed to assign a reviewer because no user was specified.")
2021-03-08 18:12:59 +05:30
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
2021-03-11 19:13:27 +05:30
current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
2021-03-08 18:12:59 +05:30
end
parse_params do |reviewer_param|
extract_users(reviewer_param)
end
2021-03-11 19:13:27 +05:30
command :assign_reviewer, :reviewer, :request_review do |users|
2021-03-08 18:12:59 +05:30
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? &&
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
2022-04-04 11:22:00 +05:30
desc do
if quick_action_target.allows_multiple_reviewers?
_('Request attention from assignee(s) or reviewer(s)')
else
_('Request attention from assignee or reviewer')
end
end
explanation do |users|
_('Request attention from %{users_sentence}.') % { users_sentence: reviewer_users_sentence(users) }
end
execution_message do |users = nil|
if users.blank?
_("Failed to request attention because no user was found.")
else
_('Requested attention from %{users_sentence}.') % { users_sentence: reviewer_users_sentence(users) }
end
end
params do
quick_action_target.allows_multiple_reviewers? ? '@user1 @user2' : '@user'
end
types MergeRequest
condition do
2022-07-16 23:28:13 +05:30
current_user.mr_attention_requests_enabled? &&
2022-04-04 11:22:00 +05:30
current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
end
parse_params do |attention_param|
extract_users(attention_param)
end
2022-06-21 17:19:12 +05:30
command :attention, :attn do |users|
2022-04-04 11:22:00 +05:30
next if users.empty?
users.each do |user|
::MergeRequests::ToggleAttentionRequestedService.new(project: quick_action_target.project, merge_request: quick_action_target, current_user: current_user, user: user).execute
end
end
desc do
if quick_action_target.allows_multiple_reviewers?
_('Remove attention request(s)')
else
_('Remove attention request')
end
end
explanation do |users|
_('Removes attention from %{users_sentence}.') % { users_sentence: reviewer_users_sentence(users) }
end
execution_message do |users = nil|
if users.blank?
_("Failed to remove attention because no user was found.")
else
_('Removed attention from %{users_sentence}.') % { users_sentence: reviewer_users_sentence(users) }
end
end
params do
quick_action_target.allows_multiple_reviewers? ? '@user1 @user2' : '@user'
end
types MergeRequest
condition do
2022-07-16 23:28:13 +05:30
current_user.mr_attention_requests_enabled? &&
2022-04-04 11:22:00 +05:30
current_user.can?(:"admin_#{quick_action_target.to_ability_name}", project)
end
parse_params do |attention_param|
extract_users(attention_param)
end
command :remove_attention do |users|
next if users.empty?
::MergeRequests::BulkRemoveAttentionRequestedService.new(project: quick_action_target.project, merge_request: quick_action_target, current_user: current_user, users: users).execute
end
2021-03-08 18:12:59 +05:30
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
2019-07-07 11:18:12 +05:30
end
2020-04-22 19:07:51 +05:30
def merge_orchestration_service
2021-11-18 22:05:49 +05:30
@merge_orchestration_service ||= ::MergeRequests::MergeOrchestrationService.new(project, current_user)
2020-04-22 19:07:51 +05:30
end
def preferred_auto_merge_strategy(merge_request)
merge_orchestration_service.preferred_auto_merge_strategy(merge_request)
end
2019-07-07 11:18:12 +05:30
end
end
end