diff --git a/app/mailers/emails/pipelines.rb b/app/mailers/emails/pipelines.rb index 643b947a049a6e9a3fa6537e6f2428ff3e1dea5e..e132105807ab959a0de9cc0102563f91d170c494 100644 --- a/app/mailers/emails/pipelines.rb +++ b/app/mailers/emails/pipelines.rb @@ -1,18 +1,18 @@ module Emails module Pipelines - def pipeline_succeeded_email(params, to) - pipeline_mail(params, to, 'succeeded') + def pipeline_success_email(pipeline, to) + pipeline_mail(pipeline, to, 'succeeded') end - def pipeline_failed_email(params, to) - pipeline_mail(params, to, 'failed') + def pipeline_failed_email(pipeline, to) + pipeline_mail(pipeline, to, 'failed') end private - def pipeline_mail(params, to, status) - @project = params.project - @pipeline = params.pipeline + def pipeline_mail(pipeline, to, status) + @project = pipeline.project + @pipeline = pipeline add_headers mail(to: to, subject: pipeline_subject(status)) diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index 0b1df9f429423b6940ff8e18257a7efa9c2601a4..b9c46202e5e3cf6b3188c606d75e9e883e4466b4 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -62,6 +62,10 @@ module Ci after_transition do |pipeline, transition| pipeline.execute_hooks unless transition.loopback? 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 @@ -90,6 +94,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 121b598b8f3839f67a9963bc31dfb3ad9b79f597..43fc218de2b5d458ab85add171d173ab8d2c0880 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/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb index 1f852445c1c3b711de9c048c24bd34942a2e3fcd..7ce0aa7c16e0df21e06aecdc6fa72166d4601cf0 100644 --- a/app/models/project_services/pipelines_email_service.rb +++ b/app/models/project_services/pipelines_email_service.rb @@ -34,7 +34,8 @@ class PipelinesEmailService < Service return unless all_recipients.any? - PipelineEmailWorker.perform_async(data, all_recipients) + pipeline = Ci::Pipeline.find(data[:object_attributes][:id]) + Ci::SendPipelineNotificationService.new(pipeline).execute(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 new file mode 100644 index 0000000000000000000000000000000000000000..d330fa1a73c2324634d8de82cbbd443c7f4c222e --- /dev/null +++ b/app/services/ci/send_pipeline_notification_service.rb @@ -0,0 +1,13 @@ +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/services/notification_service.rb b/app/services/notification_service.rb index 6139ed56e25559c4f499e0fa1b162bbf97ed3e32..de60c49ba845999580f81e908972d6f50217b402 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -311,6 +311,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, + pipeline.user, + action: pipeline.status) + + recipients.each do |to| + Notify.public_send(email_template, pipeline, to).deliver_later + end + end + protected # Get project/group users with CUSTOM notification level @@ -613,6 +629,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 diff --git a/app/views/notify/pipeline_succeeded_email.html.haml b/app/views/notify/pipeline_success_email.html.haml similarity index 100% rename from app/views/notify/pipeline_succeeded_email.html.haml rename to app/views/notify/pipeline_success_email.html.haml diff --git a/app/views/notify/pipeline_succeeded_email.text.erb b/app/views/notify/pipeline_success_email.text.erb similarity index 100% rename from app/views/notify/pipeline_succeeded_email.text.erb rename to app/views/notify/pipeline_success_email.text.erb diff --git a/app/workers/pipeline_email_worker.rb b/app/workers/pipeline_email_worker.rb deleted file mode 100644 index 2160207c9014880497940b038d936589a23cf919..0000000000000000000000000000000000000000 --- a/app/workers/pipeline_email_worker.rb +++ /dev/null @@ -1,39 +0,0 @@ -class PipelineEmailWorker - include Sidekiq::Worker - - ParamsStruct = Struct.new(:pipeline, :project, :email_template) - class Params < ParamsStruct - def initialize(pipeline_id) - self.pipeline = Ci::Pipeline.find(pipeline_id) - self.project = pipeline.project - self.email_template = case pipeline.status - when 'success' - :pipeline_succeeded_email - when 'failed' - :pipeline_failed_email - end - end - end - - def perform(data, recipients) - params = Params.new(data['object_attributes']['id']) - - return unless params.email_template - - recipients.each do |to| - deliver(params, to) do - Notify.public_send(params.email_template, params, to).deliver_now - end - end - end - - private - - def deliver(params, to) - yield - # These are input errors and won't be corrected even if Sidekiq retries - rescue Net::SMTPFatalError, Net::SMTPSyntaxError => e - project_name = params.project.path_with_namespace - logger.info("Failed to send email for #{project_name} to #{to}: #{e}") - end -end