summaryrefslogtreecommitdiff
path: root/app/models/project_services
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dzaporozhets@gitlab.com>2015-03-04 21:57:17 +0000
committerDmitriy Zaporozhets <dzaporozhets@gitlab.com>2015-03-04 21:57:17 +0000
commit63178a9509f72eb7adf1c73c2fc6dc1ec0a1ea42 (patch)
tree5a925b161c84097e804698aed37de12d1bae12df /app/models/project_services
parent00778c073130789e9f65e02e6fa6e8b987506c9e (diff)
parentfc6160816119504e1cea0954453cd557231341a1 (diff)
downloadgitlab-ce-63178a9509f72eb7adf1c73c2fc6dc1ec0a1ea42.tar.gz
Merge branch 'add-more-slack-notifications' into 'master'
Add more Slack notifications for issue and merge request events From https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/237 by Stan Hu. See merge request !1556
Diffstat (limited to 'app/models/project_services')
-rw-r--r--app/models/project_services/asana_service.rb18
-rw-r--r--app/models/project_services/assembla_service.rb14
-rw-r--r--app/models/project_services/bamboo_service.rb12
-rw-r--r--app/models/project_services/buildbox_service.rb10
-rw-r--r--app/models/project_services/campfire_service.rb14
-rw-r--r--app/models/project_services/ci_service.rb8
-rw-r--r--app/models/project_services/emails_on_push_service.rb14
-rw-r--r--app/models/project_services/flowdock_service.rb18
-rw-r--r--app/models/project_services/gemnasium_service.rb18
-rw-r--r--app/models/project_services/gitlab_ci_service.rb16
-rw-r--r--app/models/project_services/gitlab_issue_tracker_service.rb4
-rw-r--r--app/models/project_services/hipchat_service.rb14
-rw-r--r--app/models/project_services/issue_tracker_service.rb10
-rw-r--r--app/models/project_services/jira_service.rb4
-rw-r--r--app/models/project_services/pivotaltracker_service.rb14
-rw-r--r--app/models/project_services/pushover_service.rb30
-rw-r--r--app/models/project_services/redmine_service.rb4
-rw-r--r--app/models/project_services/slack_message.rb110
-rw-r--r--app/models/project_services/slack_service.rb45
-rw-r--r--app/models/project_services/slack_service/base_message.rb31
-rw-r--r--app/models/project_services/slack_service/issue_message.rb56
-rw-r--r--app/models/project_services/slack_service/merge_message.rb54
-rw-r--r--app/models/project_services/slack_service/push_message.rb108
-rw-r--r--app/models/project_services/teamcity_service.rb14
24 files changed, 488 insertions, 152 deletions
diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb
index 66b72572b9c..8ad1ad6267a 100644
--- a/app/models/project_services/asana_service.rb
+++ b/app/models/project_services/asana_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
require 'asana'
@@ -61,13 +65,19 @@ automatically inspected. Leave blank to include all branches.'
]
end
- def execute(push)
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
Asana.configure do |client|
client.api_key = api_key
end
- user = push[:user_name]
- branch = push[:ref].gsub('refs/heads/', '')
+ user = data[:user_name]
+ branch = data[:ref].gsub('refs/heads/', '')
branch_restriction = restrict_to_branch.to_s
@@ -79,7 +89,7 @@ automatically inspected. Leave blank to include all branches.'
project_name = project.name_with_namespace
push_msg = user + ' pushed to branch ' + branch + ' of ' + project_name
- push[:commits].each do |commit|
+ data[:commits].each do |commit|
check_commit(' ( ' + commit[:url] + ' ): ' + commit[:message], push_msg)
end
end
diff --git a/app/models/project_services/assembla_service.rb b/app/models/project_services/assembla_service.rb
index cf7598f35eb..02aa7c972e7 100644
--- a/app/models/project_services/assembla_service.rb
+++ b/app/models/project_services/assembla_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class AssemblaService < Service
@@ -38,8 +42,14 @@ class AssemblaService < Service
]
end
- def execute(push)
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
url = "https://atlas.assembla.com/spaces/#{subdomain}/github_tool?secret_key=#{token}"
- AssemblaService.post(url, body: { payload: push }.to_json, headers: { 'Content-Type' => 'application/json' })
+ AssemblaService.post(url, body: { payload: data }.to_json, headers: { 'Content-Type' => 'application/json' })
end
end
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index df68803152f..6c6d74c615e 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class BambooService < CiService
@@ -69,6 +73,10 @@ class BambooService < CiService
]
end
+ def supported_events
+ %w(push)
+ end
+
def build_info(sha)
url = URI.parse("#{bamboo_url}/rest/api/latest/result?label=#{sha}")
@@ -118,7 +126,9 @@ class BambooService < CiService
end
end
- def execute(_data)
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
# Bamboo requires a GET and does not take any data.
self.class.get("#{bamboo_url}/updateAndBuild.action?buildKey=#{build_key}",
verify: false)
diff --git a/app/models/project_services/buildbox_service.rb b/app/models/project_services/buildbox_service.rb
index 058c890ae45..96428c91711 100644
--- a/app/models/project_services/buildbox_service.rb
+++ b/app/models/project_services/buildbox_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
require "addressable/uri"
@@ -32,7 +36,13 @@ class BuildboxService < CiService
hook.save
end
+ def supported_events
+ %w(push)
+ end
+
def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
service_hook.execute(data)
end
diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb
index 14b6b87a0b7..2f86fbe7a03 100644
--- a/app/models/project_services/campfire_service.rb
+++ b/app/models/project_services/campfire_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class CampfireService < Service
@@ -37,11 +41,17 @@ class CampfireService < Service
]
end
- def execute(push_data)
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
room = gate.find_room_by_name(self.room)
return true unless room
- message = build_message(push_data)
+ message = build_message(data)
room.speak(message)
end
diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb
index 5a26c25b3c3..646783c8733 100644
--- a/app/models/project_services/ci_service.rb
+++ b/app/models/project_services/ci_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean
+# issues_events :boolean
+# merge_requests_events :boolean
+# tag_push_events :boolean
#
# Base class for CI services
@@ -21,6 +25,10 @@ class CiService < Service
:ci
end
+ def supported_events
+ %w(push)
+ end
+
# Return complete url to build page
#
# Ex.
diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb
index 86693ad0c7e..21041e08a20 100644
--- a/app/models/project_services/emails_on_push_service.rb
+++ b/app/models/project_services/emails_on_push_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean
+# issues_events :boolean
+# merge_requests_events :boolean
+# tag_push_events :boolean
#
class EmailsOnPushService < Service
@@ -29,8 +33,14 @@ class EmailsOnPushService < Service
'emails_on_push'
end
- def execute(push_data)
- EmailsOnPushWorker.perform_async(project_id, recipients, push_data)
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
+ EmailsOnPushWorker.perform_async(project_id, recipients, data)
end
def fields
diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb
index 13e2dfceb1a..443dca72a8c 100644
--- a/app/models/project_services/flowdock_service.rb
+++ b/app/models/project_services/flowdock_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean
+# issues_events :boolean
+# merge_requests_events :boolean
+# tag_push_events :boolean
#
require "flowdock-git-hook"
@@ -37,11 +41,17 @@ class FlowdockService < Service
]
end
- def execute(push_data)
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
Flowdock::Git.post(
- push_data[:ref],
- push_data[:before],
- push_data[:after],
+ data[:ref],
+ data[:before],
+ data[:after],
token: token,
repo: project.repository.path_to_repo,
repo_url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}",
diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb
index a2c87ae88f1..41eedc215d5 100644
--- a/app/models/project_services/gemnasium_service.rb
+++ b/app/models/project_services/gemnasium_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean
+# issues_events :boolean
+# merge_requests_events :boolean
+# tag_push_events :boolean
#
require "gemnasium/gitlab_service"
@@ -38,11 +42,17 @@ class GemnasiumService < Service
]
end
- def execute(push_data)
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
Gemnasium::GitlabService.execute(
- ref: push_data[:ref],
- before: push_data[:before],
- after: push_data[:after],
+ ref: data[:ref],
+ before: data[:before],
+ after: data[:after],
token: token,
api_key: api_key,
repo: project.repository.path_to_repo
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index f4b463e8199..02bf305f8f2 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean
+# issues_events :boolean
+# merge_requests_events :boolean
+# tag_push_events :boolean
#
class GitlabCiService < CiService
@@ -18,8 +22,6 @@ class GitlabCiService < CiService
validates :project_url, presence: true, if: :activated?
validates :token, presence: true, if: :activated?
- delegate :execute, to: :service_hook, prefix: nil
-
after_save :compose_service_hook, if: :activated?
def compose_service_hook
@@ -28,6 +30,16 @@ class GitlabCiService < CiService
hook.save
end
+ def supported_events
+ %w(push tag_push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
+ service_hook.execute(data)
+ end
+
def commit_status_path(sha)
project_url + "/commits/#{sha}/status.json?token=#{token}"
end
diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb
index 05c048e4e45..00f8d430fd5 100644
--- a/app/models/project_services/gitlab_issue_tracker_service.rb
+++ b/app/models/project_services/gitlab_issue_tracker_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class GitlabIssueTrackerService < IssueTrackerService
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index 003e06a4c80..b85863d2f0d 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean
+# issues_events :boolean
+# merge_requests_events :boolean
+# tag_push_events :boolean
#
class HipchatService < Service
@@ -40,8 +44,14 @@ class HipchatService < Service
]
end
- def execute(push_data)
- gate[room].send('GitLab', create_message(push_data))
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
+ gate[room].send('GitLab', create_message(data))
end
private
diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb
index c991a34ecdb..bfc65b5379f 100644
--- a/app/models/project_services/issue_tracker_service.rb
+++ b/app/models/project_services/issue_tracker_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class IssueTrackerService < Service
@@ -65,7 +69,13 @@ class IssueTrackerService < Service
end
end
+ def supported_events
+ %w(push)
+ end
+
def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
message = "#{self.type} was unable to reach #{self.project_url}. Check the url and try again."
result = false
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 4c056605ea8..20611eeb60c 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class JiraService < IssueTrackerService
diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb
index 287812c57a5..a2fa9788f10 100644
--- a/app/models/project_services/pivotaltracker_service.rb
+++ b/app/models/project_services/pivotaltracker_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class PivotaltrackerService < Service
@@ -37,9 +41,15 @@ class PivotaltrackerService < Service
]
end
- def execute(push)
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
url = 'https://www.pivotaltracker.com/services/v5/source_commits'
- push[:commits].each do |commit|
+ data[:commits].each do |commit|
message = {
'source_commit' => {
'commit_id' => commit[:id],
diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb
index 3a3af59390a..586d9e94a95 100644
--- a/app/models/project_services/pushover_service.rb
+++ b/app/models/project_services/pushover_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class PushoverService < Service
@@ -76,21 +80,27 @@ class PushoverService < Service
]
end
- def execute(push_data)
- ref = push_data[:ref].gsub('refs/heads/', '')
- before = push_data[:before]
- after = push_data[:after]
+ def supported_events
+ %w(push)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
+ ref = data[:ref].gsub('refs/heads/', '')
+ before = data[:before]
+ after = data[:after]
if before.include?('000000')
- message = "#{push_data[:user_name]} pushed new branch \"#{ref}\"."
+ message = "#{data[:user_name]} pushed new branch \"#{ref}\"."
elsif after.include?('000000')
- message = "#{push_data[:user_name]} deleted branch \"#{ref}\"."
+ message = "#{data[:user_name]} deleted branch \"#{ref}\"."
else
- message = "#{push_data[:user_name]} push to branch \"#{ref}\"."
+ message = "#{data[:user_name]} push to branch \"#{ref}\"."
end
- if push_data[:total_commits_count] > 0
- message << "\nTotal commits count: #{push_data[:total_commits_count]}"
+ if data[:total_commits_count] > 0
+ message << "\nTotal commits count: #{data[:total_commits_count]}"
end
pushover_data = {
@@ -100,7 +110,7 @@ class PushoverService < Service
priority: priority,
title: "#{project.name_with_namespace}",
message: message,
- url: push_data[:repository][:homepage],
+ url: data[:repository][:homepage],
url_title: "See project #{project.name_with_namespace}"
}
diff --git a/app/models/project_services/redmine_service.rb b/app/models/project_services/redmine_service.rb
index e1dc10415e0..f96eae2daa1 100644
--- a/app/models/project_services/redmine_service.rb
+++ b/app/models/project_services/redmine_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class RedmineService < IssueTrackerService
diff --git a/app/models/project_services/slack_message.rb b/app/models/project_services/slack_message.rb
deleted file mode 100644
index 6c6446db45f..00000000000
--- a/app/models/project_services/slack_message.rb
+++ /dev/null
@@ -1,110 +0,0 @@
-require 'slack-notifier'
-
-class SlackMessage
- attr_reader :after
- attr_reader :before
- attr_reader :commits
- attr_reader :project_name
- attr_reader :project_url
- attr_reader :ref
- attr_reader :username
-
- def initialize(params)
- @after = params.fetch(:after)
- @before = params.fetch(:before)
- @commits = params.fetch(:commits, [])
- @project_name = params.fetch(:project_name)
- @project_url = params.fetch(:project_url)
- @ref = params.fetch(:ref).gsub('refs/heads/', '')
- @username = params.fetch(:user_name)
- end
-
- def pretext
- format(message)
- end
-
- def attachments
- return [] if new_branch? || removed_branch?
-
- commit_message_attachments
- end
-
- private
-
- def message
- if new_branch?
- new_branch_message
- elsif removed_branch?
- removed_branch_message
- else
- push_message
- end
- end
-
- def format(string)
- Slack::Notifier::LinkFormatter.format(string)
- end
-
- def new_branch_message
- "#{username} pushed new branch #{branch_link} to #{project_link}"
- end
-
- def removed_branch_message
- "#{username} removed branch #{ref} from #{project_link}"
- end
-
- def push_message
- "#{username} pushed to branch #{branch_link} of #{project_link} (#{compare_link})"
- end
-
- def commit_messages
- commits.each_with_object('') do |commit, str|
- str << compose_commit_message(commit)
- end.chomp
- end
-
- def commit_message_attachments
- [{ text: format(commit_messages), color: attachment_color }]
- end
-
- def compose_commit_message(commit)
- author = commit.fetch(:author).fetch(:name)
- id = commit.fetch(:id)[0..8]
- message = commit.fetch(:message)
- url = commit.fetch(:url)
-
- "[#{id}](#{url}): #{message} - #{author}\n"
- end
-
- def new_branch?
- before.include?('000000')
- end
-
- def removed_branch?
- after.include?('000000')
- end
-
- def branch_url
- "#{project_url}/commits/#{ref}"
- end
-
- def compare_url
- "#{project_url}/compare/#{before}...#{after}"
- end
-
- def branch_link
- "[#{ref}](#{branch_url})"
- end
-
- def project_link
- "[#{project_name}](#{project_url})"
- end
-
- def compare_link
- "[Compare changes](#{compare_url})"
- end
-
- def attachment_color
- '#345'
- end
-end
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index c7cbff63fe5..64d6f4327b8 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class SlackService < Service
@@ -38,20 +42,43 @@ class SlackService < Service
]
end
- def execute(push_data)
+ def supported_events
+ %w(push issue merge_request)
+ end
+
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
return unless webhook.present?
- message = SlackMessage.new(push_data.merge(
+ object_kind = data[:object_kind]
+
+ data = data.merge(
project_url: project_url,
project_name: project_name
- ))
+ )
+
+ # WebHook events often have an 'update' event that follows a 'open' or
+ # 'close' action. Ignore update events for now to prevent duplicate
+ # messages from arriving.
+
+ message = \
+ case object_kind
+ when "push"
+ PushMessage.new(data)
+ when "issue"
+ IssueMessage.new(data) unless is_update?(data)
+ when "merge_request"
+ MergeMessage.new(data) unless is_update?(data)
+ end
opt = {}
opt[:channel] = channel if channel
opt[:username] = username if username
- notifier = Slack::Notifier.new(webhook, opt)
- notifier.ping(message.pretext, attachments: message.attachments)
+ if message
+ notifier = Slack::Notifier.new(webhook, opt)
+ notifier.ping(message.pretext, attachments: message.attachments)
+ end
end
private
@@ -63,4 +90,12 @@ class SlackService < Service
def project_url
project.web_url
end
+
+ def is_update?(data)
+ data[:object_attributes][:action] == 'update'
+ end
end
+
+require "slack_service/issue_message"
+require "slack_service/push_message"
+require "slack_service/merge_message"
diff --git a/app/models/project_services/slack_service/base_message.rb b/app/models/project_services/slack_service/base_message.rb
new file mode 100644
index 00000000000..aa00d6061a1
--- /dev/null
+++ b/app/models/project_services/slack_service/base_message.rb
@@ -0,0 +1,31 @@
+require 'slack-notifier'
+
+class SlackService
+ class BaseMessage
+ def initialize(params)
+ raise NotImplementedError
+ end
+
+ def pretext
+ format(message)
+ end
+
+ def attachments
+ raise NotImplementedError
+ end
+
+ private
+
+ def message
+ raise NotImplementedError
+ end
+
+ def format(string)
+ Slack::Notifier::LinkFormatter.format(string)
+ end
+
+ def attachment_color
+ '#345'
+ end
+ end
+end
diff --git a/app/models/project_services/slack_service/issue_message.rb b/app/models/project_services/slack_service/issue_message.rb
new file mode 100644
index 00000000000..e2fed0bb1b9
--- /dev/null
+++ b/app/models/project_services/slack_service/issue_message.rb
@@ -0,0 +1,56 @@
+class SlackService
+ class IssueMessage < BaseMessage
+ attr_reader :username
+ attr_reader :title
+ attr_reader :project_name
+ attr_reader :project_url
+ attr_reader :issue_iid
+ attr_reader :issue_url
+ attr_reader :action
+ attr_reader :state
+ attr_reader :description
+
+ def initialize(params)
+ @username = params[:user][:username]
+ @project_name = params[:project_name]
+ @project_url = params[:project_url]
+
+ obj_attr = params[:object_attributes]
+ obj_attr = HashWithIndifferentAccess.new(obj_attr)
+ @title = obj_attr[:title]
+ @issue_iid = obj_attr[:iid]
+ @issue_url = obj_attr[:url]
+ @action = obj_attr[:action]
+ @state = obj_attr[:state]
+ @description = obj_attr[:description]
+ end
+
+ def attachments
+ return [] unless opened_issue?
+
+ description_message
+ end
+
+ private
+
+ def message
+ "#{username} #{state} issue #{issue_link} in #{project_link}: #{title}"
+ end
+
+ def opened_issue?
+ action == "open"
+ end
+
+ def description_message
+ [{ text: format(description), color: attachment_color }]
+ end
+
+ def project_link
+ "[#{project_name}](#{project_url})"
+ end
+
+ def issue_link
+ "[##{issue_iid}](#{issue_url})"
+ end
+ end
+end
diff --git a/app/models/project_services/slack_service/merge_message.rb b/app/models/project_services/slack_service/merge_message.rb
new file mode 100644
index 00000000000..4dcce1d15a0
--- /dev/null
+++ b/app/models/project_services/slack_service/merge_message.rb
@@ -0,0 +1,54 @@
+class SlackService
+ class MergeMessage < BaseMessage
+ attr_reader :username
+ attr_reader :project_name
+ attr_reader :project_url
+ attr_reader :merge_request_id
+ attr_reader :source_branch
+ attr_reader :target_branch
+ attr_reader :state
+
+ def initialize(params)
+ @username = params[:user][:username]
+ @project_name = params[:project_name]
+ @project_url = params[:project_url]
+
+ obj_attr = params[:object_attributes]
+ obj_attr = HashWithIndifferentAccess.new(obj_attr)
+ @merge_request_id = obj_attr[:iid]
+ @source_branch = obj_attr[:source_branch]
+ @target_branch = obj_attr[:target_branch]
+ @state = obj_attr[:state]
+ end
+
+ def pretext
+ format(message)
+ end
+
+ def attachments
+ []
+ end
+
+ private
+
+ def message
+ merge_request_message
+ end
+
+ def project_link
+ "[#{project_name}](#{project_url})"
+ end
+
+ def merge_request_message
+ "#{username} #{state} merge request #{merge_request_link} in #{project_link}"
+ end
+
+ def merge_request_link
+ "[##{merge_request_id}](#{merge_request_url})"
+ end
+
+ def merge_request_url
+ "#{project_url}/merge_requests/#{merge_request_id}"
+ end
+ end
+end
diff --git a/app/models/project_services/slack_service/push_message.rb b/app/models/project_services/slack_service/push_message.rb
new file mode 100644
index 00000000000..2e566bc317b
--- /dev/null
+++ b/app/models/project_services/slack_service/push_message.rb
@@ -0,0 +1,108 @@
+class SlackService
+ class PushMessage < BaseMessage
+ attr_reader :after
+ attr_reader :before
+ attr_reader :commits
+ attr_reader :project_name
+ attr_reader :project_url
+ attr_reader :ref
+ attr_reader :username
+
+ def initialize(params)
+ @after = params[:after]
+ @before = params[:before]
+ @commits = params.fetch(:commits, [])
+ @project_name = params[:project_name]
+ @project_url = params[:project_url]
+ @ref = params[:ref].gsub('refs/heads/', '')
+ @username = params[:user_name]
+ end
+
+ def pretext
+ format(message)
+ end
+
+ def attachments
+ return [] if new_branch? || removed_branch?
+
+ commit_message_attachments
+ end
+
+ private
+
+ def message
+ if new_branch?
+ new_branch_message
+ elsif removed_branch?
+ removed_branch_message
+ else
+ push_message
+ end
+ end
+
+ def format(string)
+ Slack::Notifier::LinkFormatter.format(string)
+ end
+
+ def new_branch_message
+ "#{username} pushed new branch #{branch_link} to #{project_link}"
+ end
+
+ def removed_branch_message
+ "#{username} removed branch #{ref} from #{project_link}"
+ end
+
+ def push_message
+ "#{username} pushed to branch #{branch_link} of #{project_link} (#{compare_link})"
+ end
+
+ def commit_messages
+ commits.map { |commit| compose_commit_message(commit) }.join("\n")
+ end
+
+ def commit_message_attachments
+ [{ text: format(commit_messages), color: attachment_color }]
+ end
+
+ def compose_commit_message(commit)
+ author = commit[:author][:name]
+ id = Commit.truncate_sha(commit[:id])
+ message = commit[:message]
+ url = commit[:url]
+
+ "[#{id}](#{url}): #{message} - #{author}"
+ end
+
+ def new_branch?
+ before.include?('000000')
+ end
+
+ def removed_branch?
+ after.include?('000000')
+ end
+
+ def branch_url
+ "#{project_url}/commits/#{ref}"
+ end
+
+ def compare_url
+ "#{project_url}/compare/#{before}...#{after}"
+ end
+
+ def branch_link
+ "[#{ref}](#{branch_url})"
+ end
+
+ def project_link
+ "[#{project_name}](#{project_url})"
+ end
+
+ def compare_link
+ "[Compare changes](#{compare_url})"
+ end
+
+ def attachment_color
+ '#345'
+ end
+ end
+end
diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb
index b6932f1c77b..686e6225a2e 100644
--- a/app/models/project_services/teamcity_service.rb
+++ b/app/models/project_services/teamcity_service.rb
@@ -11,6 +11,10 @@
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
+# push_events :boolean default(TRUE)
+# issues_events :boolean default(TRUE)
+# merge_requests_events :boolean default(TRUE)
+# tag_push_events :boolean default(TRUE)
#
class TeamcityService < CiService
@@ -57,6 +61,10 @@ class TeamcityService < CiService
'teamcity'
end
+ def supported_events
+ %w(push)
+ end
+
def fields
[
{ type: 'text', name: 'teamcity_url',
@@ -115,13 +123,15 @@ class TeamcityService < CiService
end
end
- def execute(push)
+ def execute(data)
+ return unless supported_events.include?(data[:object_kind])
+
auth = {
username: username,
password: password,
}
- branch = push[:ref].gsub('refs/heads/', '')
+ branch = data[:ref].gsub('refs/heads/', '')
self.class.post("#{teamcity_url}/httpAuth/app/rest/buildQueue",
body: "<build branchName=\"#{branch}\">"\