samson_hipchat 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/app/decorators/stage_decorator.rb +50 -0
- data/app/models/hipchat_notification.rb +82 -0
- data/app/models/hipchat_notification_renderer.rb +8 -0
- data/app/models/hipchat_room.rb +3 -0
- data/app/views/samson_hipchat/_fields.html.erb +25 -0
- data/app/views/samson_hipchat/notification.text.erb +19 -0
- data/config/initializers/hipchat.rb +1 -0
- data/db/migrate/20150519105221_create_hipchat_rooms.rb +15 -0
- data/lib/samson_hipchat/samson_plugin.rb +22 -0
- data/samson_hipchat.gemspec +7 -0
- data/test/models/hipchat_notification_renderer_test.rb +42 -0
- data/test/models/hipchat_notification_test.rb +47 -0
- data/test/models/hooks_test.rb +32 -0
- data/test/test_helper.rb +1 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b607259d6768010582ed642548e566eb14e56766
|
4
|
+
data.tar.gz: d5bd36c6105fdf7379f37ff33307af64df16ddfc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 268a569dfad68045f253bb8228b6d17ed90f76d774770402bef2d4cc1a9e81f3cdb06e2a6043d6bdc1b8e77fe7c2e51c8809d5e8bc05f1abff53e39f19556747
|
7
|
+
data.tar.gz: ddd08358daca564d06cea498c532aeea93ef3d61edd8e8d478cdb1a8b28b7e759be19bce58cdf290f04f7545b1d3cf99108a63014dc81cbf9abdf0b6c1bfb88b
|
@@ -0,0 +1,50 @@
|
|
1
|
+
Stage.class_eval do
|
2
|
+
|
3
|
+
cattr_reader(:hipchat_rooms_cache_key) { 'hipchat-rooms-list' }
|
4
|
+
|
5
|
+
has_many :hipchat_rooms
|
6
|
+
accepts_nested_attributes_for :hipchat_rooms, allow_destroy: true, reject_if: :no_room_name?
|
7
|
+
validate :room_exists?
|
8
|
+
before_save :update_room_id
|
9
|
+
|
10
|
+
def send_hipchat_notifications?
|
11
|
+
hipchat_rooms.any?
|
12
|
+
end
|
13
|
+
|
14
|
+
def room_name
|
15
|
+
hipchat_rooms.first.try(:name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def no_room_name?(hipchat_attrs)
|
19
|
+
hipchat_attrs['name'].blank?
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_room_id
|
23
|
+
if room_for(room_name)
|
24
|
+
self.hipchat_rooms.first.room_id = room_for(room_name)['id']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def room_exists?
|
29
|
+
if room_name
|
30
|
+
errors.add(:hipchat_rooms_name, "was not found. Create the room first.") unless room_for(room_name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def hipchat
|
35
|
+
client = HipChat::Client.new(hipchat_rooms.first.try(:token), :api_version => 'v2')
|
36
|
+
client
|
37
|
+
end
|
38
|
+
|
39
|
+
def room_for(name)
|
40
|
+
return nil unless name
|
41
|
+
|
42
|
+
Rails.cache.fetch(hipchat_rooms_cache_key, expires_in: 5.minutes) do
|
43
|
+
begin
|
44
|
+
hipchat[name].get_room
|
45
|
+
rescue HipChat::UnknownRoom
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class HipchatNotification
|
2
|
+
|
3
|
+
def initialize(deploy)
|
4
|
+
@deploy = deploy
|
5
|
+
@stage = deploy.stage
|
6
|
+
end
|
7
|
+
|
8
|
+
def deliver
|
9
|
+
message = Message.new(@deploy)
|
10
|
+
begin
|
11
|
+
hipchat[@stage.hipchat_rooms.first.name].send message.from, message.to_s, **message.style
|
12
|
+
rescue HipChat::UnknownRoom => e
|
13
|
+
Rails.logger.error("Room did not existed")
|
14
|
+
rescue HipChat::Unauthorized => e
|
15
|
+
Rails.logger.error("Invalid token to post to room")
|
16
|
+
rescue HipChat::UnknownResponseCode => e
|
17
|
+
Rails.logger.error("Could not deliver hipchat message: #{e.message}")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Message
|
22
|
+
delegate :project, :stage, :user, to: :@deploy
|
23
|
+
delegate :project_deploy_url, to: 'AppRoutes.url_helpers'
|
24
|
+
|
25
|
+
def initialize(deploy)
|
26
|
+
@deploy = deploy
|
27
|
+
@stage = deploy.stage
|
28
|
+
@project = @stage.project
|
29
|
+
@user = @deploy.user
|
30
|
+
@changeset = @deploy.changeset
|
31
|
+
end
|
32
|
+
|
33
|
+
def style
|
34
|
+
{:color => color}
|
35
|
+
end
|
36
|
+
|
37
|
+
def from
|
38
|
+
"Deploy"
|
39
|
+
end
|
40
|
+
|
41
|
+
def subject
|
42
|
+
subject = "#{@user.name} is about to <a href='#{deploy_url}'>deploy</a> <strong>#{@project.name}</strong> on <strong>#{@stage.name}</strong><br>"
|
43
|
+
|
44
|
+
subject = "#{@user.name} successfully deploy <strong>#{@project.name}</strong> @<a href='#{diff_url}'>#{@deploy.commit}...#{@changeset.try(:previous_commit)}</a> on <strong>#{@stage.name}</strong><br>" if @deploy.job.succeeded?
|
45
|
+
|
46
|
+
subject = "#{@user.name} failed to <a href='#{deploy_url}'>deploy</a> <strong>#{@project.name}</strong> on <strong>#{@stage.name}</strong><br>" if @deploy.job.failed? || @deploy.job.errored?
|
47
|
+
|
48
|
+
subject
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_s
|
52
|
+
content
|
53
|
+
end
|
54
|
+
|
55
|
+
def content
|
56
|
+
return subject if @deploy.job.succeeded? || @deploy.job.failed? || @deploy.job.errored?
|
57
|
+
@content ||= HipchatNotificationRenderer.render(@deploy, subject)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def color
|
63
|
+
return 'green' if @deploy.job.succeeded?
|
64
|
+
return 'red' if @deploy.job.failed? || @deploy.job.errored?
|
65
|
+
'yellow'
|
66
|
+
end
|
67
|
+
|
68
|
+
def diff_url
|
69
|
+
@changeset.github_url
|
70
|
+
end
|
71
|
+
|
72
|
+
def deploy_url
|
73
|
+
project_deploy_url(@deploy.project, @deploy)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def hipchat
|
80
|
+
HipChat::Client.new @stage.hipchat_rooms.first.token, api_version: 'v2'
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class HipchatNotificationRenderer
|
2
|
+
def self.render(deploy, subject)
|
3
|
+
controller = ActionController::Base.new
|
4
|
+
view = ActionView::Base.new(File.expand_path("../../views/samson_hipchat", __FILE__), {}, controller)
|
5
|
+
locals = { deploy: deploy, changeset: deploy.changeset, subject: subject }
|
6
|
+
view.render(template: 'notification', locals: locals).chomp
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<fieldset>
|
2
|
+
<legend>Hipchat</legend>
|
3
|
+
<p class="col-lg-offset-2">Hipchat room and token.</p>
|
4
|
+
|
5
|
+
<% stage = form.object %>
|
6
|
+
<% stage.hipchat_rooms.build if stage.hipchat_rooms.last.try(:name).blank? %>
|
7
|
+
|
8
|
+
<%= form.fields_for :hipchat_rooms do |hipchat_fields| %>
|
9
|
+
<div class="form-group">
|
10
|
+
<div class="col-lg-2 col-lg-offset-2">
|
11
|
+
<%= hipchat_fields.text_field :name, class: "form-control", placeholder: "Room name" %>
|
12
|
+
</div>
|
13
|
+
<div class="col-lg-4">
|
14
|
+
<%= hipchat_fields.text_field :token, class: "form-control", placeholder: "Token" %>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<% if hipchat_fields.object.persisted? %>
|
18
|
+
<div class="col-lg-1 checkbox">
|
19
|
+
<%= hipchat_fields.check_box :_destroy if hipchat_fields.object.persisted? %>
|
20
|
+
<%= hipchat_fields.label :_destroy, "Delete" %>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
25
|
+
</fieldset>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<%= subject %>
|
2
|
+
<% if changeset.commits.count == 0 %>
|
3
|
+
There are no new commits since last time.
|
4
|
+
<% else %>
|
5
|
+
<%= pluralize changeset.commits.count, "commit" %> by <%= changeset.author_names.to_sentence %>.
|
6
|
+
<br>
|
7
|
+
<strong>Files changed:</strong>
|
8
|
+
<ul>
|
9
|
+
<% changeset.files.each do |file| %>
|
10
|
+
<li><%= file.status[0].upcase %> <%= file.filename %></li>
|
11
|
+
<% end %>
|
12
|
+
</ul>
|
13
|
+
<strong>Commits:</strong>
|
14
|
+
<ol>
|
15
|
+
<% changeset.commits.each do |commit| %>
|
16
|
+
<li><a href='<%= commit.url %>'>(<%= commit.author_name %>)</a>: <%= commit.summary %></li>
|
17
|
+
<% end %>
|
18
|
+
</ol>
|
19
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'hipchat'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class CreateHipchatRooms < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :hipchat_rooms do |t|
|
4
|
+
t.string :name, null: false
|
5
|
+
t.string :token, null: false
|
6
|
+
t.string :room_id, null: false
|
7
|
+
t.integer :stage_id, null: false
|
8
|
+
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :hipchat_rooms, :stage_id
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SamsonHipchat
|
2
|
+
class Engine < Rails::Engine
|
3
|
+
end
|
4
|
+
end
|
5
|
+
Samson::Hooks.view :stage_form, "samson_hipchat/fields"
|
6
|
+
|
7
|
+
Samson::Hooks.callback :stage_clone do |old_stage, new_stage|
|
8
|
+
new_stage.hipchat_rooms.build(old_stage.hipchat_rooms.map(&:attributes))
|
9
|
+
end
|
10
|
+
|
11
|
+
Samson::Hooks.callback :stage_permitted_params do
|
12
|
+
{ hipchat_rooms_attributes: [:id, :name, :token, :_destroy] }
|
13
|
+
end
|
14
|
+
|
15
|
+
notify = -> (deploy, _buddy) do
|
16
|
+
if deploy.stage.send_hipchat_notifications?
|
17
|
+
HipchatNotification.new(deploy).deliver
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Samson::Hooks.callback :before_deploy, ¬ify
|
22
|
+
Samson::Hooks.callback :after_deploy, ¬ify
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe HipchatNotificationRenderer do
|
4
|
+
describe "starting" do
|
5
|
+
it "renders a nicely formatted notification" do
|
6
|
+
changeset = stub("changeset")
|
7
|
+
deploy = stub("deploy", short_reference: "xyz", changeset: changeset)
|
8
|
+
|
9
|
+
author1 = "author1"
|
10
|
+
author2 = "author2"
|
11
|
+
changeset.stubs(:author_names).returns([author1, author2])
|
12
|
+
|
13
|
+
commit1 = stub("commit1", url: "#", author_name: "author1", summary: "Introduce bug")
|
14
|
+
commit2 = stub("commit2", url: "#", author_name: "author2", summary: "Fix bug")
|
15
|
+
changeset.stubs(:commits).returns([commit1, commit2])
|
16
|
+
|
17
|
+
file1 = stub("file1", status: "added", filename: "foo.rb")
|
18
|
+
file2 = stub("file2", status: "modified", filename: "bar.rb")
|
19
|
+
changeset.stubs(:files).returns([file1, file2])
|
20
|
+
|
21
|
+
subject = "Deploy starting"
|
22
|
+
|
23
|
+
result = HipchatNotificationRenderer.render(deploy, subject)
|
24
|
+
|
25
|
+
result.must_equal <<-RESULT.strip_heredoc.chomp
|
26
|
+
Deploy starting
|
27
|
+
2 commits by author1 and author2.
|
28
|
+
<br>
|
29
|
+
<strong>Files changed:</strong>
|
30
|
+
<ul>
|
31
|
+
<li>A foo.rb</li>
|
32
|
+
<li>M bar.rb</li>
|
33
|
+
</ul>
|
34
|
+
<strong>Commits:</strong>
|
35
|
+
<ol>
|
36
|
+
<li><a href='#'>(author1)</a>: Introduce bug</li>
|
37
|
+
<li><a href='#'>(author2)</a>: Fix bug</li>
|
38
|
+
<ol>
|
39
|
+
RESULT
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe HipchatNotification do
|
4
|
+
let(:project) { stub(name: "Glitter") }
|
5
|
+
let(:user) { stub(name: "John Wu", email: "wu@rocks.com") }
|
6
|
+
let(:stage) { stub(name: "staging", hipchat_rooms: [stub(name: "x123yx", token: "token123")], project: project) }
|
7
|
+
let(:hipchat_message) { stub(content: "hello world!", style: {color: :red}, subject: "subject") }
|
8
|
+
let(:previous_deploy) { stub(summary: "hello world!", user: user, stage: stage) }
|
9
|
+
let(:deploy) { stub(summary: "hello world!", user: user, stage: stage, changeset: "changeset") }
|
10
|
+
let(:notification) { HipchatNotification.new(deploy) }
|
11
|
+
let(:endpoint) { "https://api.hipchat.com/v2/room/x123yx/notification?auth_token=token123" }
|
12
|
+
|
13
|
+
before do
|
14
|
+
HipchatNotificationRenderer.stubs(:render).returns("foo")
|
15
|
+
HipchatNotification::Message.any_instance.stubs(:content).returns("message to send")
|
16
|
+
HipchatNotification::Message.any_instance.stubs(:from).returns("Deployer")
|
17
|
+
HipchatNotification::Message.any_instance.stubs(:style).returns({color: :red})
|
18
|
+
end
|
19
|
+
|
20
|
+
it "notifies hipchat channels configured for the stage" do
|
21
|
+
delivery = stub_request(:post, endpoint)
|
22
|
+
notification.deliver
|
23
|
+
|
24
|
+
assert_requested delivery
|
25
|
+
end
|
26
|
+
|
27
|
+
it "renders a nicely formatted notification" do
|
28
|
+
stub_request(:post, endpoint)
|
29
|
+
HipchatNotificationRenderer.stubs(:render).returns("bar")
|
30
|
+
notification.deliver
|
31
|
+
|
32
|
+
content, format, from, color = nil
|
33
|
+
assert_requested :post, endpoint do |request|
|
34
|
+
body = JSON.parse(request.body)
|
35
|
+
puts body["message"]
|
36
|
+
content = body.fetch("message")
|
37
|
+
format = body.fetch("message_format")
|
38
|
+
from = body.fetch("from")
|
39
|
+
color = body.fetch("color")
|
40
|
+
content.must_equal "message to send"
|
41
|
+
format.must_equal "html"
|
42
|
+
from.must_equal "Deployer"
|
43
|
+
color.must_equal "red"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe "hipchat hooks" do
|
4
|
+
let(:deploy) { deploys(:succeeded_test) }
|
5
|
+
let(:stage) { deploy.stage }
|
6
|
+
|
7
|
+
describe :before_deploy do
|
8
|
+
it "sends notification on before hook" do
|
9
|
+
stage.stubs(:send_hipchat_notifications?).returns(true)
|
10
|
+
HipchatNotification.any_instance.expects(:deliver)
|
11
|
+
Samson::Hooks.fire(:before_deploy, deploy, nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "does not send notifications when disabled" do
|
15
|
+
HipchatNotification.any_instance.expects(:deliver).never
|
16
|
+
Samson::Hooks.fire(:before_deploy, deploy, nil)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe :after_deploy do
|
21
|
+
it "sends notification on after hook" do
|
22
|
+
stage.stubs(:send_hipchat_notifications?).returns(true)
|
23
|
+
HipchatNotification.any_instance.expects(:deliver)
|
24
|
+
Samson::Hooks.fire(:after_deploy, deploy, nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "does not send notifications when disabled" do
|
28
|
+
HipchatNotification.any_instance.expects(:deliver).never
|
29
|
+
Samson::Hooks.fire(:after_deploy, deploy, nil)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../../../test/test_helper'
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: samson_hipchat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vinh Nguyen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hipchat
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
description:
|
28
|
+
email: vinh@listia.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- app/decorators/stage_decorator.rb
|
34
|
+
- app/models/hipchat_notification.rb
|
35
|
+
- app/models/hipchat_notification_renderer.rb
|
36
|
+
- app/models/hipchat_room.rb
|
37
|
+
- app/views/samson_hipchat/_fields.html.erb
|
38
|
+
- app/views/samson_hipchat/notification.text.erb
|
39
|
+
- config/initializers/hipchat.rb
|
40
|
+
- db/migrate/20150519105221_create_hipchat_rooms.rb
|
41
|
+
- lib/samson_hipchat/samson_plugin.rb
|
42
|
+
- samson_hipchat.gemspec
|
43
|
+
- test/models/hipchat_notification_renderer_test.rb
|
44
|
+
- test/models/hipchat_notification_test.rb
|
45
|
+
- test/models/hooks_test.rb
|
46
|
+
- test/test_helper.rb
|
47
|
+
homepage:
|
48
|
+
licenses: []
|
49
|
+
metadata: {}
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project:
|
66
|
+
rubygems_version: 2.4.7
|
67
|
+
signing_key:
|
68
|
+
specification_version: 4
|
69
|
+
summary: Samson hipchat integration
|
70
|
+
test_files: []
|