diff options
author | Federico Ravasio <ravasio.federico@gmail.com> | 2014-03-18 18:27:03 +0100 |
---|---|---|
committer | Federico Ravasio <ravasio.federico@gmail.com> | 2014-03-18 18:54:30 +0100 |
commit | e3fc01b3eaa13a51aef380dc21f1e7d259706227 (patch) | |
tree | f0d01f3ed7f2eff37d0ab81d268592101d1a2a52 /app/models | |
parent | acaf297846907bff096dcbd71d6665ac6d4b8abc (diff) | |
download | gitlab-ce-e3fc01b3eaa13a51aef380dc21f1e7d259706227.tar.gz |
Added Slack service integration.
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/project.rb | 3 | ||||
-rw-r--r-- | app/models/project_services/slack_message.rb | 95 | ||||
-rw-r--r-- | app/models/project_services/slack_service.rb | 67 |
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 |