summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2016-07-30 00:59:54 +0800
committerLin Jen-Shin <godfat@godfat.org>2016-07-30 00:59:54 +0800
commitd27095a36a5d8c83182771d7548a13fcc9188e3c (patch)
tree74e08e2d59addd14f89892d70581e822b9d8bfbb
parent4a431a266f8773c54a0f47292d4b9470a7d2acd3 (diff)
downloadgitlab-ce-d27095a36a5d8c83182771d7548a13fcc9188e3c.tar.gz
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.
-rw-r--r--app/controllers/concerns/service_params.rb15
-rw-r--r--app/models/project_services/slack_service.rb20
-rw-r--r--app/models/project_services/slack_service/pipeline_message.rb77
-rw-r--r--app/models/service.rb4
-rw-r--r--lib/gitlab/data_builder/pipeline_data_builder.rb3
-rw-r--r--spec/models/project_services/slack_service/pipeline_message_spec.rb58
6 files changed, 166 insertions, 11 deletions
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
index 471d15af913..58877c5ad5d 100644
--- a/app/controllers/concerns/service_params.rb
+++ b/app/controllers/concerns/service_params.rb
@@ -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)
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index abbc780dc1a..6584646e998 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -1,6 +1,6 @@
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"
diff --git a/app/models/project_services/slack_service/pipeline_message.rb b/app/models/project_services/slack_service/pipeline_message.rb
new file mode 100644
index 00000000000..3d12af3fa7e
--- /dev/null
+++ b/app/models/project_services/slack_service/pipeline_message.rb
@@ -0,0 +1,77 @@
+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
diff --git a/app/models/service.rb b/app/models/service.rb
index 4a63abb2724..e4cd44f542a 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -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
diff --git a/lib/gitlab/data_builder/pipeline_data_builder.rb b/lib/gitlab/data_builder/pipeline_data_builder.rb
index fed9bd92ba4..46f8a1857b4 100644
--- a/lib/gitlab/data_builder/pipeline_data_builder.rb
+++ b/lib/gitlab/data_builder/pipeline_data_builder.rb
@@ -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
diff --git a/spec/models/project_services/slack_service/pipeline_message_spec.rb b/spec/models/project_services/slack_service/pipeline_message_spec.rb
new file mode 100644
index 00000000000..2960a200e9d
--- /dev/null
+++ b/spec/models/project_services/slack_service/pipeline_message_spec.rb
@@ -0,0 +1,58 @@
+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