diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index 4abb936e14a..28fa887bf2d 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -268,18 +268,20 @@ module QuickActions end end - desc 'Inherit (copy) labels and milestone from other issue' - explanation do |issue_id| - "Inherit (copy) labels and milestone from issue \"#{issue_id}\"." + desc 'Copy labels and milestone from other issue or merge request' + explanation do |issueable_id| + "Copy labels and milestone from issue or merge_request \"#{issueable_id}\"." end - params '#issue' + params '< #issue | !merge_request >' condition do issuable.persisted? && current_user.can?(:"update_#{issuable.to_ability_name}", issuable) end - command :inherit do |issue_id| - issue = extract_references(issue_id, :issue).first - if issue.present? && issue.project_id == issuable.project_id + command :copy_metadata do |issueable_id| + reference_type = issueable_id.include?("#") ? :issue : :merge_request + issue = extract_references(issueable_id, reference_type).first + + if issue.present? && issue.project.id == issuable.project.id @updates[:add_label_ids] = issue.labels.map(&:id) @updates[:milestone_id] = issue.milestone.id if issue.milestone diff --git a/changelogs/unreleased/add-inherit-command.yml b/changelogs/unreleased/add-inherit-command.yml index 84f5bc97fbe..d47aa8c7b36 100644 --- a/changelogs/unreleased/add-inherit-command.yml +++ b/changelogs/unreleased/add-inherit-command.yml @@ -1,5 +1,5 @@ --- title: Add Inherit quick action -merge_request: +merge_request: 16473 author: Mateusz Bajorski type: added diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md index 3b6bdc8ca3d..e2e2b859d35 100644 --- a/doc/user/project/quick_actions.md +++ b/doc/user/project/quick_actions.md @@ -41,4 +41,4 @@ do. | `/move path/to/project` | Moves issue to another project | | `/tableflip` | Append the comment with `(╯°□°)╯︵ ┻━┻` | | `/shrug` | Append the comment with `¯\_(ツ)_/¯` | -| `/inherit #issue` | Inherit (copy) labels and milestone from other issue | +| /copy_metadata < #issue | !merge_request > | copy_metadata labels and milestone from other issue or merge request | diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index ebe0c7639a0..9a8240f9491 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -306,17 +306,17 @@ describe QuickActions::InterpretService do end end - shared_examples 'inherit command' do - it 'fetches issue and copies labels and milestone if content contains /inherit issue_reference' do - issue_father # populate the issue + shared_examples 'copy_metadata command' do + it 'fetches issue or merge request and copies labels and milestone if content contains /copy_metadata reference' do + issueable_father # populate the issue todo_label # populate this label inreview_label # populate this label _, updates = service.execute(content, issuable) expect(updates[:add_label_ids]).to match_array([inreview_label.id, todo_label.id]) - if issue_father.milestone - expect(updates[:milestone_id]).to eq(issue_father.milestone.id) + if issueable_father.milestone + expect(updates[:milestone_id]).to eq(issueable_father.milestone.id) else expect(updates).not_to have_key(:milestone_id) end @@ -774,49 +774,49 @@ describe QuickActions::InterpretService do let(:issuable) { issue } end - context '/inherit command' do + context '/copy_metadata command' do let!(:todo_label) { create(:label, project: project, title: 'To Do') } let!(:inreview_label) { create(:label, project: project, title: 'In Review') } - it_behaves_like 'inherit command' do - # Without milestone assignment - let(:issue_father) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) } - - let(:content) { "/inherit #{issue_father.to_reference}" } - let(:issuable) { issue } - end - - it_behaves_like 'inherit command' do - # With milestone assignment - let(:issue_father) { create(:labeled_issue, project: project, labels: [todo_label, inreview_label], milestone: milestone) } - - let(:content) { "/inherit #{issue_father.to_reference(project)}" } - let(:issuable) { issue } - end - it_behaves_like 'empty command' do - let(:content) { '/inherit' } + let(:content) { '/copy_metadata' } let(:issuable) { issue } end + it_behaves_like 'copy_metadata command' do + let(:issueable_father) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) } + + let(:content) { "/copy_metadata #{issueable_father.to_reference}" } + let(:issuable) { issue } + end + + context 'when the parent issueable has a milestone' do + it_behaves_like 'copy_metadata command' do + let(:issueable_father) { create(:labeled_issue, project: project, labels: [todo_label, inreview_label], milestone: milestone) } + + let(:content) { "/copy_metadata #{issueable_father.to_reference(project)}" } + let(:issuable) { issue } + end + end + context 'cross project references' do it_behaves_like 'empty command' do let(:other_project) { create(:project, :public) } - let(:issue_father) { create(:labeled_issue, project: other_project, labels: [todo_label, inreview_label]) } - let(:content) { "/inherit #{issue_father.to_reference(project)}" } + let(:issueable_father) { create(:labeled_issue, project: other_project, labels: [todo_label, inreview_label]) } + let(:content) { "/copy_metadata #{issueable_father.to_reference(project)}" } let(:issuable) { issue } end it_behaves_like 'empty command' do - let(:content) { "/inherit imaginary#1234" } + let(:content) { "/copy_metadata imaginary#1234" } let(:issuable) { issue } end it_behaves_like 'empty command' do let(:other_project) { create(:project, :private) } - let(:issue_father) { create(:issue, project: other_project) } + let(:issueable_father) { create(:issue, project: other_project) } - let(:content) { "/inherit #{issue_father.to_reference(project)}" } + let(:content) { "/copy_metadata #{issueable_father.to_reference(project)}" } let(:issuable) { issue } end end