From 7f7c3e1a8aeba5d21c332c8cacdf8af9067199c4 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 19:23:04 +0800 Subject: Add notification tests for it --- .../ci/send_pipeline_notification_service_spec.rb | 67 ++++++++++++++++++++-- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/spec/services/ci/send_pipeline_notification_service_spec.rb b/spec/services/ci/send_pipeline_notification_service_spec.rb index 288302cc94f..9c840967aed 100644 --- a/spec/services/ci/send_pipeline_notification_service_spec.rb +++ b/spec/services/ci/send_pipeline_notification_service_spec.rb @@ -11,23 +11,30 @@ describe Ci::SendPipelineNotificationService, services: true do let(:project) { create(:project) } let(:user) { create(:user) } - - subject{ described_class.new(pipeline) } + let(:pusher) { user } + let(:watcher) { pusher } describe '#execute' do before do reset_delivered_emails! + pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] end shared_examples 'sending emails' do - it 'sends an email to pipeline user' do + it 'sends emails' do perform_enqueued_jobs do subject.execute([user.email]) end - email = ActionMailer::Base.deliveries.last - expect(email.subject).to include(email_subject) - expect(email.to).to eq([user.email]) + expected_receivers = [pusher, watcher].uniq.sort_by(&:email) + actual = ActionMailer::Base.deliveries.sort_by(&:to) + + expect(expected_receivers.size).to eq(actual.size) + + actual.zip(expected_receivers).each do |(email, receiver)| + expect(email.subject).to include(email_subject) + expect(email.to).to eq([receiver.email]) + end end end @@ -36,6 +43,30 @@ describe Ci::SendPipelineNotificationService, services: true do let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + + context 'with success pipeline notification on' do + let(:watcher) { user } + + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with success pipeline notification off' do + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end end context 'with failed pipeline' do @@ -43,6 +74,30 @@ describe Ci::SendPipelineNotificationService, services: true do let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + + context 'with failed pipeline notification on' do + let(:watcher) { user } + + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with failed pipeline notification off' do + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end end end end -- cgit v1.2.1 From 8ea702cfe590e94ea496609f85ba0f23bda2dcce Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 19:42:16 +0800 Subject: Revert "Split notification integration into another branch" This reverts commit 1404aa8677969a03ed56e8f8350257f317f576d8. --- app/models/ci/pipeline.rb | 9 +++++++++ app/models/notification_setting.rb | 4 +++- app/services/ci/send_pipeline_notification_service.rb | 10 ++-------- app/services/notification_service.rb | 16 ++++++++++++++++ .../ci/send_pipeline_notification_service_spec.rb | 2 +- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 4fdb5fef4fb..c293096f5c9 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -82,6 +82,10 @@ module Ci PipelineHooksWorker.perform_async(id) end end + + after_transition any => [:success, :failed] do |pipeline, transition| + SendPipelineNotificationService.new(pipeline).execute + end end # ref can't be HEAD or SHA, can only be branch/tag name @@ -110,6 +114,11 @@ module Ci project.id end + # For now the only user who participants is the user who triggered + def participants(current_user = nil) + [user] + end + def valid_commit_sha if self.sha == Gitlab::Git::BLANK_SHA self.errors.add(:sha, " cant be 00000000 (branch removal)") diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb index 121b598b8f3..43fc218de2b 100644 --- a/app/models/notification_setting.rb +++ b/app/models/notification_setting.rb @@ -32,7 +32,9 @@ class NotificationSetting < ActiveRecord::Base :reopen_merge_request, :close_merge_request, :reassign_merge_request, - :merge_merge_request + :merge_merge_request, + :failed_pipeline, + :success_pipeline ] store :events, accessors: EMAIL_EVENTS, coder: JSON diff --git a/app/services/ci/send_pipeline_notification_service.rb b/app/services/ci/send_pipeline_notification_service.rb index ceb182801f7..cfbcad5dadf 100644 --- a/app/services/ci/send_pipeline_notification_service.rb +++ b/app/services/ci/send_pipeline_notification_service.rb @@ -6,14 +6,8 @@ module Ci @pipeline = new_pipeline end - def execute(recipients) - email_template = "pipeline_#{pipeline.status}_email" - - return unless Notify.respond_to?(email_template) - - recipients.each do |to| - Notify.public_send(email_template, pipeline, to).deliver_later - end + def execute(recipients = nil) + notification_service.pipeline_finished(pipeline, recipients) end end end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 72712afc07e..65091c2b8af 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -312,6 +312,22 @@ class NotificationService mailer.project_was_not_exported_email(current_user, project, errors).deliver_later end + def pipeline_finished(pipeline, recipients = nil) + email_template = "pipeline_#{pipeline.status}_email" + + return unless mailer.respond_to?(email_template) + + recipients ||= build_recipients( + pipeline, + pipeline.project, + nil, # The acting user, who won't be added to recipients + action: pipeline.status) + + recipients.each do |to| + mailer.public_send(email_template, pipeline, to.email).deliver_later + end + end + protected # Get project/group users with CUSTOM notification level diff --git a/spec/services/ci/send_pipeline_notification_service_spec.rb b/spec/services/ci/send_pipeline_notification_service_spec.rb index 9c840967aed..110e16410c5 100644 --- a/spec/services/ci/send_pipeline_notification_service_spec.rb +++ b/spec/services/ci/send_pipeline_notification_service_spec.rb @@ -23,7 +23,7 @@ describe Ci::SendPipelineNotificationService, services: true do shared_examples 'sending emails' do it 'sends emails' do perform_enqueued_jobs do - subject.execute([user.email]) + subject.execute end expected_receivers = [pusher, watcher].uniq.sort_by(&:email) -- cgit v1.2.1 From 1c38dbcadc23485ce1421f10d6062fb00221e0e1 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 19:45:18 +0800 Subject: Revert "Revert this until we do notifications" This reverts commit c5e0305d5fe150acd74a66efa46e3ee741642978. --- app/services/notification_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 65091c2b8af..4fef2395c6f 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -640,6 +640,6 @@ class NotificationService # Build event key to search on custom notification level # Check NotificationSetting::EMAIL_EVENTS def build_custom_key(action, object) - "#{action}_#{object.class.name.underscore}".to_sym + "#{action}_#{object.class.model_name.name.underscore}".to_sym end end -- cgit v1.2.1 From 691ed8aca410e8025582579cfa8454b1e54acb12 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 20:00:36 +0800 Subject: recipients should be a list of emails --- app/services/notification_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 4fef2395c6f..d4976aa8362 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -321,10 +321,10 @@ class NotificationService pipeline, pipeline.project, nil, # The acting user, who won't be added to recipients - action: pipeline.status) + action: pipeline.status).map(&:email) recipients.each do |to| - mailer.public_send(email_template, pipeline, to.email).deliver_later + mailer.public_send(email_template, pipeline, to).deliver_later end end -- cgit v1.2.1 From f049bdeb9dc08f52671e5919c83a6cf55865b246 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 21:40:19 +0800 Subject: Add CHANGELOG entry [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcaf62ac0aa..dad5df73203 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -246,6 +246,7 @@ Please view this file on the master branch, on stable branches it's out of date. - Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling) - Fix blame table layout width - Spec testing if issue authors can read issues on private projects + - Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - Fix bug where pagination is still displayed despite all todos marked as done (ClemMakesApps) - Request only the LDAP attributes we need !6187 - Center build stage columns in pipeline overview (ClemMakesApps) -- cgit v1.2.1 From 9c2d40649e0792652c3d41d3c19f2e45c0db5b03 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 21:43:52 +0800 Subject: Remove pusher support because it's covered by notifications --- app/models/project_services/pipelines_email_service.rb | 14 ++------------ .../models/project_services/pipeline_email_service_spec.rb | 8 -------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb index ec3c1bc85ee..b4e36a7c3de 100644 --- a/app/models/project_services/pipelines_email_service.rb +++ b/app/models/project_services/pipelines_email_service.rb @@ -1,10 +1,9 @@ class PipelinesEmailService < Service prop_accessor :recipients - boolean_accessor :add_pusher boolean_accessor :notify_only_broken_pipelines validates :recipients, presence: true, - if: ->(s) { s.activated? && !s.add_pusher? } + if: ->(s) { s.activated? } def initialize_properties self.properties ||= { notify_only_broken_pipelines: true } @@ -57,9 +56,6 @@ class PipelinesEmailService < Service { type: 'textarea', name: 'recipients', placeholder: 'Emails separated by comma' }, - { type: 'checkbox', - name: 'add_pusher', - label: 'Add pusher to recipients list' }, { type: 'checkbox', name: 'notify_only_broken_pipelines' }, ] @@ -85,12 +81,6 @@ class PipelinesEmailService < Service end def retrieve_recipients(data) - all_recipients = recipients.to_s.split(',').reject(&:blank?) - - if add_pusher? && data[:user].try(:[], :email) - all_recipients << data[:user][:email] - end - - all_recipients + recipients.to_s.split(',').reject(&:blank?) end end diff --git a/spec/models/project_services/pipeline_email_service_spec.rb b/spec/models/project_services/pipeline_email_service_spec.rb index 1368a2925e8..68a96b9251f 100644 --- a/spec/models/project_services/pipeline_email_service_spec.rb +++ b/spec/models/project_services/pipeline_email_service_spec.rb @@ -23,14 +23,6 @@ describe PipelinesEmailService do end it { is_expected.to validate_presence_of(:recipients) } - - context 'when pusher is added' do - before do - subject.add_pusher = true - end - - it { is_expected.not_to validate_presence_of(:recipients) } - end end context 'when service is inactive' do -- cgit v1.2.1 From 811de6ac73ea68ae3361ec49d2094d4f2006f493 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 21:57:04 +0800 Subject: Add test for sending pipeline notifications --- spec/models/ci/pipeline_spec.rb | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 550a890797e..f564a2d4fdd 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -523,4 +523,58 @@ describe Ci::Pipeline, models: true do expect(pipeline.merge_requests).to be_empty end end + + describe 'notifications when pipeline success or failed' do + before do + ActionMailer::Base.deliveries.clear + + pipeline.enqueue + pipeline.run + end + + shared_examples 'sending a notification' do + it 'sends an email' do + sent_to = ActionMailer::Base.deliveries.flat_map(&:to) + expect(sent_to).to contain_exactly(pipeline.user.email) + end + end + + shared_examples 'not sending any notification' do + it 'does not send any email' do + expect(ActionMailer::Base.deliveries).to be_empty + end + end + + context 'with success pipeline' do + before do + perform_enqueued_jobs do + pipeline.success + end + end + end + + context 'with failed pipeline' do + before do + perform_enqueued_jobs do + pipeline.drop + end + end + end + + context 'with skipped pipeline' do + before do + perform_enqueued_jobs do + pipeline.skip + end + end + end + + context 'with cancelled pipeline' do + before do + perform_enqueued_jobs do + pipeline.cancel + end + end + end + end end -- cgit v1.2.1 From aafd42c49d516d301d72a4f43d7e56d7bf168d80 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 14 Sep 2016 22:12:31 +0800 Subject: How could I forget this? --- spec/models/ci/pipeline_spec.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index f564a2d4fdd..dc1d1de12a1 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -528,6 +528,7 @@ describe Ci::Pipeline, models: true do before do ActionMailer::Base.deliveries.clear + pipeline.update(user: create(:user)) pipeline.enqueue pipeline.run end @@ -548,9 +549,11 @@ describe Ci::Pipeline, models: true do context 'with success pipeline' do before do perform_enqueued_jobs do - pipeline.success + pipeline.succeed end end + + it_behaves_like 'sending a notification' end context 'with failed pipeline' do @@ -559,6 +562,8 @@ describe Ci::Pipeline, models: true do pipeline.drop end end + + it_behaves_like 'sending a notification' end context 'with skipped pipeline' do @@ -567,6 +572,8 @@ describe Ci::Pipeline, models: true do pipeline.skip end end + + it_behaves_like 'not sending any notification' end context 'with cancelled pipeline' do @@ -575,6 +582,8 @@ describe Ci::Pipeline, models: true do pipeline.cancel end end + + it_behaves_like 'not sending any notification' end end end -- cgit v1.2.1 From 55f2e6ab21d4e23675fd3b1e9f5e0a5d59ea3976 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 15 Sep 2016 00:03:10 +0800 Subject: We're using BaseService --- app/services/ci/send_pipeline_notification_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/ci/send_pipeline_notification_service.rb b/app/services/ci/send_pipeline_notification_service.rb index cfbcad5dadf..d330fa1a73c 100644 --- a/app/services/ci/send_pipeline_notification_service.rb +++ b/app/services/ci/send_pipeline_notification_service.rb @@ -1,5 +1,5 @@ module Ci - class SendPipelineNotificationService + class SendPipelineNotificationService < BaseService attr_reader :pipeline def initialize(new_pipeline) -- cgit v1.2.1 From bac500fdeb3ac9b29c26fd8b48a0b1974c894413 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 19 Sep 2016 13:44:36 +0800 Subject: It no longer needs a block, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_15434727 --- app/models/project_services/pipelines_email_service.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb index b4e36a7c3de..ec27aa88f16 100644 --- a/app/models/project_services/pipelines_email_service.rb +++ b/app/models/project_services/pipelines_email_service.rb @@ -1,9 +1,7 @@ class PipelinesEmailService < Service prop_accessor :recipients boolean_accessor :notify_only_broken_pipelines - validates :recipients, - presence: true, - if: ->(s) { s.activated? } + validates :recipients, presence: true, if: :activated? def initialize_properties self.properties ||= { notify_only_broken_pipelines: true } -- cgit v1.2.1 From d39b1959d80f857e57fe67696c8d4525cb5966d9 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 19 Sep 2016 13:47:11 +0800 Subject: Prefer methods from EmailHelpers, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_15434869 --- spec/models/ci/pipeline_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index dc1d1de12a1..03dd8867b18 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -526,7 +526,7 @@ describe Ci::Pipeline, models: true do describe 'notifications when pipeline success or failed' do before do - ActionMailer::Base.deliveries.clear + reset_delivered_emails! pipeline.update(user: create(:user)) pipeline.enqueue -- cgit v1.2.1 From 572585665f838584b9547831528f26fb60df8d0f Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 19 Sep 2016 13:54:16 +0800 Subject: Use EmailHelpers where possible, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_15434860 --- spec/models/ci/pipeline_spec.rb | 5 ++--- spec/support/email_helpers.rb | 6 +++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 03dd8867b18..050ab50f84f 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -535,14 +535,13 @@ describe Ci::Pipeline, models: true do shared_examples 'sending a notification' do it 'sends an email' do - sent_to = ActionMailer::Base.deliveries.flat_map(&:to) - expect(sent_to).to contain_exactly(pipeline.user.email) + should_only_email(pipeline.user) end end shared_examples 'not sending any notification' do it 'does not send any email' do - expect(ActionMailer::Base.deliveries).to be_empty + should_email_no_one end end diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb index 0bfc4685532..dfb252544e7 100644 --- a/spec/support/email_helpers.rb +++ b/spec/support/email_helpers.rb @@ -1,6 +1,6 @@ module EmailHelpers def sent_to_user?(user) - ActionMailer::Base.deliveries.map(&:to).flatten.count(user.email) == 1 + ActionMailer::Base.deliveries.flat_map(&:to).count(user.email) == 1 end def reset_delivered_emails! @@ -20,4 +20,8 @@ module EmailHelpers def should_not_email(user) expect(sent_to_user?(user)).to be_falsey end + + def should_email_no_one + expect(ActionMailer::Base.deliveries).to be_empty + end end -- cgit v1.2.1 From 230bae9d48505ac59bfdc61ae739192416d18e92 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 19 Sep 2016 13:57:55 +0800 Subject: Update the other sites for reset_delivered_emails! as well --- spec/mailers/shared/notify.rb | 2 +- .../pipeline_email_service_spec.rb | 2 +- spec/services/notification_service_spec.rb | 28 +++++++++++----------- spec/workers/build_email_worker_spec.rb | 2 +- spec/workers/emails_on_push_worker_spec.rb | 4 ++-- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/spec/mailers/shared/notify.rb b/spec/mailers/shared/notify.rb index 3956d05060b..49867aa5cc4 100644 --- a/spec/mailers/shared/notify.rb +++ b/spec/mailers/shared/notify.rb @@ -7,7 +7,7 @@ shared_context 'gitlab email notification' do let(:new_user_address) { 'newguy@example.com' } before do - ActionMailer::Base.deliveries.clear + reset_delivered_emails! email = recipient.emails.create(email: "notifications@example.com") recipient.update_attribute(:notification_email, email.email) stub_incoming_email_setting(enabled: true, address: "reply+%{key}@#{Gitlab.config.gitlab.host}") diff --git a/spec/models/project_services/pipeline_email_service_spec.rb b/spec/models/project_services/pipeline_email_service_spec.rb index 68a96b9251f..e2d8eaf6a1f 100644 --- a/spec/models/project_services/pipeline_email_service_spec.rb +++ b/spec/models/project_services/pipeline_email_service_spec.rb @@ -13,7 +13,7 @@ describe PipelinesEmailService do end before do - ActionMailer::Base.deliveries.clear + reset_delivered_emails! end describe 'Validations' do diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 699b9925b4e..84c22631c67 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -17,7 +17,7 @@ describe NotificationService, services: true do it 'sends no emails when no new mentions are present' do send_notifications - expect(ActionMailer::Base.deliveries).to be_empty + should_email_no_one end it 'emails new mentions with a watch level higher than participant' do @@ -27,7 +27,7 @@ describe NotificationService, services: true do it 'does not email new mentions with a watch level equal to or less than participant' do send_notifications(@u_participating, @u_mentioned) - expect(ActionMailer::Base.deliveries).to be_empty + should_email_no_one end end @@ -79,7 +79,7 @@ describe NotificationService, services: true do # Ensure create SentNotification by noteable = issue 6 times, not noteable = note expect(SentNotification).to receive(:record).with(issue, any_args).exactly(8).times - ActionMailer::Base.deliveries.clear + reset_delivered_emails! notification.new_note(note) @@ -111,7 +111,7 @@ describe NotificationService, services: true do context 'participating' do context 'by note' do before do - ActionMailer::Base.deliveries.clear + reset_delivered_emails! note.author = @u_lazy_participant note.save notification.new_note(note) @@ -134,7 +134,7 @@ describe NotificationService, services: true do @u_watcher.notification_settings_for(note.project).participating! @u_watcher.notification_settings_for(note.project.group).global! update_custom_notification(:new_note, @u_custom_global) - ActionMailer::Base.deliveries.clear + reset_delivered_emails! end it do @@ -173,7 +173,7 @@ describe NotificationService, services: true do expect(SentNotification).to receive(:record).with(confidential_issue, any_args).exactly(4).times - ActionMailer::Base.deliveries.clear + reset_delivered_emails! notification.new_note(note) @@ -196,7 +196,7 @@ describe NotificationService, services: true do before do build_team(note.project) note.project.team << [note.author, :master] - ActionMailer::Base.deliveries.clear + reset_delivered_emails! end describe '#new_note' do @@ -238,7 +238,7 @@ describe NotificationService, services: true do before do build_team(note.project) note.project.team << [note.author, :master] - ActionMailer::Base.deliveries.clear + reset_delivered_emails! end describe '#new_note' do @@ -273,7 +273,7 @@ describe NotificationService, services: true do before do build_team(note.project) - ActionMailer::Base.deliveries.clear + reset_delivered_emails! allow_any_instance_of(Commit).to receive(:author).and_return(@u_committer) update_custom_notification(:new_note, @u_guest_custom, project) update_custom_notification(:new_note, @u_custom_global) @@ -348,7 +348,7 @@ describe NotificationService, services: true do before do build_team(issue.project) add_users_with_subscription(issue.project, issue) - ActionMailer::Base.deliveries.clear + reset_delivered_emails! update_custom_notification(:new_issue, @u_guest_custom, project) update_custom_notification(:new_issue, @u_custom_global) end @@ -408,7 +408,7 @@ describe NotificationService, services: true do label.toggle_subscription(guest) label.toggle_subscription(admin) - ActionMailer::Base.deliveries.clear + reset_delivered_emails! notification.new_issue(confidential_issue, @u_disabled) @@ -604,7 +604,7 @@ describe NotificationService, services: true do label_2.toggle_subscription(guest) label_2.toggle_subscription(admin) - ActionMailer::Base.deliveries.clear + reset_delivered_emails! notification.relabeled_issue(confidential_issue, [label_2], @u_disabled) @@ -733,7 +733,7 @@ describe NotificationService, services: true do add_users_with_subscription(merge_request.target_project, merge_request) update_custom_notification(:new_merge_request, @u_guest_custom, project) update_custom_notification(:new_merge_request, @u_custom_global) - ActionMailer::Base.deliveries.clear + reset_delivered_emails! end describe '#new_merge_request' do @@ -1111,7 +1111,7 @@ describe NotificationService, services: true do before do build_team(project) - ActionMailer::Base.deliveries.clear + reset_delivered_emails! end describe '#project_was_moved' do diff --git a/spec/workers/build_email_worker_spec.rb b/spec/workers/build_email_worker_spec.rb index 788b92c1b84..a1aa336361a 100644 --- a/spec/workers/build_email_worker_spec.rb +++ b/spec/workers/build_email_worker_spec.rb @@ -24,7 +24,7 @@ describe BuildEmailWorker do end it "gracefully handles an input SMTP error" do - ActionMailer::Base.deliveries.clear + reset_delivered_emails! allow(Notify).to receive(:build_success_email).and_raise(Net::SMTPFatalError) subject.perform(build.id, [user.email], data.stringify_keys) diff --git a/spec/workers/emails_on_push_worker_spec.rb b/spec/workers/emails_on_push_worker_spec.rb index 036d037f3f9..fc652f6f4c3 100644 --- a/spec/workers/emails_on_push_worker_spec.rb +++ b/spec/workers/emails_on_push_worker_spec.rb @@ -87,7 +87,7 @@ describe EmailsOnPushWorker do context "when there is an SMTP error" do before do - ActionMailer::Base.deliveries.clear + reset_delivered_emails! allow(Notify).to receive(:repository_push_email).and_raise(Net::SMTPFatalError) allow(subject).to receive_message_chain(:logger, :info) perform @@ -112,7 +112,7 @@ describe EmailsOnPushWorker do original.call(Mail.new(mail.encoded)) end - ActionMailer::Base.deliveries.clear + reset_delivered_emails! end it "sends the mail to each of the recipients" do -- cgit v1.2.1 From beb47c257a6673addb44fc6573c176f6be6cbd1b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 19 Sep 2016 14:01:58 +0800 Subject: Try to slightly optimize EmailHeleprs --- spec/support/email_helpers.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb index dfb252544e7..2931967de35 100644 --- a/spec/support/email_helpers.rb +++ b/spec/support/email_helpers.rb @@ -1,6 +1,8 @@ module EmailHelpers - def sent_to_user?(user) - ActionMailer::Base.deliveries.flat_map(&:to).count(user.email) == 1 + def sent_to_user?(user, recipients = nil) + recipients ||= ActionMailer::Base.deliveries.flat_map(&:to) + + recipients.count(user.email) == 1 end def reset_delivered_emails! @@ -8,17 +10,19 @@ module EmailHelpers end def should_only_email(*users) - users.each {|user| should_email(user) } recipients = ActionMailer::Base.deliveries.flat_map(&:to) + + users.each { |user| should_email(user, recipients) } + expect(recipients.count).to eq(users.count) end - def should_email(user) - expect(sent_to_user?(user)).to be_truthy + def should_email(user, recipients = nil) + expect(sent_to_user?(user, recipients)).to be_truthy end - def should_not_email(user) - expect(sent_to_user?(user)).to be_falsey + def should_not_email(user, recipients = nil) + expect(sent_to_user?(user, recipients)).to be_falsey end def should_email_no_one -- cgit v1.2.1 From 612820b2964e77397b6d85f74eb96888b72c4cbd Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 26 Sep 2016 19:04:02 +0800 Subject: Fix test by having a real commit --- spec/models/ci/pipeline_spec.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 050ab50f84f..787042cf055 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -525,10 +525,18 @@ describe Ci::Pipeline, models: true do end describe 'notifications when pipeline success or failed' do + let(:project) { create(:project) } + + let(:pipeline) do + create(:ci_pipeline, + project: project, + sha: project.commit('master').sha, + user: create(:user)) + end + before do reset_delivered_emails! - pipeline.update(user: create(:user)) pipeline.enqueue pipeline.run end -- cgit v1.2.1 From 56562d26dd1346d8db4fc673d711b3b6a77851cd Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 28 Sep 2016 15:27:11 +0800 Subject: Fix spelling, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_16074432 --- app/models/ci/pipeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index c293096f5c9..fd50abe1c36 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -114,7 +114,7 @@ module Ci project.id end - # For now the only user who participants is the user who triggered + # For now the only user who participates is the user who triggered def participants(current_user = nil) [user] end -- cgit v1.2.1 From 12a6bbc36a85fce8e4025470ea559a2830617eb9 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 28 Sep 2016 15:28:01 +0800 Subject: Prefix _ to show that it's intended unused, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_16073734 --- app/models/ci/pipeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index fd50abe1c36..61bb89a0a23 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -115,7 +115,7 @@ module Ci end # For now the only user who participates is the user who triggered - def participants(current_user = nil) + def participants(_current_user = nil) [user] end -- cgit v1.2.1 From 9622ef64e41058b8dec97c98f568d8fdea95fd61 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 28 Sep 2016 15:39:54 +0800 Subject: Introduce email_recipients and use include? Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_16075554 https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_16075622 --- spec/support/email_helpers.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb index 2931967de35..caa6ab1345a 100644 --- a/spec/support/email_helpers.rb +++ b/spec/support/email_helpers.rb @@ -1,8 +1,6 @@ module EmailHelpers - def sent_to_user?(user, recipients = nil) - recipients ||= ActionMailer::Base.deliveries.flat_map(&:to) - - recipients.count(user.email) == 1 + def sent_to_user?(user, recipients = email_recipients) + recipients.include?(user.email) end def reset_delivered_emails! @@ -10,22 +8,26 @@ module EmailHelpers end def should_only_email(*users) - recipients = ActionMailer::Base.deliveries.flat_map(&:to) + recipients = email_recipients users.each { |user| should_email(user, recipients) } expect(recipients.count).to eq(users.count) end - def should_email(user, recipients = nil) + def should_email(user, recipients = email_recipients) expect(sent_to_user?(user, recipients)).to be_truthy end - def should_not_email(user, recipients = nil) + def should_not_email(user, recipients = email_recipients) expect(sent_to_user?(user, recipients)).to be_falsey end def should_email_no_one expect(ActionMailer::Base.deliveries).to be_empty end + + def email_recipients + ActionMailer::Base.deliveries.flat_map(&:to) + end end -- cgit v1.2.1 From eeeb96c9d0cab9c5da850809a9614e2a01fdb7d2 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 28 Sep 2016 17:22:06 +0800 Subject: Change service to be a worker, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_16118195 --- app/models/ci/pipeline.rb | 4 +- .../project_services/pipelines_email_service.rb | 4 +- .../ci/send_pipeline_notification_service.rb | 13 --- app/workers/send_pipeline_notification_worker.rb | 9 ++ spec/models/ci/pipeline_spec.rb | 6 +- .../ci/send_pipeline_notification_service_spec.rb | 103 --------------------- .../send_pipeline_notification_worker_spec.rb | 103 +++++++++++++++++++++ 7 files changed, 120 insertions(+), 122 deletions(-) delete mode 100644 app/services/ci/send_pipeline_notification_service.rb create mode 100644 app/workers/send_pipeline_notification_worker.rb delete mode 100644 spec/services/ci/send_pipeline_notification_service_spec.rb create mode 100644 spec/workers/send_pipeline_notification_worker_spec.rb diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 61bb89a0a23..d534fdc0560 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -83,8 +83,8 @@ module Ci end end - after_transition any => [:success, :failed] do |pipeline, transition| - SendPipelineNotificationService.new(pipeline).execute + after_transition any => [:success, :failed] do |pipeline| + SendPipelineNotificationWorker.perform_async(pipeline.id) end end diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb index ec27aa88f16..4cebb9e7f93 100644 --- a/app/models/project_services/pipelines_email_service.rb +++ b/app/models/project_services/pipelines_email_service.rb @@ -31,8 +31,8 @@ class PipelinesEmailService < Service return unless all_recipients.any? - pipeline = Ci::Pipeline.find(data[:object_attributes][:id]) - Ci::SendPipelineNotificationService.new(pipeline).execute(all_recipients) + pipeline_id = data[:object_attributes][:id] + SendPipelineNotificationWorker.perform_async(pipeline_id, all_recipients) end def can_test? diff --git a/app/services/ci/send_pipeline_notification_service.rb b/app/services/ci/send_pipeline_notification_service.rb deleted file mode 100644 index d330fa1a73c..00000000000 --- a/app/services/ci/send_pipeline_notification_service.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Ci - class SendPipelineNotificationService < BaseService - attr_reader :pipeline - - def initialize(new_pipeline) - @pipeline = new_pipeline - end - - def execute(recipients = nil) - notification_service.pipeline_finished(pipeline, recipients) - end - end -end diff --git a/app/workers/send_pipeline_notification_worker.rb b/app/workers/send_pipeline_notification_worker.rb new file mode 100644 index 00000000000..d4837d815a5 --- /dev/null +++ b/app/workers/send_pipeline_notification_worker.rb @@ -0,0 +1,9 @@ +class SendPipelineNotificationWorker + include Sidekiq::Worker + + def perform(pipeline_id, recipients = nil) + pipeline = Ci::Pipeline.find(pipeline_id) + + NotificationService.new.pipeline_finished(pipeline, recipients) + end +end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 787042cf055..6ea712ae1b3 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -537,8 +537,10 @@ describe Ci::Pipeline, models: true do before do reset_delivered_emails! - pipeline.enqueue - pipeline.run + perform_enqueued_jobs do + pipeline.enqueue + pipeline.run + end end shared_examples 'sending a notification' do diff --git a/spec/services/ci/send_pipeline_notification_service_spec.rb b/spec/services/ci/send_pipeline_notification_service_spec.rb deleted file mode 100644 index 110e16410c5..00000000000 --- a/spec/services/ci/send_pipeline_notification_service_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'spec_helper' - -describe Ci::SendPipelineNotificationService, services: true do - let(:pipeline) do - create(:ci_pipeline, - project: project, - sha: project.commit('master').sha, - user: user, - status: status) - end - - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:pusher) { user } - let(:watcher) { pusher } - - describe '#execute' do - before do - reset_delivered_emails! - pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] - end - - shared_examples 'sending emails' do - it 'sends emails' do - perform_enqueued_jobs do - subject.execute - end - - expected_receivers = [pusher, watcher].uniq.sort_by(&:email) - actual = ActionMailer::Base.deliveries.sort_by(&:to) - - expect(expected_receivers.size).to eq(actual.size) - - actual.zip(expected_receivers).each do |(email, receiver)| - expect(email.subject).to include(email_subject) - expect(email.to).to eq([receiver.email]) - end - end - end - - context 'with success pipeline' do - let(:status) { 'success' } - let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } - - it_behaves_like 'sending emails' - - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } - - context 'with success pipeline notification on' do - let(:watcher) { user } - - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: true) - end - - it_behaves_like 'sending emails' - end - - context 'with success pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: false) - end - - it_behaves_like 'sending emails' - end - end - end - - context 'with failed pipeline' do - let(:status) { 'failed' } - let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } - - it_behaves_like 'sending emails' - - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } - - context 'with failed pipeline notification on' do - let(:watcher) { user } - - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: true) - end - - it_behaves_like 'sending emails' - end - - context 'with failed pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: false) - end - - it_behaves_like 'sending emails' - end - end - end - end -end diff --git a/spec/workers/send_pipeline_notification_worker_spec.rb b/spec/workers/send_pipeline_notification_worker_spec.rb new file mode 100644 index 00000000000..0670d67501a --- /dev/null +++ b/spec/workers/send_pipeline_notification_worker_spec.rb @@ -0,0 +1,103 @@ +require 'spec_helper' + +describe SendPipelineNotificationWorker, services: true do + let(:pipeline) do + create(:ci_pipeline, + project: project, + sha: project.commit('master').sha, + user: user, + status: status) + end + + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:pusher) { user } + let(:watcher) { pusher } + + describe '#execute' do + before do + reset_delivered_emails! + pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] + end + + shared_examples 'sending emails' do + it 'sends emails' do + perform_enqueued_jobs do + subject.perform(pipeline.id) + end + + expected_receivers = [pusher, watcher].uniq.sort_by(&:email) + actual = ActionMailer::Base.deliveries.sort_by(&:to) + + expect(expected_receivers.size).to eq(actual.size) + + actual.zip(expected_receivers).each do |(email, receiver)| + expect(email.subject).to include(email_subject) + expect(email.to).to eq([receiver.email]) + end + end + end + + context 'with success pipeline' do + let(:status) { 'success' } + let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } + + it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + + context 'with success pipeline notification on' do + let(:watcher) { user } + + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with success pipeline notification off' do + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end + end + + context 'with failed pipeline' do + let(:status) { 'failed' } + let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } + + it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + + context 'with failed pipeline notification on' do + let(:watcher) { user } + + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with failed pipeline notification off' do + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end + end + end +end -- cgit v1.2.1 From c065f5360fb3c89ab66fc2b744243b0eef166355 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 28 Sep 2016 17:29:53 +0800 Subject: That's no longer a service [ci skip] --- spec/workers/send_pipeline_notification_worker_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/workers/send_pipeline_notification_worker_spec.rb b/spec/workers/send_pipeline_notification_worker_spec.rb index 0670d67501a..f03231498a2 100644 --- a/spec/workers/send_pipeline_notification_worker_spec.rb +++ b/spec/workers/send_pipeline_notification_worker_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SendPipelineNotificationWorker, services: true do +describe SendPipelineNotificationWorker do let(:pipeline) do create(:ci_pipeline, project: project, -- cgit v1.2.1 From 8dd580f4022fa01521264cfbd6eaeb92d39430b5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 30 Sep 2016 00:12:10 +0800 Subject: It's already async, from Project#execute_services, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_16132555 --- app/models/project_services/pipelines_email_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb index 4cebb9e7f93..e2cb1df81b5 100644 --- a/app/models/project_services/pipelines_email_service.rb +++ b/app/models/project_services/pipelines_email_service.rb @@ -32,7 +32,7 @@ class PipelinesEmailService < Service return unless all_recipients.any? pipeline_id = data[:object_attributes][:id] - SendPipelineNotificationWorker.perform_async(pipeline_id, all_recipients) + SendPipelineNotificationWorker.new.perform(pipeline_id, all_recipients) end def can_test? -- cgit v1.2.1 From 6bab69aa0c0a6383a7eda5d74504939891f30f41 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 30 Sep 2016 01:15:03 +0800 Subject: Show it as successful pipeline, rather than success pipeline Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_16132150 --- app/helpers/notifications_helper.rb | 9 +++++++++ app/views/shared/notifications/_custom_notifications.html.haml | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index 7e8369d0a05..03cc8f2b6bd 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -74,4 +74,13 @@ module NotificationsHelper return unless notification_setting.source_type hidden_field_tag "#{notification_setting.source_type.downcase}_id", notification_setting.source_id end + + def notification_event_name(event) + case event + when :success_pipeline + 'Successful pipeline' + else + event.to_s.humanize + end + end end diff --git a/app/views/shared/notifications/_custom_notifications.html.haml b/app/views/shared/notifications/_custom_notifications.html.haml index b704981e3db..a82fc95df84 100644 --- a/app/views/shared/notifications/_custom_notifications.html.haml +++ b/app/views/shared/notifications/_custom_notifications.html.haml @@ -27,5 +27,5 @@ %label{ for: field_id } = check_box("notification_setting", event, id: field_id, class: "js-custom-notification-event", checked: notification_setting.events[event]) %strong - = event.to_s.humanize + = notification_event_name(event) = icon("spinner spin", class: "custom-notification-event-loading") -- cgit v1.2.1 From 776877c27deec6d44b1f95f16af5852653d8b946 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 14 Oct 2016 20:07:14 +0800 Subject: Pipeline#user could be nil. Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_16956937 --- app/models/ci/pipeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index d534fdc0560..0ed1c496022 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -116,7 +116,7 @@ module Ci # For now the only user who participates is the user who triggered def participants(_current_user = nil) - [user] + [user].compact end def valid_commit_sha -- cgit v1.2.1 From 0a11d53153d692f8c2b3c5125c5cd5e5042c08b3 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 17 Oct 2016 18:03:42 +0800 Subject: Fix test failure due to bad rebase, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_17043090 --- spec/workers/send_pipeline_notification_worker_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/workers/send_pipeline_notification_worker_spec.rb b/spec/workers/send_pipeline_notification_worker_spec.rb index f03231498a2..8d358992c7c 100644 --- a/spec/workers/send_pipeline_notification_worker_spec.rb +++ b/spec/workers/send_pipeline_notification_worker_spec.rb @@ -5,7 +5,7 @@ describe SendPipelineNotificationWorker do create(:ci_pipeline, project: project, sha: project.commit('master').sha, - user: user, + user: pusher, status: status) end -- cgit v1.2.1 From 98217bc0674253f30dea3892a8e833436b89d5b9 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 17 Oct 2016 18:03:53 +0800 Subject: should_email_no_one -> should_not_email_anyone, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_17039876 --- spec/models/ci/pipeline_spec.rb | 2 +- spec/services/notification_service_spec.rb | 4 ++-- spec/support/email_helpers.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 6ea712ae1b3..85820a9dc57 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -551,7 +551,7 @@ describe Ci::Pipeline, models: true do shared_examples 'not sending any notification' do it 'does not send any email' do - should_email_no_one + should_not_email_anyone end end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 84c22631c67..8ce35354c22 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -17,7 +17,7 @@ describe NotificationService, services: true do it 'sends no emails when no new mentions are present' do send_notifications - should_email_no_one + should_not_email_anyone end it 'emails new mentions with a watch level higher than participant' do @@ -27,7 +27,7 @@ describe NotificationService, services: true do it 'does not email new mentions with a watch level equal to or less than participant' do send_notifications(@u_participating, @u_mentioned) - should_email_no_one + should_not_email_anyone end end diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb index caa6ab1345a..36f5a2d5975 100644 --- a/spec/support/email_helpers.rb +++ b/spec/support/email_helpers.rb @@ -23,7 +23,7 @@ module EmailHelpers expect(sent_to_user?(user, recipients)).to be_falsey end - def should_email_no_one + def should_not_email_anyone expect(ActionMailer::Base.deliveries).to be_empty end -- cgit v1.2.1 From b4e751557ad35d7c5fbed55328892c43a4c84ba5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 17 Oct 2016 18:09:43 +0800 Subject: Use run_after_commit to avoid race condition, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_17038749 --- app/models/ci/pipeline.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 0ed1c496022..2a0865abd4b 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -84,7 +84,9 @@ module Ci end after_transition any => [:success, :failed] do |pipeline| - SendPipelineNotificationWorker.perform_async(pipeline.id) + pipeline.run_after_commit do + SendPipelineNotificationWorker.perform_async(pipeline.id) + end end end -- cgit v1.2.1 From 2e067480a9824228542c229a09aa4b6f006dc6f3 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 17 Oct 2016 18:12:07 +0800 Subject: Rename for a more consistent pipeline worker name, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_17039533 --- app/models/ci/pipeline.rb | 2 +- .../project_services/pipelines_email_service.rb | 2 +- app/workers/pipeline_notification_worker.rb | 9 ++ app/workers/send_pipeline_notification_worker.rb | 9 -- spec/workers/pipeline_notification_worker_spec.rb | 103 +++++++++++++++++++++ .../send_pipeline_notification_worker_spec.rb | 103 --------------------- 6 files changed, 114 insertions(+), 114 deletions(-) create mode 100644 app/workers/pipeline_notification_worker.rb delete mode 100644 app/workers/send_pipeline_notification_worker.rb create mode 100644 spec/workers/pipeline_notification_worker_spec.rb delete mode 100644 spec/workers/send_pipeline_notification_worker_spec.rb diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 2a0865abd4b..5604296cba5 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -85,7 +85,7 @@ module Ci after_transition any => [:success, :failed] do |pipeline| pipeline.run_after_commit do - SendPipelineNotificationWorker.perform_async(pipeline.id) + PipelineNotificationWorker.perform_async(pipeline.id) end end end diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb index e2cb1df81b5..745f9bd1b43 100644 --- a/app/models/project_services/pipelines_email_service.rb +++ b/app/models/project_services/pipelines_email_service.rb @@ -32,7 +32,7 @@ class PipelinesEmailService < Service return unless all_recipients.any? pipeline_id = data[:object_attributes][:id] - SendPipelineNotificationWorker.new.perform(pipeline_id, all_recipients) + PipelineNotificationWorker.new.perform(pipeline_id, all_recipients) end def can_test? diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb new file mode 100644 index 00000000000..f4e9a4cf245 --- /dev/null +++ b/app/workers/pipeline_notification_worker.rb @@ -0,0 +1,9 @@ +class PipelineNotificationWorker + include Sidekiq::Worker + + def perform(pipeline_id, recipients = nil) + pipeline = Ci::Pipeline.find(pipeline_id) + + NotificationService.new.pipeline_finished(pipeline, recipients) + end +end diff --git a/app/workers/send_pipeline_notification_worker.rb b/app/workers/send_pipeline_notification_worker.rb deleted file mode 100644 index d4837d815a5..00000000000 --- a/app/workers/send_pipeline_notification_worker.rb +++ /dev/null @@ -1,9 +0,0 @@ -class SendPipelineNotificationWorker - include Sidekiq::Worker - - def perform(pipeline_id, recipients = nil) - pipeline = Ci::Pipeline.find(pipeline_id) - - NotificationService.new.pipeline_finished(pipeline, recipients) - end -end diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb new file mode 100644 index 00000000000..c641d7a7801 --- /dev/null +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -0,0 +1,103 @@ +require 'spec_helper' + +describe PipelineNotificationWorker do + let(:pipeline) do + create(:ci_pipeline, + project: project, + sha: project.commit('master').sha, + user: pusher, + status: status) + end + + let(:project) { create(:project) } + let(:user) { create(:user) } + let(:pusher) { user } + let(:watcher) { pusher } + + describe '#execute' do + before do + reset_delivered_emails! + pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] + end + + shared_examples 'sending emails' do + it 'sends emails' do + perform_enqueued_jobs do + subject.perform(pipeline.id) + end + + expected_receivers = [pusher, watcher].uniq.sort_by(&:email) + actual = ActionMailer::Base.deliveries.sort_by(&:to) + + expect(expected_receivers.size).to eq(actual.size) + + actual.zip(expected_receivers).each do |(email, receiver)| + expect(email.subject).to include(email_subject) + expect(email.to).to eq([receiver.email]) + end + end + end + + context 'with success pipeline' do + let(:status) { 'success' } + let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } + + it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + + context 'with success pipeline notification on' do + let(:watcher) { user } + + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with success pipeline notification off' do + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end + end + + context 'with failed pipeline' do + let(:status) { 'failed' } + let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } + + it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + + context 'with failed pipeline notification on' do + let(:watcher) { user } + + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with failed pipeline notification off' do + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end + end + end +end diff --git a/spec/workers/send_pipeline_notification_worker_spec.rb b/spec/workers/send_pipeline_notification_worker_spec.rb deleted file mode 100644 index 8d358992c7c..00000000000 --- a/spec/workers/send_pipeline_notification_worker_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'spec_helper' - -describe SendPipelineNotificationWorker do - let(:pipeline) do - create(:ci_pipeline, - project: project, - sha: project.commit('master').sha, - user: pusher, - status: status) - end - - let(:project) { create(:project) } - let(:user) { create(:user) } - let(:pusher) { user } - let(:watcher) { pusher } - - describe '#execute' do - before do - reset_delivered_emails! - pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] - end - - shared_examples 'sending emails' do - it 'sends emails' do - perform_enqueued_jobs do - subject.perform(pipeline.id) - end - - expected_receivers = [pusher, watcher].uniq.sort_by(&:email) - actual = ActionMailer::Base.deliveries.sort_by(&:to) - - expect(expected_receivers.size).to eq(actual.size) - - actual.zip(expected_receivers).each do |(email, receiver)| - expect(email.subject).to include(email_subject) - expect(email.to).to eq([receiver.email]) - end - end - end - - context 'with success pipeline' do - let(:status) { 'success' } - let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } - - it_behaves_like 'sending emails' - - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } - - context 'with success pipeline notification on' do - let(:watcher) { user } - - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: true) - end - - it_behaves_like 'sending emails' - end - - context 'with success pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: false) - end - - it_behaves_like 'sending emails' - end - end - end - - context 'with failed pipeline' do - let(:status) { 'failed' } - let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } - - it_behaves_like 'sending emails' - - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } - - context 'with failed pipeline notification on' do - let(:watcher) { user } - - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: true) - end - - it_behaves_like 'sending emails' - end - - context 'with failed pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: false) - end - - it_behaves_like 'sending emails' - end - end - end - end -end -- cgit v1.2.1 From 7e1b9196c413927e4db5e38c40ee944ef6d29884 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 17 Oct 2016 18:13:39 +0800 Subject: Move the entry to 8.13.0, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_17039513 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad5df73203..dd88b348734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Please view this file on the master branch, on stable branches it's out of date. - Change user & group landing page routing from /u/:username to /:username - Prevent running GfmAutocomplete setup for each diff note !6569 - Added documentation for .gitattributes files + - Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - AbstractReferenceFilter caches project_refs on RequestStore when active - Replaced the check sign to arrow in the show build view. !6501 - Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar) @@ -246,7 +247,6 @@ Please view this file on the master branch, on stable branches it's out of date. - Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling) - Fix blame table layout width - Spec testing if issue authors can read issues on private projects - - Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - Fix bug where pagination is still displayed despite all todos marked as done (ClemMakesApps) - Request only the LDAP attributes we need !6187 - Center build stage columns in pipeline overview (ClemMakesApps) -- cgit v1.2.1 From 0f21b1313b853d92b722b32ac25b8ad6a4860a63 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 17 Oct 2016 18:18:16 +0800 Subject: Skip if cannot find pipeline, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342/diffs#note_17038807 --- app/workers/pipeline_notification_worker.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb index f4e9a4cf245..68e72f7382f 100644 --- a/app/workers/pipeline_notification_worker.rb +++ b/app/workers/pipeline_notification_worker.rb @@ -2,7 +2,9 @@ class PipelineNotificationWorker include Sidekiq::Worker def perform(pipeline_id, recipients = nil) - pipeline = Ci::Pipeline.find(pipeline_id) + pipeline = Ci::Pipeline.find_by(id: pipeline_id) + + return unless pipeline NotificationService.new.pipeline_finished(pipeline, recipients) end -- cgit v1.2.1 From 12ef494db812de3790ad5f42152f9b3fdf8c9f3c Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 18 Oct 2016 18:48:02 +0800 Subject: Use Array rather than compact, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_17089690 --- app/models/ci/pipeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 941b01c29e0..d1c68300067 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -120,7 +120,7 @@ module Ci # For now the only user who participates is the user who triggered def participants(_current_user = nil) - [user].compact + Array(user) end def valid_commit_sha -- cgit v1.2.1 From 045c6715330d25adff95304a3de908037c63a163 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 18 Oct 2016 20:02:35 +0800 Subject: Use bcc for pipeline emails because: We use bcc here because we don't want to generate this emails for a thousand times. This could be potentially expensive in a loop, and recipients would contain all project watchers so it could be a lot. --- app/mailers/emails/pipelines.rb | 17 +++++++++++------ app/services/notification_service.rb | 4 +--- spec/models/ci/pipeline_spec.rb | 2 +- spec/support/email_helpers.rb | 8 ++++---- spec/workers/pipeline_notification_worker_spec.rb | 14 ++++++-------- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/app/mailers/emails/pipelines.rb b/app/mailers/emails/pipelines.rb index 601c8b5cd62..9460a6cd2be 100644 --- a/app/mailers/emails/pipelines.rb +++ b/app/mailers/emails/pipelines.rb @@ -1,22 +1,27 @@ module Emails module Pipelines - def pipeline_success_email(pipeline, to) - pipeline_mail(pipeline, to, 'succeeded') + def pipeline_success_email(pipeline, recipients) + pipeline_mail(pipeline, recipients, 'succeeded') end - def pipeline_failed_email(pipeline, to) - pipeline_mail(pipeline, to, 'failed') + def pipeline_failed_email(pipeline, recipients) + pipeline_mail(pipeline, recipients, 'failed') end private - def pipeline_mail(pipeline, to, status) + def pipeline_mail(pipeline, recipients, status) @project = pipeline.project @pipeline = pipeline @merge_request = pipeline.merge_requests.first add_headers - mail(to: to, subject: pipeline_subject(status), skip_premailer: true) do |format| + # We use bcc here because we don't want to generate this emails for a + # thousand times. This could be potentially expensive in a loop, and + # recipients would contain all project watchers so it could be a lot. + mail(bcc: recipients, + subject: pipeline_subject(status), + skip_premailer: true) do |format| format.html { render layout: false } format.text end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index d4976aa8362..d5d69248af7 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -323,9 +323,7 @@ class NotificationService nil, # The acting user, who won't be added to recipients action: pipeline.status).map(&:email) - recipients.each do |to| - mailer.public_send(email_template, pipeline, to).deliver_later - end + mailer.public_send(email_template, pipeline, recipients).deliver_later end protected diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index caf191e11ae..4032029b80b 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -536,7 +536,7 @@ describe Ci::Pipeline, models: true do shared_examples 'sending a notification' do it 'sends an email' do - should_only_email(pipeline.user) + should_only_email(pipeline.user, kind: :bcc) end end diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb index 36f5a2d5975..a946f10f71a 100644 --- a/spec/support/email_helpers.rb +++ b/spec/support/email_helpers.rb @@ -7,8 +7,8 @@ module EmailHelpers ActionMailer::Base.deliveries.clear end - def should_only_email(*users) - recipients = email_recipients + def should_only_email(*users, kind: :to) + recipients = email_recipients(kind: kind) users.each { |user| should_email(user, recipients) } @@ -27,7 +27,7 @@ module EmailHelpers expect(ActionMailer::Base.deliveries).to be_empty end - def email_recipients - ActionMailer::Base.deliveries.flat_map(&:to) + def email_recipients(kind: :to) + ActionMailer::Base.deliveries.flat_map(&kind) end end diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb index c641d7a7801..c334b2057a6 100644 --- a/spec/workers/pipeline_notification_worker_spec.rb +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -26,15 +26,13 @@ describe PipelineNotificationWorker do subject.perform(pipeline.id) end - expected_receivers = [pusher, watcher].uniq.sort_by(&:email) - actual = ActionMailer::Base.deliveries.sort_by(&:to) + emails = ActionMailer::Base.deliveries + actual = emails.flat_map(&:bcc).sort + expected_receivers = [pusher, watcher].map(&:email).uniq.sort - expect(expected_receivers.size).to eq(actual.size) - - actual.zip(expected_receivers).each do |(email, receiver)| - expect(email.subject).to include(email_subject) - expect(email.to).to eq([receiver.email]) - end + expect(actual).to eq(expected_receivers) + expect(emails.size).to eq(1) + expect(emails.last.subject).to include(email_subject) end end -- cgit v1.2.1 From cefc7eb15bd7526a7c40fc0a1ca3534c2a12a0ef Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 18 Oct 2016 20:53:28 +0800 Subject: Fix test for bcc changes --- spec/models/project_services/pipeline_email_service_spec.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/models/project_services/pipeline_email_service_spec.rb b/spec/models/project_services/pipeline_email_service_spec.rb index e2d8eaf6a1f..57baff3354f 100644 --- a/spec/models/project_services/pipeline_email_service_spec.rb +++ b/spec/models/project_services/pipeline_email_service_spec.rb @@ -58,8 +58,7 @@ describe PipelinesEmailService do end it 'sends email' do - sent_to = ActionMailer::Base.deliveries.flat_map(&:to) - expect(sent_to).to contain_exactly(recipient) + should_only_email(double(email: recipient), kind: :bcc) end end @@ -71,7 +70,7 @@ describe PipelinesEmailService do end it 'does not send email' do - expect(ActionMailer::Base.deliveries).to be_empty + should_not_email_anyone end end -- cgit v1.2.1 From a87b6cc3f550dff2fd4189970a3d2456052987a3 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 20 Oct 2016 17:15:38 +0800 Subject: Move CHANGELOG entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b65f5842b4..ae990fcc44c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) - Adds user project membership expired event to clarify why user was removed (Callum Dryden) + - Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 ## 8.13.0 (2016-10-22) @@ -30,7 +31,6 @@ Please view this file on the master branch, on stable branches it's out of date. - The instrumentation for Banzai::Renderer has been restored - Change user & group landing page routing from /u/:username to /:username - Added documentation for .gitattributes files - - Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - Move Pipeline Metrics to separate worker - AbstractReferenceFilter caches project_refs on RequestStore when active - Replaced the check sign to arrow in the show build view. !6501 -- cgit v1.2.1 From 1cdad622aacf9ae7e7d61e575aaa77dddf7ae7b9 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 20 Oct 2016 18:13:45 +0800 Subject: Should send to notification_email instead, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_17146325 --- app/services/notification_service.rb | 2 +- spec/models/project_services/pipeline_email_service_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index d5d69248af7..2cc9a9fd7bf 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -321,7 +321,7 @@ class NotificationService pipeline, pipeline.project, nil, # The acting user, who won't be added to recipients - action: pipeline.status).map(&:email) + action: pipeline.status).map(&:notification_email) mailer.public_send(email_template, pipeline, recipients).deliver_later end diff --git a/spec/models/project_services/pipeline_email_service_spec.rb b/spec/models/project_services/pipeline_email_service_spec.rb index 57baff3354f..4f56bceda44 100644 --- a/spec/models/project_services/pipeline_email_service_spec.rb +++ b/spec/models/project_services/pipeline_email_service_spec.rb @@ -58,7 +58,7 @@ describe PipelinesEmailService do end it 'sends email' do - should_only_email(double(email: recipient), kind: :bcc) + should_only_email(double(notification_email: recipient), kind: :bcc) end end -- cgit v1.2.1 From 6061c9fa3d942c4b1aa466ee8f5f8eb3ae48853e Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 21 Oct 2016 18:16:39 +0800 Subject: Send only to users have :read_build access, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_17193335 --- app/policies/ci/build_policy.rb | 2 +- app/policies/ci/pipeline_policy.rb | 4 + app/services/notification_service.rb | 11 +- spec/workers/pipeline_notification_worker_spec.rb | 132 +++++++++++++--------- 4 files changed, 94 insertions(+), 55 deletions(-) create mode 100644 app/policies/ci/pipeline_policy.rb diff --git a/app/policies/ci/build_policy.rb b/app/policies/ci/build_policy.rb index 2232e231cf8..8b25332b73c 100644 --- a/app/policies/ci/build_policy.rb +++ b/app/policies/ci/build_policy.rb @@ -5,7 +5,7 @@ module Ci # If we can't read build we should also not have that # ability when looking at this in context of commit_status - %w(read create update admin).each do |rule| + %w[read create update admin].each do |rule| cannot! :"#{rule}_commit_status" unless can? :"#{rule}_build" end end diff --git a/app/policies/ci/pipeline_policy.rb b/app/policies/ci/pipeline_policy.rb new file mode 100644 index 00000000000..3d2eef1c50c --- /dev/null +++ b/app/policies/ci/pipeline_policy.rb @@ -0,0 +1,4 @@ +module Ci + class PipelinePolicy < BuildPolicy + end +end diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 2cc9a9fd7bf..f48255b2e6c 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -489,9 +489,14 @@ class NotificationService end def reject_users_without_access(recipients, target) - return recipients unless target.is_a?(Issuable) - - ability = :"read_#{target.to_ability_name}" + ability = case target + when Issuable + :"read_#{target.to_ability_name}" + when Ci::Pipeline + :read_build # We have build trace in pipeline emails + end + + return recipients unless ability recipients.select do |user| user.can?(ability, target) diff --git a/spec/workers/pipeline_notification_worker_spec.rb b/spec/workers/pipeline_notification_worker_spec.rb index c334b2057a6..d487a719680 100644 --- a/spec/workers/pipeline_notification_worker_spec.rb +++ b/spec/workers/pipeline_notification_worker_spec.rb @@ -17,84 +17,114 @@ describe PipelineNotificationWorker do describe '#execute' do before do reset_delivered_emails! - pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] + pipeline.project.team << [pusher, Gitlab::Access::DEVELOPER] end - shared_examples 'sending emails' do - it 'sends emails' do - perform_enqueued_jobs do - subject.perform(pipeline.id) - end + context 'when watcher has developer access' do + before do + pipeline.project.team << [watcher, Gitlab::Access::DEVELOPER] + end - emails = ActionMailer::Base.deliveries - actual = emails.flat_map(&:bcc).sort - expected_receivers = [pusher, watcher].map(&:email).uniq.sort + shared_examples 'sending emails' do + it 'sends emails' do + perform_enqueued_jobs do + subject.perform(pipeline.id) + end - expect(actual).to eq(expected_receivers) - expect(emails.size).to eq(1) - expect(emails.last.subject).to include(email_subject) - end - end + emails = ActionMailer::Base.deliveries + actual = emails.flat_map(&:bcc).sort + expected_receivers = receivers.map(&:email).uniq.sort - context 'with success pipeline' do - let(:status) { 'success' } - let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } + expect(actual).to eq(expected_receivers) + expect(emails.size).to eq(1) + expect(emails.last.subject).to include(email_subject) + end + end - it_behaves_like 'sending emails' + context 'with success pipeline' do + let(:status) { 'success' } + let(:email_subject) { "Pipeline ##{pipeline.id} has succeeded" } + let(:receivers) { [pusher, watcher] } - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } + it_behaves_like 'sending emails' - context 'with success pipeline notification on' do + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } let(:watcher) { user } - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: true) + context 'with success pipeline notification on' do + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: true) + end + + it_behaves_like 'sending emails' end - it_behaves_like 'sending emails' - end + context 'with success pipeline notification off' do + let(:receivers) { [pusher] } + + before do + watcher.global_notification_setting. + update(level: 'custom', success_pipeline: false) + end - context 'with success pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', success_pipeline: false) + it_behaves_like 'sending emails' end + end + + context 'with failed pipeline' do + let(:status) { 'failed' } + let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } it_behaves_like 'sending emails' + + context 'with pipeline from someone else' do + let(:pusher) { create(:user) } + let(:watcher) { user } + + context 'with failed pipeline notification on' do + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) + end + + it_behaves_like 'sending emails' + end + + context 'with failed pipeline notification off' do + let(:receivers) { [pusher] } + + before do + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: false) + end + + it_behaves_like 'sending emails' + end + end end end end - context 'with failed pipeline' do + context 'when watcher has no read_build access' do let(:status) { 'failed' } let(:email_subject) { "Pipeline ##{pipeline.id} has failed" } + let(:watcher) { create(:user) } - it_behaves_like 'sending emails' + before do + pipeline.project.team << [watcher, Gitlab::Access::GUEST] - context 'with pipeline from someone else' do - let(:pusher) { create(:user) } - - context 'with failed pipeline notification on' do - let(:watcher) { user } - - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: true) - end + watcher.global_notification_setting. + update(level: 'custom', failed_pipeline: true) - it_behaves_like 'sending emails' + perform_enqueued_jobs do + subject.perform(pipeline.id) end + end - context 'with failed pipeline notification off' do - before do - watcher.global_notification_setting. - update(level: 'custom', failed_pipeline: false) - end - - it_behaves_like 'sending emails' - end + it 'does not send emails' do + should_only_email(pusher, kind: :bcc) end end end -- cgit v1.2.1 From 2c09d2a13d83494f195fda8620e322dff7738dc5 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 21 Oct 2016 18:22:09 +0800 Subject: Test against notification email --- spec/support/email_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb index a946f10f71a..3e979f2f470 100644 --- a/spec/support/email_helpers.rb +++ b/spec/support/email_helpers.rb @@ -1,6 +1,6 @@ module EmailHelpers def sent_to_user?(user, recipients = email_recipients) - recipients.include?(user.email) + recipients.include?(user.notification_email) end def reset_delivered_emails! -- cgit v1.2.1 From f388fceb4cc64d67b95e45cdbe77c9907803d6f1 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 22 Oct 2016 01:10:47 +0800 Subject: Make sure pusher has the read_build privilege --- spec/models/ci/pipeline_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index ab05150c97e..65e663be411 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -542,6 +542,8 @@ describe Ci::Pipeline, models: true do before do reset_delivered_emails! + project.team << [pipeline.user, Gitlab::Access::DEVELOPER] + perform_enqueued_jobs do pipeline.enqueue pipeline.run -- cgit v1.2.1 From 383b0e9686a5f7a98cd21e6c5a7c9974f9ea3b80 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 22 Oct 2016 01:11:59 +0800 Subject: Well pusher's privilege for read_build could be removed --- app/services/notification_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index f48255b2e6c..6697840cc26 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -323,7 +323,9 @@ class NotificationService nil, # The acting user, who won't be added to recipients action: pipeline.status).map(&:notification_email) - mailer.public_send(email_template, pipeline, recipients).deliver_later + if recipients.any? + mailer.public_send(email_template, pipeline, recipients).deliver_later + end end protected -- cgit v1.2.1 From 02b624740d1153ac242cabada937272dc9925fca Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Mon, 24 Oct 2016 17:39:04 +0800 Subject: include PipelineQueue, feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_17353703 --- app/workers/pipeline_notification_worker.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb index 68e72f7382f..cdb860b6675 100644 --- a/app/workers/pipeline_notification_worker.rb +++ b/app/workers/pipeline_notification_worker.rb @@ -1,5 +1,6 @@ class PipelineNotificationWorker include Sidekiq::Worker + include PipelineQueue def perform(pipeline_id, recipients = nil) pipeline = Ci::Pipeline.find_by(id: pipeline_id) -- cgit v1.2.1 From 6aa615842262f2500270d13aa735634637fd0d67 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 2 Nov 2016 16:19:25 +0800 Subject: Add failed_pipeline and success_pipeline to API doc --- doc/api/notification_settings.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/api/notification_settings.md b/doc/api/notification_settings.md index ff6c9e4931c..b3ceaf296a2 100644 --- a/doc/api/notification_settings.md +++ b/doc/api/notification_settings.md @@ -4,7 +4,7 @@ **Valid notification levels** -The notification levels are defined in the `NotificationSetting::level` model enumeration. Currently, these levels are recognized: +The notification levels are defined in the `NotificationSetting.level` model enumeration. Currently, these levels are recognized: ``` disabled @@ -28,6 +28,8 @@ reopen_merge_request close_merge_request reassign_merge_request merge_merge_request +failed_pipeline +success_pipeline ``` ## Global notification settings -- cgit v1.2.1 From 9176a19e3d858a6d64a2254260febe000474af6d Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 3 Nov 2016 20:41:51 +0800 Subject: Add pipelines to notifications documentation --- doc/workflow/notifications.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/workflow/notifications.md b/doc/workflow/notifications.md index 1b49a5c385f..4824b4e34b9 100644 --- a/doc/workflow/notifications.md +++ b/doc/workflow/notifications.md @@ -66,6 +66,7 @@ Below is the table of events users can be notified of: In all of the below cases, the notification will be sent to: - Participants: - the author and assignee of the issue/merge request + - the author of the pipeline - authors of comments on the issue/merge request - anyone mentioned by `@username` in the issue/merge request title or description - anyone mentioned by `@username` in any of the comments on the issue/merge request @@ -88,6 +89,8 @@ In all of the below cases, the notification will be sent to: | Reopen merge request | | | Merge merge request | | | New comment | The above, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher | +| Failed pipeline | The author of the pipeline and watchers | +| Successful pipeline | The author of the pipeline and watchers | In addition, if the title or description of an Issue or Merge Request is -- cgit v1.2.1 From 3bf3c2c23f348569292ff5f2a6382c12741c5dc3 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 3 Nov 2016 20:46:26 +0800 Subject: Fix CHANGELOG --- CHANGELOG.md | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a2b0de3b0..f2a219fc5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,34 +1,8 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) - - Adds user project membership expired event to clarify why user was removed (Callum Dryden) - - Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - - Trim leading and trailing whitespace on project_path (Linus Thiel) - - Prevent award emoji via notes for issues/MRs authored by user (barthc) - - Adds an optional path parameter to the Commits API to filter commits by path (Luis HGO) - - Fix extra space on Build sidebar on Firefox !7060 - - Fix HipChat notifications rendering (airatshigapov, eisnerd) - - Add hover to trash icon in notes !7008 (blackst0ne) - - Escape ref and path for relative links !6050 (winniehell) - - Simpler arguments passed to named_route on toggle_award_url helper method - - Fix: Backup restore doesn't clear cache - - Use MergeRequestsClosingIssues cache data on Issue#closed_by_merge_requests method - - Fix Sign in page 'Forgot your password?' link overlaps on medium-large screens - - Fix documents and comments on Build API `scope` - - Refactor email, use setter method instead AR callbacks for email attribute (Semyon Pupkov) - -## 8.13.1 (unreleased) - - Fix bug where labels would be assigned to issues that were moved - - Fix error in generating labels - - Fix reply-by-email not working due to queue name mismatch - - Fixed hidden pipeline graph on commit and MR page !6895 - - Expire and build repository cache after project import - - Fix 404 for group pages when GitLab setup uses relative url - - Simpler arguments passed to named_route on toggle_award_url helper method - - Fix unauthorized users dragging on issue boards - - Better handle when no users were selected for adding to group or project. (Linus Thiel) - - Only show register tab if signup enabled. +- Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - Fix Milestone dropdown not stay selected for `Upcoming` and `No Milestone` option !7117 - Backups do not fail anymore when using tar on annex and custom_hooks only. !5814 - Adds user project membership expired event to clarify why user was removed (Callum Dryden) -- cgit v1.2.1 From 00800f4dd38ed6827ff413d8bdfa8112c27cfa03 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Thu, 3 Nov 2016 20:49:48 +0800 Subject: Try to reduce conflicts --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2a219fc5ca..2c193bfb9dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,6 @@ Please view this file on the master branch, on stable branches it's out of date. ## 8.14.0 (2016-11-22) - -- Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - Fix Milestone dropdown not stay selected for `Upcoming` and `No Milestone` option !7117 - Backups do not fail anymore when using tar on annex and custom_hooks only. !5814 - Adds user project membership expired event to clarify why user was removed (Callum Dryden) @@ -22,6 +20,7 @@ Please view this file on the master branch, on stable branches it's out of date. - Hides project activity tabs when features are disabled - Only show one error message for an invalid email !5905 (lycoperdon) - Added guide describing how to upgrade PostgreSQL using Slony +- Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - Fix sidekiq stats in admin area (blackst0ne) - Added label description as tooltip to issue board list title - Created cycle analytics bundle JavaScript file -- cgit v1.2.1 From 17a6f942e0119ee8f1fab5b0476c73fd61a98191 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Fri, 4 Nov 2016 03:01:26 +0800 Subject: Update CHANGELOG --- CHANGELOG.md | 1 - changelogs/unreleased/pipeline-notifications.yml | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/pipeline-notifications.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c193bfb9dc..82ede293a72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,6 @@ Please view this file on the master branch, on stable branches it's out of date. - Hides project activity tabs when features are disabled - Only show one error message for an invalid email !5905 (lycoperdon) - Added guide describing how to upgrade PostgreSQL using Slony -- Add CI notifications. Who triggered a pipeline would receive an email after the pipeline is succeeded or failed. Users could also update notification settings accordingly. !6342 - Fix sidekiq stats in admin area (blackst0ne) - Added label description as tooltip to issue board list title - Created cycle analytics bundle JavaScript file diff --git a/changelogs/unreleased/pipeline-notifications.yml b/changelogs/unreleased/pipeline-notifications.yml new file mode 100644 index 00000000000..e415444020f --- /dev/null +++ b/changelogs/unreleased/pipeline-notifications.yml @@ -0,0 +1,6 @@ +--- +title: Add CI notifications. Who triggered a pipeline would receive an email after + the pipeline is succeeded or failed. Users could also update notification settings + accordingly +merge_request: 6342 +author: Lin Jen-Shin -- cgit v1.2.1 From d03615736f29cb791db6e98ad658a532d6c8d271 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Sat, 5 Nov 2016 02:18:04 +0800 Subject: No need to set author for GitLab members --- changelogs/unreleased/pipeline-notifications.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/unreleased/pipeline-notifications.yml b/changelogs/unreleased/pipeline-notifications.yml index e415444020f..b43060674b2 100644 --- a/changelogs/unreleased/pipeline-notifications.yml +++ b/changelogs/unreleased/pipeline-notifications.yml @@ -3,4 +3,4 @@ title: Add CI notifications. Who triggered a pipeline would receive an email aft the pipeline is succeeded or failed. Users could also update notification settings accordingly merge_request: 6342 -author: Lin Jen-Shin +author: -- cgit v1.2.1 From 62735ef8fafd941ffe34432c0685078a4b4c4744 Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Tue, 8 Nov 2016 23:52:45 +0800 Subject: Add failed_pipeline and success_pipeline to API doc Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_17981448 --- doc/api/notification_settings.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/api/notification_settings.md b/doc/api/notification_settings.md index b3ceaf296a2..aea1c12a392 100644 --- a/doc/api/notification_settings.md +++ b/doc/api/notification_settings.md @@ -79,6 +79,8 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab | `close_merge_request` | boolean | no | Enable/disable this notification | | `reassign_merge_request` | boolean | no | Enable/disable this notification | | `merge_merge_request` | boolean | no | Enable/disable this notification | +| `failed_pipeline` | boolean | no | Enable/disable this notification | +| `success_pipeline` | boolean | no | Enable/disable this notification | Example response: @@ -143,6 +145,8 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab | `close_merge_request` | boolean | no | Enable/disable this notification | | `reassign_merge_request` | boolean | no | Enable/disable this notification | | `merge_merge_request` | boolean | no | Enable/disable this notification | +| `failed_pipeline` | boolean | no | Enable/disable this notification | +| `success_pipeline` | boolean | no | Enable/disable this notification | Example responses: @@ -163,7 +167,9 @@ Example responses: "reopen_merge_request": false, "close_merge_request": false, "reassign_merge_request": false, - "merge_merge_request": false + "merge_merge_request": false, + "failed_pipeline": false, + "success_pipeline": false } } ``` -- cgit v1.2.1 From 3e75e453fb258b3e60f3e9606b5f589006a4654b Mon Sep 17 00:00:00 2001 From: Lin Jen-Shin Date: Wed, 9 Nov 2016 00:29:07 +0800 Subject: Try to cover more cases about receivers of pipeline notifications Feedback: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/6342#note_17981421 --- doc/workflow/notifications.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/workflow/notifications.md b/doc/workflow/notifications.md index 4824b4e34b9..c936e8833c6 100644 --- a/doc/workflow/notifications.md +++ b/doc/workflow/notifications.md @@ -89,8 +89,8 @@ In all of the below cases, the notification will be sent to: | Reopen merge request | | | Merge merge request | | | New comment | The above, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher | -| Failed pipeline | The author of the pipeline and watchers | -| Successful pipeline | The author of the pipeline and watchers | +| Failed pipeline | The above, plus the author of the pipeline | +| Successful pipeline | The above, plus the author of the pipeline | In addition, if the title or description of an Issue or Merge Request is -- cgit v1.2.1