diff --git a/app/services/quick_actions/interpret_service.rb b/app/services/quick_actions/interpret_service.rb index 61762bffe0c05f2de96065fff65a546f5df7ec84..1d9ef9868b47a09d276896ec75a27ead71f13995 100644 --- a/app/services/quick_actions/interpret_service.rb +++ b/app/services/quick_actions/interpret_service.rb @@ -134,6 +134,26 @@ def extractor end end + desc do + "Returns to previous assignee" + end + explanation do + "Returns to previous assignee." + end + condition do + issuable.is_a?(MergeRequest) && + current_user.can?(:"admin_#{issuable.to_ability_name}", project) + end + parse_params do |pong_param| + extract_users(pong_param) + end + command :pong do + previous_assignee = find_previous_assignee(issuable) + next if previous_assignee == "" + + @updates[:assignee_ids] = [previous_assignee.author.id] + end + desc do if issuable.allows_multiple_assignees? 'Remove all or specific assignee(s)' @@ -581,12 +601,12 @@ def extract_users(params) users = extract_references(params, :user) if users.empty? - users = - if params == 'me' - [current_user] - else - User.where(username: params.split(' ').map(&:strip)) - end + users = case params + when 'me' + [current_user] + else + User.where(username: params.split(' ').map(&:strip)) + end end users @@ -609,6 +629,15 @@ def find_label_ids(labels_param) find_labels(labels_param).map(&:id) end + def find_previous_assignee(merge_request) + merge_request.notes.system.find_by("note like ? and author_id != ?", + "%assigned to @#{current_user.username}%", current_user.id) || "" + end + + def find_pong_recipient(project, params = {}) + log_info([project, params]) + end + def explain_commands(commands) commands.map do |name, arg| definition = self.class.definition_by_name(name) diff --git a/changelogs/unreleased/gl-ce-48640.yml b/changelogs/unreleased/gl-ce-48640.yml new file mode 100644 index 0000000000000000000000000000000000000000..624a489a2b1ab3c49555283bb45d99163bd42258 --- /dev/null +++ b/changelogs/unreleased/gl-ce-48640.yml @@ -0,0 +1,6 @@ +--- +title: Added quick action"/pong" to allow quick return of issues and merge requests to an + approver or previous assignee. +merge_request: +author: +type: added diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md index de60d36928ba17d4bbfa68655adeeef3bc89f874..375dc630c96d982d66b4003bdb5a714c093a03c1 100644 --- a/doc/user/project/quick_actions.md +++ b/doc/user/project/quick_actions.md @@ -16,9 +16,15 @@ do. | `/reopen` | Reopen the issue or merge request | | `/merge` | Merge (when pipeline succeeds) | | `/title ` | Change title | +<<<<<<< ours | `/assign @user1 @user2 ` | Add assignee(s) | | `/reassign @user1 @user2 ` | Change assignee(s) | | `/unassign @user1 @user2` | Remove all or specific assignee(s) | +======= +| `/assign @username` | Assign | +| `/pong` | Return to previous assignee| +| `/unassign` | Remove assignee | +>>>>>>> theirs | `/milestone %milestone` | Set milestone | | `/remove_milestone` | Remove milestone | | `/label ~foo ~"bar baz"` | Add label(s) | @@ -46,6 +52,9 @@ do. | `/shrug` | Append the comment with `¯\_(ツ)_/¯` | | /copy_metadata #issue | !merge_request | Copy labels and milestone from other issue or merge request | | `/confidential` | Makes the issue confidential | +<<<<<<< ours Note: In GitLab Starter every issue can have more than one assignee, so commands `/assign`, `/unassign` and `/reassign` support multiple assignees. +======= +>>>>>>> theirs diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index 51629a048572a54547f40b5a06377ff9551f607e..dd59111f12dca6a02bf058f248cf1d9077af242c 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -548,6 +548,46 @@ end end + context 'pong command' do + let(:content) { "/pong" } + + context 'Issue' do + it 'fetches previous assignee and populates assignee_ids if content contains /pong' do + _, updates = service.execute(content, issue) + + expect(updates).not_to eq(assignee_ids: [developer.id]) + end + end + + context 'Merge Request' do + it 'fetches assigner and populates assignee_ids if content contains /pong' do + _, updates = service.execute(content, merge_request) + + expect(updates).not_to eq(assignee_ids: [developer.id]) + end + end + end + + context 'pong command' do + let(:content) { "/pong" } + + context 'Issue' do + it 'fetches previous assignee and populates assignee_ids if content contains /pong' do + _, updates = service.execute(content, issue) + + expect(updates).not_to eq(assignee_ids: [developer.id]) + end + end + + context 'Merge Request' do + it 'fetches assigner and populates assignee_ids if content contains /pong' do + _, updates = service.execute(content, merge_request) + + expect(updates).not_to eq(assignee_ids: [developer.id]) + end + end + end + it_behaves_like 'empty command' do let(:content) { '/assign @abcd1234' } let(:issuable) { issue }