Commit 51fbe028 authored by Sean McGivern's avatar Sean McGivern

Merge branch 'sh-quick-action-rebase' into 'master'

Add a quick action for /rebase

See merge request gitlab-org/gitlab!49800
parents e9a97d90 b15df829
...@@ -126,9 +126,23 @@ module MergeRequests ...@@ -126,9 +126,23 @@ module MergeRequests
override :handle_quick_actions override :handle_quick_actions
def handle_quick_actions(merge_request) def handle_quick_actions(merge_request)
super super
# Ensure this parameter does not get used as an attribute
rebase = params.delete(:rebase)
if rebase
rebase_from_quick_action(merge_request)
# Ignore "/merge" if "/rebase" is used to avoid an unexpected race
params.delete(:merge)
end
merge_from_quick_action(merge_request) if params[:merge] merge_from_quick_action(merge_request) if params[:merge]
end end
def rebase_from_quick_action(merge_request)
merge_request.rebase_async(current_user.id)
end
def merge_from_quick_action(merge_request) def merge_from_quick_action(merge_request)
last_diff_sha = params.delete(:merge) last_diff_sha = params.delete(:merge)
......
---
title: Add a quick action for /rebase
merge_request: 49800
author:
type: added
...@@ -56,6 +56,7 @@ The following quick actions are applicable to descriptions, discussions and thre ...@@ -56,6 +56,7 @@ The following quick actions are applicable to descriptions, discussions and thre
| `/promote` | ✓ | | | Promote issue to epic. **(PREMIUM)** | | `/promote` | ✓ | | | Promote issue to epic. **(PREMIUM)** |
| `/publish` | ✓ | | | Publish issue to an associated [Status Page](../../operations/incident_management/status_page.md) ([Introduced in GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30906)) **(ULTIMATE)** | | `/publish` | ✓ | | | Publish issue to an associated [Status Page](../../operations/incident_management/status_page.md) ([Introduced in GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30906)) **(ULTIMATE)** |
| `/reassign @user1 @user2` | ✓ | ✓ | | Replace current assignees with those specified. **(STARTER)** | | `/reassign @user1 @user2` | ✓ | ✓ | | Replace current assignees with those specified. **(STARTER)** |
| `/rebase` | | ✓ | | Rebase source branch. This will schedule a background task that attempt to rebase the changes in the source branch on the latest commit of the target branch. If `/rebase` is used, `/merge` will be ignored to avoid a race condition where the source branch is merged or deleted before it is rebased. |
| `/relabel ~label1 ~label2` | ✓ | ✓ | ✓ | Replace current labels with those specified. | | `/relabel ~label1 ~label2` | ✓ | ✓ | ✓ | Replace current labels with those specified. |
| `/relate #issue1 #issue2` | ✓ | | | Mark issues as related. **(STARTER)** | | `/relate #issue1 #issue2` | ✓ | | | Mark issues as related. **(STARTER)** |
| `/remove_child_epic <epic>` | | | ✓ | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab/-/issues/7330)). **(ULTIMATE)** | | `/remove_child_epic <epic>` | | | ✓ | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab/-/issues/7330)). **(ULTIMATE)** |
......
...@@ -38,6 +38,32 @@ module Gitlab ...@@ -38,6 +38,32 @@ module Gitlab
@updates[:merge] = params[:merge_request_diff_head_sha] @updates[:merge] = params[:merge_request_diff_head_sha]
end 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.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
# 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' desc 'Toggle the Draft status'
explanation do explanation do
noun = quick_action_target.to_ability_name.humanize(capitalize: false) noun = quick_action_target.to_ability_name.humanize(capitalize: false)
......
...@@ -22975,6 +22975,12 @@ msgstr "" ...@@ -22975,6 +22975,12 @@ msgstr ""
msgid "Rebase in progress" msgid "Rebase in progress"
msgstr "" msgstr ""
msgid "Rebase source branch"
msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
msgid "Receive alerts from manually configured Prometheus servers." msgid "Receive alerts from manually configured Prometheus servers."
msgstr "" msgstr ""
...@@ -24328,6 +24334,9 @@ msgstr "" ...@@ -24328,6 +24334,9 @@ msgstr ""
msgid "Scheduled Deletion At - %{permanent_deletion_time}" msgid "Scheduled Deletion At - %{permanent_deletion_time}"
msgstr "" msgstr ""
msgid "Scheduled a rebase of branch %{branch}."
msgstr ""
msgid "Scheduled to merge this merge request (%{strategy})." msgid "Scheduled to merge this merge request (%{strategy})."
msgstr "" msgstr ""
......
...@@ -41,5 +41,6 @@ RSpec.describe 'Merge request > User uses quick actions', :js do ...@@ -41,5 +41,6 @@ RSpec.describe 'Merge request > User uses quick actions', :js do
end end
it_behaves_like 'merge quick action' it_behaves_like 'merge quick action'
it_behaves_like 'rebase quick action'
end end
end end
# frozen_string_literal: true
RSpec.shared_examples 'rebase quick action' do
context 'when updating the description' do
before do
sign_in(user)
visit edit_project_merge_request_path(project, merge_request)
end
it 'rebases the MR', :sidekiq_inline do
fill_in('Description', with: '/rebase')
click_button('Save changes')
expect(page).not_to have_content('commit behind the target branch')
expect(merge_request.reload).not_to be_merged
end
it 'ignores /merge if /rebase is specified', :sidekiq_inline do
fill_in('Description', with: "/merge\n/rebase")
click_button('Save changes')
expect(page).not_to have_content('commit behind the target branch')
expect(merge_request.reload).not_to be_merged
end
end
context 'when creating a new note' do
context 'when the current user can rebase the MR' do
before do
sign_in(user)
visit project_merge_request_path(project, merge_request)
end
it 'rebase the MR', :sidekiq_inline do
add_note("/rebase")
expect(page).to have_content "Scheduled a rebase of branch #{merge_request.source_branch}."
end
end
context 'when the current user cannot rebase the MR' do
before do
project.add_guest(guest)
sign_in(guest)
visit project_merge_request_path(project, merge_request)
end
it 'does not rebase the MR' do
add_note("/rebase")
expect(page).not_to have_content 'Your commands have been executed!'
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment