summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward P. Logsdon <howard@hplogsdon.com>2015-04-24 11:45:17 -0600
committerHoward P. Logsdon <howard@hplogsdon.com>2015-04-30 22:02:28 -0600
commit4c63ef932bc2b573cd9306066993f72c1cb8dc83 (patch)
tree3b26f21873330db918237bd63c9a11404e2ec4e9
parent3bbd2f55a299b31a702b7ae6aa2624e5116bc8e8 (diff)
downloadgitlab-ci-4c63ef932bc2b573cd9306066993f72c1cb8dc83.tar.gz
HipChat Notification Service
* Move existing Slack service spec into a subdir, mirroring /app * Wire up HipChat service to the project and services controller. * Split the message building into own class. * 'namespace' room and token variables. * Enforce v2 client (bug in HipChat gem v1.5.0. fixed in 1.5.1). Note that I'm using the same version string as GitLab-CE, for shared installations. * Defer execution to a notifier worker, like the Slack service. * Ensure passing specs (basically a Slack service spec copy, fwiw) * Added change to the CHANGELOG
-rw-r--r--CHANGELOG1
-rw-r--r--Gemfile3
-rw-r--r--Gemfile.lock5
-rw-r--r--app/controllers/services_controller.rb3
-rw-r--r--app/models/project.rb3
-rw-r--r--app/models/project_services/hip_chat_message.rb62
-rw-r--r--app/models/project_services/hip_chat_service.rb67
-rw-r--r--app/workers/hip_chat_notifier_worker.rb9
-rw-r--r--spec/models/project_services/hip_chat_service_spec.rb48
-rw-r--r--spec/models/project_services/slack_message_spec.rb (renamed from spec/models/slack_message_spec.rb)0
-rw-r--r--spec/models/project_services/slack_service_spec.rb (renamed from spec/models/slack_service_spec.rb)0
11 files changed, 199 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 84499ee..5f157e0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@ v7.11.0
- Improved runners page
- Running and Pending tabs on admin builds page
- Fix [ci skip] tag, so you can skip CI triggering now
+ - Add HipChat notifications
v7.10.1
- Fix failing migration when update to 7.10 from 7.8 and older versions
diff --git a/Gemfile b/Gemfile
index b0b803e..9950761 100644
--- a/Gemfile
+++ b/Gemfile
@@ -63,6 +63,9 @@ gem "default_value_for", "~> 3.0.0"
# Slack integration
gem "slack-notifier", "~> 1.0.0"
+# HipChat integration
+gem 'hipchat', '~> 1.5.0'
+
# Other
gem 'rake'
gem 'foreman'
diff --git a/Gemfile.lock b/Gemfile.lock
index 41bc118..d2c9158 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -156,6 +156,9 @@ GEM
hashie (2.0.5)
highline (1.6.21)
hike (1.2.3)
+ hipchat (1.5.0)
+ httparty
+ mimemagic
httparty (0.11.0)
multi_json (~> 1.0)
multi_xml (>= 0.5.2)
@@ -186,6 +189,7 @@ GEM
mime-types (>= 1.16, < 3)
method_source (0.8.2)
mime-types (2.4.3)
+ mimemagic (0.3.0)
mini_portile (0.5.2)
minitest (5.5.1)
multi_json (1.11.0)
@@ -390,6 +394,7 @@ DEPENDENCIES
growl
guard-rspec
haml-rails (~> 0.5.3)
+ hipchat (~> 1.5.0)
httparty (= 0.11.0)
jquery-rails
jquery-turbolinks
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index 39cf306..64bc698 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -50,7 +50,8 @@ class ServicesController < ApplicationController
def service_params
params.require(:service).permit(
:type, :active, :webhook, :notify_only_broken_builds,
- :email_recipients, :email_only_broken_builds, :email_add_pusher
+ :email_recipients, :email_only_broken_builds, :email_add_pusher,
+ :hipchat_token, :hipchat_room, :hipchat_server
)
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 31ce6ab..c48b079 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -37,6 +37,7 @@ class Project < ActiveRecord::Base
# Project services
has_many :services, dependent: :destroy
+ has_one :hip_chat_service, dependent: :destroy
has_one :slack_service, dependent: :destroy
has_one :mail_service, dependent: :destroy
@@ -210,7 +211,7 @@ ls -la
end
def available_services_names
- %w(slack mail)
+ %w(slack mail hip_chat)
end
def build_missing_services
diff --git a/app/models/project_services/hip_chat_message.rb b/app/models/project_services/hip_chat_message.rb
new file mode 100644
index 0000000..85695cc
--- /dev/null
+++ b/app/models/project_services/hip_chat_message.rb
@@ -0,0 +1,62 @@
+class HipChatMessage
+ attr_reader :build
+
+ def initialize(build)
+ @build = build
+ end
+
+ def to_s
+ lines = Array.new
+ lines.push("<a href=\"#{RoutesHelper.project_url(build.project)}\">#{build.project.name}</a> - ")
+ if build.commit.matrix?
+ lines.push("<a href=\"#{RoutesHelper.project_ref_commit_url(build.project, build.commit.ref, build.commit.sha)}\">Commit ##{commit.id}</a></br>")
+ else
+ lines.push("<a href=\"#{RoutesHelper.project_build_url(build.project, build)}\">Build '#{build.job_name}' ##{build.id}</a></br>")
+ end
+ lines.push("#{build.commit.short_sha} #{build.commit.git_author_name} - #{build.commit.git_commit_message}</br>")
+ lines.push("#{humanized_status} in #{build.commit.duration} second(s).")
+ lines.join('')
+ end
+
+ def color
+ case status
+ when :success
+ 'green'
+ when :failed, :canceled
+ 'red'
+ when :pending, :running
+ 'yellow'
+ else
+ 'random'
+ end
+ end
+
+ def notify?
+ [:failed, :canceled].include?(status)
+ end
+
+ private
+
+ def status
+ build.status.to_sym
+ end
+
+ def humanized_status
+ case status
+ when :pending
+ "Pending"
+ when :running
+ "Running"
+ when :failed
+ "Failed"
+ when :success
+ "Successful"
+ when :canceled
+ "Canceled"
+ else
+ "Unknown"
+ end
+ end
+
+end
+
diff --git a/app/models/project_services/hip_chat_service.rb b/app/models/project_services/hip_chat_service.rb
new file mode 100644
index 0000000..0faaca5
--- /dev/null
+++ b/app/models/project_services/hip_chat_service.rb
@@ -0,0 +1,67 @@
+# == Schema Information
+#
+# Table name: services
+#
+# id :integer not null, primary key
+# type :string(255)
+# title :string(255)
+# project_id :integer not null
+# created_at :datetime
+# updated_at :datetime
+# active :boolean default(FALSE), not null
+# properties :text
+#
+
+class HipChatService < Service
+ prop_accessor :hipchat_token, :hipchat_room, :hipchat_server
+ boolean_accessor :notify_only_broken_builds
+ validates :hipchat_token, presence: true, if: :activated?
+ validates :hipchat_room, presence: true, if: :activated?
+ default_value_for :notify_only_broken_builds, true
+
+ def title
+ "HipChat"
+ end
+
+ def description
+ "Private group chat, video chat, instant messaging for teams"
+ end
+
+ def help
+ end
+
+ def to_param
+ 'hip_chat'
+ end
+
+ def fields
+ [
+ { type: 'text', name: 'hipchat_token', label: 'Token', placeholder: '' },
+ { type: 'text', name: 'hipchat_room', label: 'Room', placeholder: '' },
+ { type: 'text', name: 'hipchat_server', label: 'Server', placeholder: 'https://hipchat.example.com', help: 'Leave blank for default' },
+ { type: 'checkbox', name: 'notify_only_broken_builds', label: 'Notify only broken builds' }
+ ]
+ end
+
+ def execute build
+ commit = build.commit
+ return unless commit
+ return unless commit.builds_without_retry.include? build
+
+ msg = HipChatMessage.new(build)
+ HipChatNotifierWorker.perform_async(hipchat_room, hipchat_token, msg.to_s, {
+ message_format: 'html',
+ color: msg.color,
+ notify: notify_only_broken_builds? && msg.notify?
+ })
+ end
+
+ private
+
+ def default_options
+ {
+ hipchat_server: 'https://api.hipchat.com'
+ }
+ end
+
+end
diff --git a/app/workers/hip_chat_notifier_worker.rb b/app/workers/hip_chat_notifier_worker.rb
new file mode 100644
index 0000000..5bc7dda
--- /dev/null
+++ b/app/workers/hip_chat_notifier_worker.rb
@@ -0,0 +1,9 @@
+
+class HipChatNotifierWorker
+ include Sidekiq::Worker
+
+ def perform(room, token, message, options={})
+ client = HipChat::Client.new(token, api_version: 'v2') # v1.5.0 requires explicit version (
+ client[room].send("GitLab CI", message, options)
+ end
+end
diff --git a/spec/models/project_services/hip_chat_service_spec.rb b/spec/models/project_services/hip_chat_service_spec.rb
new file mode 100644
index 0000000..e578461
--- /dev/null
+++ b/spec/models/project_services/hip_chat_service_spec.rb
@@ -0,0 +1,48 @@
+
+require 'spec_helper'
+
+describe HipChatService do
+
+ describe "Validations" do
+
+ context "active" do
+ before do
+ subject.active = true
+ end
+
+ it { should validate_presence_of :hipchat_room }
+ it { should validate_presence_of :hipchat_token }
+
+ end
+ end
+
+ describe "Execute" do
+
+ let(:service) { HipChatService.new }
+ let(:project) { FactoryGirl.create :project }
+ let(:commit) { FactoryGirl.create :commit, project: project }
+ let(:build) { FactoryGirl.create :build, commit: commit, status: 'failed' }
+ let(:api_url) { 'https://api.hipchat.com/v2/room/123/notification?auth_token=a1b2c3d4e5f6' }
+
+ before do
+ service.stub(
+ project: project,
+ project_id: project.id,
+ notify_only_broken_builds: false,
+ hipchat_room: 123,
+ hipchat_token: 'a1b2c3d4e5f6'
+ )
+
+ WebMock.stub_request(:post, api_url)
+ end
+
+
+ it "should call the HipChat API" do
+ service.execute(build)
+ HipChatNotifierWorker.drain
+
+ WebMock.should have_requested(:post, api_url).once
+ end
+ end
+end
+
diff --git a/spec/models/slack_message_spec.rb b/spec/models/project_services/slack_message_spec.rb
index 1fa2e31..1fa2e31 100644
--- a/spec/models/slack_message_spec.rb
+++ b/spec/models/project_services/slack_message_spec.rb
diff --git a/spec/models/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb
index e1c1428..e1c1428 100644
--- a/spec/models/slack_service_spec.rb
+++ b/spec/models/project_services/slack_service_spec.rb