Add a new pipeline email service. TODO: email templates and tests
This commit is contained in:
parent
7bbb523b23
commit
34cbc51e23
|
@ -0,0 +1,38 @@
|
|||
module Emails
|
||||
module Pipelines
|
||||
def pipeline_succeeded_email(params, to)
|
||||
pipeline_mail(params, to, 'succeeded') # TODO: missing template
|
||||
end
|
||||
|
||||
def pipeline_failed_email(params, to)
|
||||
pipeline_mail(params, to, 'failed') # TODO: missing template
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pipeline_mail(params, to, status)
|
||||
@params = params
|
||||
add_headers
|
||||
|
||||
mail(to: to, subject: pipeline_subject('failed'))
|
||||
end
|
||||
|
||||
def add_headers
|
||||
@project = @params.project # `add_project_headers` needs this
|
||||
add_project_headers
|
||||
add_pipeline_headers(@params.pipeline)
|
||||
end
|
||||
|
||||
def add_pipeline_headers(pipeline)
|
||||
headers['X-GitLab-Pipeline-Id'] = pipeline.id
|
||||
headers['X-GitLab-Pipeline-Ref'] = pipeline.ref
|
||||
headers['X-GitLab-Pipeline-Status'] = pipeline.status
|
||||
end
|
||||
|
||||
def pipeline_subject(status)
|
||||
subject(
|
||||
"Pipeline #{status} for #{@params.project.name}",
|
||||
@params.pipeline.short_sha)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,7 @@ class Notify < BaseMailer
|
|||
include Emails::Projects
|
||||
include Emails::Profile
|
||||
include Emails::Builds
|
||||
include Emails::Pipelines
|
||||
include Emails::Members
|
||||
|
||||
add_template_helper MergeRequestsHelper
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
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? }
|
||||
|
||||
def initialize_properties
|
||||
self.properties ||= { notify_only_broken_builds: true }
|
||||
end
|
||||
|
||||
def title
|
||||
'Pipelines emails'
|
||||
end
|
||||
|
||||
def description
|
||||
'Email the pipelines status to a list of recipients.'
|
||||
end
|
||||
|
||||
def to_param
|
||||
'pipelines_email'
|
||||
end
|
||||
|
||||
def supported_events
|
||||
%w[pipeline]
|
||||
end
|
||||
|
||||
def execute(data, force = false)
|
||||
return unless supported_events.include?(data[:object_kind])
|
||||
return unless force || should_build_be_notified?(data)
|
||||
|
||||
all_recipients = retrieve_recipients(data)
|
||||
|
||||
return unless all_recipients.any?
|
||||
|
||||
PipelineEmailWorker.perform_async(data, all_recipients)
|
||||
end
|
||||
|
||||
def can_test?
|
||||
project.pipelines.count > 0
|
||||
end
|
||||
|
||||
def disabled_title
|
||||
'Please setup a pipeline on your repository.'
|
||||
end
|
||||
|
||||
def test_data(project, user)
|
||||
data = Gitlab::DataBuilder::Pipeline.build(project.pipelines.last)
|
||||
data[:user] = user.hook_attrs
|
||||
data
|
||||
end
|
||||
|
||||
def fields
|
||||
[
|
||||
{ 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' },
|
||||
]
|
||||
end
|
||||
|
||||
def test(data)
|
||||
result = execute(data, true)
|
||||
|
||||
{ success: true, result: result }
|
||||
rescue StandardError => error
|
||||
{ success: false, result: error }
|
||||
end
|
||||
|
||||
def should_build_be_notified?(data)
|
||||
case data[:object_attributes][:status]
|
||||
when 'success'
|
||||
!notify_only_broken_pipelines?
|
||||
else
|
||||
false
|
||||
end
|
||||
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]
|
||||
else
|
||||
all_recipients
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,39 @@
|
|||
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
|
Loading…
Reference in New Issue