diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index 926880d7b0129c3c8c31bf25512c885d69ee0e1a..d29100be28c259150b9222e663f62aeec15ab983 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -122,12 +122,19 @@ def extract_users_failed(err) end end - def find_milestones(project, params = {}) - return [] unless project - - group_ids = project.group.self_and_ancestors.select(:id) if project.group + def find_milestones(container, params = {}) + return [] unless container + + group_ids = + if container.is_a?(Group) + group.self_and_ancestors.select(:id) + elsif container.is_a?(Project) && container.group + container.group.self_and_ancestors.select(:id) + else + [] + end - MilestonesFinder.new(params.merge(project_ids: [project.id], group_ids: group_ids)).execute + MilestonesFinder.new(params.merge(project_ids: [project&.id], group_ids: group_ids)).execute end def parent diff --git a/ee/spec/services/quick_actions/interpret_service_spec.rb b/ee/spec/services/quick_actions/interpret_service_spec.rb index cfcd1ce8f216f53a03f94e3b01d26518315e9764..6f2b8b5fdee62f6ce42e47b1815640c92138e4e7 100644 --- a/ee/spec/services/quick_actions/interpret_service_spec.rb +++ b/ee/spec/services/quick_actions/interpret_service_spec.rb @@ -1545,6 +1545,29 @@ end end + describe 'milestone command' do + context 'on group-level work items' do + let_it_be(:group_milestone) { create(:milestone, group: group, title: 'Group Milestone') } + let_it_be(:group_work_item) { create(:work_item, :epic, :group_level, namespace: group) } + let_it_be(:group_service) { described_class.new(container: group, current_user: developer) } + + before do + group.add_developer(developer) + stub_licensed_features(epics: true) + end + + it 'includes the milestone command in available commands for group level work items' do + expect(group_service.available_commands(group_work_item)).to include(a_hash_including(name: :milestone)) + end + + it 'updates the milestone on a group level work item' do + _, updates, _ = group_service.execute("/milestone %\"#{group_milestone.title}\"", group_work_item) + + expect(updates).to eq(milestone_id: group_milestone.id) + end + end + end + describe 'unassign command' do let(:content) { '/unassign' } let(:issue) { create(:issue, project: project, assignees: [user, user2]) } diff --git a/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb b/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb index fff3ad8b6946e63a88376b16f50d8c080bb5e953..1e49ab5258fa58f8422981ac15300047ad5028e8 100644 --- a/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb +++ b/lib/gitlab/quick_actions/issue_and_merge_request_actions.rb @@ -103,15 +103,15 @@ module IssueAndMergeRequestActions _("Set the milestone to %{milestone_reference}.") % { milestone_reference: milestone.to_reference } if milestone end params '%"milestone"' - types Issue, MergeRequest + types Issue, MergeRequest, WorkItem condition do quick_action_target.supports_milestone? && current_user.can?(:"set_#{quick_action_target.to_ability_name}_metadata", quick_action_target) && - find_milestones(project, state: 'active').any? + find_milestones(container, state: 'active').any? end parse_params do |milestone_param| extract_references(milestone_param, :milestone).first || - find_milestones(project, title: milestone_param.strip).first + find_milestones(container, title: milestone_param.strip).first end command :milestone do |milestone| @updates[:milestone_id] = milestone.id if milestone