Commit d27095a3 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Add pipeline_events to Slack service:

Also add Service#event_names so that we don't have to hard code all
event names in ServiceParams. Note that I don't know why we want to
call plural on issue_event and merge_request_event so that we still
need to hard code them for issues_event and merge_requests_event.
See app/helpers/services_helper.rb for those special rules.
parent 4a431a26
......@@ -7,11 +7,12 @@ module ServiceParams
:build_key, :server, :teamcity_url, :drone_url, :build_type,
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
:colorize_messages, :channels,
:push_events, :issues_events, :merge_requests_events, :tag_push_events,
:note_events, :build_events, :wiki_page_events,
:notify_only_broken_builds, :add_pusher,
:send_from_committer_email, :disable_diffs, :external_wiki_url,
:notify, :color,
# See app/helpers/services_helper.rb
# for why we need issues_events and merge_requests_events.
:issues_events, :merge_requests_events,
:notify_only_broken_builds, :notify_only_broken_pipelines,
:add_pusher, :send_from_committer_email, :disable_diffs,
:external_wiki_url, :notify, :color,
:server_host, :server_port, :default_irc_uri, :enable_ssl_verification,
:jira_issue_transition_id]
......@@ -19,9 +20,7 @@ module ServiceParams
FILTER_BLANK_PARAMS = [:password]
def service_params
dynamic_params = []
dynamic_params.concat(@service.event_channel_names)
dynamic_params = @service.event_channel_names + @service.event_names
service_params = params.permit(:id, service: ALLOWED_PARAMS + dynamic_params)
if service_params[:service].is_a?(Hash)
......
class SlackService < Service
prop_accessor :webhook, :username, :channel
boolean_accessor :notify_only_broken_builds
boolean_accessor :notify_only_broken_builds, :notify_only_broken_pipelines
validates :webhook, presence: true, url: true, if: :activated?
def initialize_properties
......@@ -10,6 +10,7 @@ class SlackService < Service
if properties.nil?
self.properties = {}
self.notify_only_broken_builds = true
self.notify_only_broken_pipelines = true
end
end
......@@ -38,13 +39,14 @@ class SlackService < Service
{ type: 'text', name: 'username', placeholder: 'username' },
{ type: 'text', name: 'channel', placeholder: "#general" },
{ type: 'checkbox', name: 'notify_only_broken_builds' },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
]
default_fields + build_event_channels
end
def supported_events
%w(push issue merge_request note tag_push build wiki_page)
%w(push issue merge_request note tag_push build pipeline wiki_page)
end
def execute(data)
......@@ -74,6 +76,8 @@ class SlackService < Service
NoteMessage.new(data)
when "build"
BuildMessage.new(data) if should_build_be_notified?(data)
when "pipeline"
PipelineMessage.new(data) if should_pipeline_be_notified?(data)
when "wiki_page"
WikiPageMessage.new(data)
end
......@@ -142,6 +146,17 @@ class SlackService < Service
false
end
end
def should_pipeline_be_notified?(data)
case data[:object_attributes][:status]
when 'success'
!notify_only_broken_builds?
when 'failed'
true
else
false
end
end
end
require "slack_service/issue_message"
......@@ -149,4 +164,5 @@ require "slack_service/push_message"
require "slack_service/merge_message"
require "slack_service/note_message"
require "slack_service/build_message"
require "slack_service/pipeline_message"
require "slack_service/wiki_page_message"
class SlackService
class PipelineMessage < BaseMessage
attr_reader :sha, :ref_type, :ref, :status, :project_name, :project_url,
:user_name, :duration, :pipeline_id
def initialize(data)
@sha = data[:sha]
@ref_type = data[:tag] ? 'tag' : 'branch'
@ref = data[:ref]
@status = data[:status]
@project_name = data[:project][:path_with_namespace]
@project_url = data[:project][:web_url]
@user_name = data[:commit] && data[:commit][:author_name]
@duration = data[:object_attributes][:duration]
@pipeline_id = data[:object_attributes][:id]
end
def pretext
''
end
def fallback
format(message)
end
def attachments
[{ text: format(message), color: attachment_color }]
end
private
def message
"#{project_link}: Pipeline #{pipeline_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status} in #{duration} #{'second'.pluralize(duration)}"
end
def format(string)
Slack::Notifier::LinkFormatter.format(string)
end
def humanized_status
case status
when 'success'
'passed'
else
status
end
end
def attachment_color
if status == 'success'
'good'
else
'danger'
end
end
def branch_url
"#{project_url}/commits/#{ref}"
end
def branch_link
"[#{ref}](#{branch_url})"
end
def project_link
"[#{project_name}](#{project_url})"
end
def pipeline_url
"#{project_url}/pipelines/#{pipeline_id}"
end
def pipeline_link
"[#{Commit.truncate_sha(sha)}](#{pipeline_url})"
end
end
end
......@@ -87,6 +87,10 @@ class Service < ActiveRecord::Base
[]
end
def event_names
supported_events.map { |event| "#{event}_events" }
end
def event_field(event)
nil
end
......
......@@ -28,7 +28,8 @@ module Gitlab
stage: first_pending_build.try(:stage),
stages: config_processor.try(:stages),
created_at: pipeline.created_at,
finished_at: pipeline.finished_at
finished_at: pipeline.finished_at,
duration: pipeline.duration
}
end
......
require 'spec_helper'
describe SlackService::PipelineMessage do
subject { SlackService::PipelineMessage.new(args) }
let(:args) do
{
sha: '97de212e80737a608d939f648d959671fb0a0142',
tag: false,
ref: 'develop',
status: status,
project: { path_with_namespace: 'project_name',
web_url: 'somewhere.com' },
commit: { author_name: 'hacker' },
object_attributes: { duration: duration,
id: 123 }
}
end
context 'succeeded' do
let(:status) { 'success' }
let(:color) { 'good' }
let(:duration) { 10 }
it 'returns a message with information about succeeded build' do
message = '<somewhere.com|project_name>: Pipeline <somewhere.com/pipelines/123|97de212e> of <somewhere.com/commits/develop|develop> branch by hacker passed in 10 seconds'
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
end
context 'failed' do
let(:status) { 'failed' }
let(:color) { 'danger' }
let(:duration) { 10 }
it 'returns a message with information about failed build' do
message = '<somewhere.com|project_name>: Pipeline <somewhere.com/pipelines/123|97de212e> of <somewhere.com/commits/develop|develop> branch by hacker failed in 10 seconds'
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
end
describe '#seconds_name' do
let(:status) { 'failed' }
let(:color) { 'danger' }
let(:duration) { 1 }
it 'returns seconds as singular when there is only one' do
message = '<somewhere.com|project_name>: Pipeline <somewhere.com/pipelines/123|97de212e> of <somewhere.com/commits/develop|develop> branch by hacker failed in 1 second'
expect(subject.pretext).to be_empty
expect(subject.fallback).to eq(message)
expect(subject.attachments).to eq([text: message, color: color])
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment