summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
authorFederico Ravasio <ravasio.federico@gmail.com>2014-03-18 18:27:03 +0100
committerFederico Ravasio <ravasio.federico@gmail.com>2014-03-18 18:54:30 +0100
commite3fc01b3eaa13a51aef380dc21f1e7d259706227 (patch)
treef0d01f3ed7f2eff37d0ab81d268592101d1a2a52 /app/models
parentacaf297846907bff096dcbd71d6665ac6d4b8abc (diff)
downloadgitlab-ce-e3fc01b3eaa13a51aef380dc21f1e7d259706227.tar.gz
Added Slack service integration.
Diffstat (limited to 'app/models')
-rw-r--r--app/models/project.rb3
-rw-r--r--app/models/project_services/slack_message.rb95
-rw-r--r--app/models/project_services/slack_service.rb67
3 files changed, 164 insertions, 1 deletions
diff --git a/app/models/project.rb b/app/models/project.rb
index 7d7edc45739..769ab217625 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -56,6 +56,7 @@ class Project < ActiveRecord::Base
has_one :flowdock_service, dependent: :destroy
has_one :assembla_service, dependent: :destroy
has_one :gemnasium_service, dependent: :destroy
+ has_one :slack_service, dependent: :destroy
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
has_one :forked_from_project, through: :forked_project_link
# Merge Requests for target project should be removed with it
@@ -304,7 +305,7 @@ class Project < ActiveRecord::Base
end
def available_services_names
- %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium)
+ %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack)
end
def gitlab_ci?
diff --git a/app/models/project_services/slack_message.rb b/app/models/project_services/slack_message.rb
new file mode 100644
index 00000000000..b2b8d6fed7a
--- /dev/null
+++ b/app/models/project_services/slack_message.rb
@@ -0,0 +1,95 @@
+require 'slack-notifier'
+
+class SlackMessage
+ 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 compose
+ format(message)
+ end
+
+ private
+
+ attr_reader :after
+ attr_reader :before
+ attr_reader :commits
+ attr_reader :project_name
+ attr_reader :project_url
+ attr_reader :ref
+ attr_reader :username
+
+ def message
+ if new_branch?
+ new_branch_message
+ elsif removed_branch?
+ removed_branch_message
+ else
+ push_message << commit_messages
+ 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
+ end
+
+ def compose_commit_message(commit)
+ id = commit.fetch(:id)[0..5]
+ message = commit.fetch(:message)
+ url = commit.fetch(:url)
+
+ "\n - #{message} ([#{id}](#{url}))"
+ end
+
+ def new_branch?
+ before =~ /000000/
+ end
+
+ def removed_branch?
+ after =~ /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
+end
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
new file mode 100644
index 00000000000..27648acf6d0
--- /dev/null
+++ b/app/models/project_services/slack_service.rb
@@ -0,0 +1,67 @@
+# == Schema Information
+#
+# Table name: services
+#
+# id :integer not null, primary key
+# type :string(255)
+# title :string(255)
+# token :string(255)
+# project_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# active :boolean default(FALSE), not null
+# project_url :string(255)
+# subdomain :string(255)
+# room :string(255)
+# api_key :string(255)
+#
+
+class SlackService < Service
+ attr_accessible :room
+ attr_accessible :subdomain
+
+ validates :room, presence: true, if: :activated?
+ validates :subdomain, presence: true, if: :activated?
+ validates :token, presence: true, if: :activated?
+
+ def title
+ 'Slack'
+ end
+
+ def description
+ 'A team communication tool for the 21st century'
+ end
+
+ def to_param
+ 'slack'
+ end
+
+ def fields
+ [
+ { type: 'text', name: 'subdomain', placeholder: '' },
+ { type: 'text', name: 'token', placeholder: '' },
+ { type: 'text', name: 'room', placeholder: '' },
+ ]
+ end
+
+ def execute(push_data)
+ message = SlackMessage.new(push_data.merge(
+ project_url: project_url,
+ project_name: project_name
+ ))
+
+ notifier = Slack::Notifier.new(subdomain, token)
+ notifier.channel = room
+ notifier.ping(message.compose)
+ end
+
+ private
+
+ def project_name
+ project.name_with_namespace.gsub(/\s/, '')
+ end
+
+ def project_url
+ project.web_url
+ end
+end