diff --git a/app/services/issuable/common_system_notes_service.rb b/app/services/issuable/common_system_notes_service.rb index 765de9c66b0..885e14bba8f 100644 --- a/app/services/issuable/common_system_notes_service.rb +++ b/app/services/issuable/common_system_notes_service.rb @@ -4,20 +4,23 @@ module Issuable class CommonSystemNotesService < ::BaseService attr_reader :issuable - def execute(issuable, old_labels) + def execute(issuable, old_labels: [], is_update: true) @issuable = issuable - if issuable.previous_changes.include?('title') - create_title_change_note(issuable.previous_changes['title'].first) + if is_update + if issuable.previous_changes.include?('title') + create_title_change_note(issuable.previous_changes['title'].first) + end + + handle_description_change_note + + handle_time_tracking_note if issuable.is_a?(TimeTrackable) + create_discussion_lock_note if issuable.previous_changes.include?('discussion_locked') end - handle_description_change_note - - handle_time_tracking_note if issuable.is_a?(TimeTrackable) - create_labels_note(old_labels) if issuable.labels != old_labels - create_discussion_lock_note if issuable.previous_changes.include?('discussion_locked') - create_milestone_note if issuable.previous_changes.include?('milestone_id') create_due_date_note if issuable.previous_changes.include?('due_date') + create_milestone_note if issuable.previous_changes.include?('milestone_id') + create_labels_note(old_labels) if issuable.labels != old_labels end private diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb index e32e262ac31..c7e7bb55e4b 100644 --- a/app/services/issuable_base_service.rb +++ b/app/services/issuable_base_service.rb @@ -152,6 +152,10 @@ class IssuableBaseService < BaseService before_create(issuable) if issuable.save + ActiveRecord::Base.no_touching do + Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, is_update: false) + end + after_create(issuable) execute_hooks(issuable) invalidate_cache_counts(issuable, users: issuable.assignees) @@ -207,7 +211,7 @@ class IssuableBaseService < BaseService if issuable.with_transaction_returning_status { issuable.save } # We do not touch as it will affect a update on updated_at field ActiveRecord::Base.no_touching do - Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_associations[:labels]) + Issuable::CommonSystemNotesService.new(project, current_user).execute(issuable, old_labels: old_associations[:labels]) end handle_changes(issuable, old_associations: old_associations) diff --git a/changelogs/unreleased/51485-new-issue-labels-note.yml b/changelogs/unreleased/51485-new-issue-labels-note.yml new file mode 100644 index 00000000000..a312d379ce2 --- /dev/null +++ b/changelogs/unreleased/51485-new-issue-labels-note.yml @@ -0,0 +1,5 @@ +--- +title: Create system notes on issue / MR creation when labels, milestone, or due date is set +merge_request: 23859 +author: +type: added diff --git a/spec/services/issuable/common_system_notes_service_spec.rb b/spec/services/issuable/common_system_notes_service_spec.rb index fa1a421d528..fa5d5ebac5c 100644 --- a/spec/services/issuable/common_system_notes_service_spec.rb +++ b/spec/services/issuable/common_system_notes_service_spec.rb @@ -5,7 +5,7 @@ describe Issuable::CommonSystemNotesService do let(:project) { create(:project) } let(:issuable) { create(:issue) } - describe '#execute' do + context 'on issuable update' do it_behaves_like 'system note creation', { title: 'New title' }, 'changed title' it_behaves_like 'system note creation', { description: 'New description' }, 'changed the description' it_behaves_like 'system note creation', { discussion_locked: true }, 'locked this issue' @@ -20,7 +20,7 @@ describe Issuable::CommonSystemNotesService do end it 'creates a resource label event' do - described_class.new(project, user).execute(issuable, []) + described_class.new(project, user).execute(issuable, old_labels: []) event = issuable.reload.resource_label_events.last expect(event).not_to be_nil @@ -68,4 +68,47 @@ describe Issuable::CommonSystemNotesService do end end end + + context 'on issuable create' do + let(:issuable) { build(:issue) } + + subject { described_class.new(project, user).execute(issuable, old_labels: [], is_update: false) } + + it 'does not create system note for title and description' do + issuable.save + + expect { subject }.not_to change { issuable.notes.count } + end + + it 'creates a resource label event for labels added' do + label = create(:label, project: project) + + issuable.labels << label + issuable.save + + expect { subject }.to change { issuable.resource_label_events.count }.from(0).to(1) + + event = issuable.reload.resource_label_events.last + + expect(event).not_to be_nil + expect(event.label_id).to eq label.id + expect(event.user_id).to eq user.id + end + + it 'creates a system note for milestone set' do + issuable.milestone = create(:milestone, project: project) + issuable.save + + expect { subject }.to change { issuable.notes.count }.from(0).to(1) + expect(issuable.notes.last.note).to match('changed milestone') + end + + it 'creates a system note for due_date set' do + issuable.due_date = Date.today + issuable.save + + expect { subject }.to change { issuable.notes.count }.from(0).to(1) + expect(issuable.notes.last.note).to match('changed due date') + end + end end diff --git a/spec/support/shared_examples/common_system_notes_examples.rb b/spec/support/shared_examples/common_system_notes_examples.rb index 96ef30b7513..da5a4f3e319 100644 --- a/spec/support/shared_examples/common_system_notes_examples.rb +++ b/spec/support/shared_examples/common_system_notes_examples.rb @@ -1,5 +1,5 @@ shared_examples 'system note creation' do |update_params, note_text| - subject { described_class.new(project, user).execute(issuable, [])} + subject { described_class.new(project, user).execute(issuable, old_labels: []) } before do issuable.assign_attributes(update_params) @@ -16,7 +16,7 @@ shared_examples 'system note creation' do |update_params, note_text| end shared_examples 'WIP notes creation' do |wip_action| - subject { described_class.new(project, user).execute(issuable, []) } + subject { described_class.new(project, user).execute(issuable, old_labels: []) } it 'creates WIP toggle and title change notes' do expect { subject }.to change { Note.count }.from(0).to(2)