summaryrefslogtreecommitdiff
path: root/app/models/project_services
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/project_services')
-rw-r--r--app/models/project_services/builds_email_service.rb3
-rw-r--r--app/models/project_services/campfire_service.rb51
-rw-r--r--app/models/project_services/custom_issue_tracker_service.rb4
-rw-r--r--app/models/project_services/hipchat_service.rb2
-rw-r--r--app/models/project_services/pivotaltracker_service.rb31
-rw-r--r--app/models/project_services/slack_service.rb72
-rw-r--r--app/models/project_services/slack_service/build_message.rb4
-rw-r--r--app/models/project_services/slack_service/pipeline_message.rb79
8 files changed, 206 insertions, 40 deletions
diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb
index 5e166471077..fa66e5864b8 100644
--- a/app/models/project_services/builds_email_service.rb
+++ b/app/models/project_services/builds_email_service.rb
@@ -51,8 +51,7 @@ class BuildsEmailService < Service
end
def test_data(project = nil, user = nil)
- build = project.builds.last
- Gitlab::BuildDataBuilder.build(build)
+ Gitlab::DataBuilder::Build.build(project.builds.last)
end
def fields
diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb
index 511b2eac792..5af93860d09 100644
--- a/app/models/project_services/campfire_service.rb
+++ b/app/models/project_services/campfire_service.rb
@@ -1,4 +1,6 @@
class CampfireService < Service
+ include HTTParty
+
prop_accessor :token, :subdomain, :room
validates :token, presence: true, if: :activated?
@@ -29,18 +31,53 @@ class CampfireService < Service
def execute(data)
return unless supported_events.include?(data[:object_kind])
- room = gate.find_room_by_name(self.room)
- return true unless room
-
+ self.class.base_uri base_uri
message = build_message(data)
-
- room.speak(message)
+ speak(self.room, message, auth)
end
private
- def gate
- @gate ||= Tinder::Campfire.new(subdomain, token: token)
+ def base_uri
+ @base_uri ||= "https://#{subdomain}.campfirenow.com"
+ end
+
+ def auth
+ # use a dummy password, as explained in the Campfire API doc:
+ # https://github.com/basecamp/campfire-api#authentication
+ @auth ||= {
+ basic_auth: {
+ username: token,
+ password: 'X'
+ }
+ }
+ end
+
+ # Post a message into a room, returns the message Hash in case of success.
+ # Returns nil otherwise.
+ # https://github.com/basecamp/campfire-api/blob/master/sections/messages.md#create-message
+ def speak(room_name, message, auth)
+ room = rooms(auth).find { |r| r["name"] == room_name }
+ return nil unless room
+
+ path = "/room/#{room["id"]}/speak.json"
+ body = {
+ body: {
+ message: {
+ type: 'TextMessage',
+ body: message
+ }
+ }
+ }
+ res = self.class.post(path, auth.merge(body))
+ res.code == 201 ? res : nil
+ end
+
+ # Returns a list of rooms, or [].
+ # https://github.com/basecamp/campfire-api/blob/master/sections/rooms.md#get-rooms
+ def rooms(auth)
+ res = self.class.get("/rooms.json", auth)
+ res.code == 200 ? res["rooms"] : []
end
def build_message(push)
diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb
index 63a5ed14484..d9fba3d4a41 100644
--- a/app/models/project_services/custom_issue_tracker_service.rb
+++ b/app/models/project_services/custom_issue_tracker_service.rb
@@ -9,6 +9,10 @@ class CustomIssueTrackerService < IssueTrackerService
end
end
+ def title=(value)
+ self.properties['title'] = value if self.properties
+ end
+
def description
if self.properties && self.properties['description'].present?
self.properties['description']
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index d7c986c1a91..afebd3b6a12 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -39,7 +39,7 @@ class HipchatService < Service
end
def supported_events
- %w(push issue merge_request note tag_push build)
+ %w(push issue confidential_issue merge_request note tag_push build)
end
def execute(data)
diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb
index ad19b7795da..5301f9fa0ff 100644
--- a/app/models/project_services/pivotaltracker_service.rb
+++ b/app/models/project_services/pivotaltracker_service.rb
@@ -1,7 +1,9 @@
class PivotaltrackerService < Service
include HTTParty
- prop_accessor :token
+ API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'
+
+ prop_accessor :token, :restrict_to_branch
validates :token, presence: true, if: :activated?
def title
@@ -18,7 +20,17 @@ class PivotaltrackerService < Service
def fields
[
- { type: 'text', name: 'token', placeholder: '' }
+ {
+ type: 'text',
+ name: 'token',
+ placeholder: 'Pivotal Tracker API token.'
+ },
+ {
+ type: 'text',
+ name: 'restrict_to_branch',
+ placeholder: 'Comma-separated list of branches which will be ' \
+ 'automatically inspected. Leave blank to include all branches.'
+ }
]
end
@@ -28,8 +40,8 @@ class PivotaltrackerService < Service
def execute(data)
return unless supported_events.include?(data[:object_kind])
+ return unless allowed_branch?(data[:ref])
- url = 'https://www.pivotaltracker.com/services/v5/source_commits'
data[:commits].each do |commit|
message = {
'source_commit' => {
@@ -40,7 +52,7 @@ class PivotaltrackerService < Service
}
}
PivotaltrackerService.post(
- url,
+ API_ENDPOINT,
body: message.to_json,
headers: {
'Content-Type' => 'application/json',
@@ -49,4 +61,15 @@ class PivotaltrackerService < Service
)
end
end
+
+ private
+
+ def allowed_branch?(ref)
+ return true unless ref.present? && restrict_to_branch.present?
+
+ branch = Gitlab::Git.ref_name(ref)
+ allowed_branches = restrict_to_branch.split(',').map(&:strip)
+
+ branch.present? && allowed_branches.include?(branch)
+ end
end
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index abbc780dc1a..e1b937817f4 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,15 @@ 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 confidential_issue merge_request note tag_push
+ build pipeline wiki_page]
end
def execute(data)
@@ -62,32 +65,22 @@ class SlackService < Service
# 'close' action. Ignore update events for now to prevent duplicate
# messages from arriving.
- message = \
- case object_kind
- when "push", "tag_push"
- PushMessage.new(data)
- when "issue"
- IssueMessage.new(data) unless is_update?(data)
- when "merge_request"
- MergeMessage.new(data) unless is_update?(data)
- when "note"
- NoteMessage.new(data)
- when "build"
- BuildMessage.new(data) if should_build_be_notified?(data)
- when "wiki_page"
- WikiPageMessage.new(data)
- end
-
- opt = {}
-
- event_channel = get_channel_field(object_kind) || channel
-
- opt[:channel] = event_channel if event_channel
- opt[:username] = username if username
+ message = get_message(object_kind, data)
if message
+ opt = {}
+
+ event_channel = get_channel_field(object_kind) || channel
+
+ opt[:channel] = event_channel if event_channel
+ opt[:username] = username if username
+
notifier = Slack::Notifier.new(webhook, opt)
notifier.ping(message.pretext, attachments: message.attachments, fallback: message.fallback)
+
+ true
+ else
+ false
end
end
@@ -105,6 +98,25 @@ class SlackService < Service
private
+ def get_message(object_kind, data)
+ case object_kind
+ when "push", "tag_push"
+ PushMessage.new(data)
+ when "issue"
+ IssueMessage.new(data) unless is_update?(data)
+ when "merge_request"
+ MergeMessage.new(data) unless is_update?(data)
+ when "note"
+ 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
+ end
+
def get_channel_field(event)
field_name = event_channel_name(event)
self.public_send(field_name)
@@ -142,6 +154,17 @@ class SlackService < Service
false
end
end
+
+ def should_pipeline_be_notified?(data)
+ case data[:object_attributes][:status]
+ when 'success'
+ !notify_only_broken_pipelines?
+ when 'failed'
+ true
+ else
+ false
+ end
+ end
end
require "slack_service/issue_message"
@@ -149,4 +172,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/build_message.rb b/app/models/project_services/slack_service/build_message.rb
index 69c21b3fc38..0fca4267bad 100644
--- a/app/models/project_services/slack_service/build_message.rb
+++ b/app/models/project_services/slack_service/build_message.rb
@@ -9,7 +9,7 @@ class SlackService
attr_reader :user_name
attr_reader :duration
- def initialize(params, commit = true)
+ def initialize(params)
@sha = params[:sha]
@ref_type = params[:tag] ? 'tag' : 'branch'
@ref = params[:ref]
@@ -36,7 +36,7 @@ class SlackService
def message
"#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status} in #{duration} #{'second'.pluralize(duration)}"
- end
+ end
def format(string)
Slack::Notifier::LinkFormatter.format(string)
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..f06b3562965
--- /dev/null
+++ b/app/models/project_services/slack_service/pipeline_message.rb
@@ -0,0 +1,79 @@
+class SlackService
+ class PipelineMessage < BaseMessage
+ attr_reader :sha, :ref_type, :ref, :status, :project_name, :project_url,
+ :user_name, :duration, :pipeline_id
+
+ def initialize(data)
+ pipeline_attributes = data[:object_attributes]
+ @sha = pipeline_attributes[:sha]
+ @ref_type = pipeline_attributes[:tag] ? 'tag' : 'branch'
+ @ref = pipeline_attributes[:ref]
+ @status = pipeline_attributes[:status]
+ @duration = pipeline_attributes[:duration]
+ @pipeline_id = pipeline_attributes[:id]
+
+ @project_name = data[:project][:path_with_namespace]
+ @project_url = data[:project][:web_url]
+ @user_name = data[:commit] && data[:commit][:author_name]
+ 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