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 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,3 @@
1
+ class HipchatRoom < ActiveRecord::Base
2
+ belongs_to :stage
3
+ 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, &notify
22
+ Samson::Hooks.callback :after_deploy, &notify
@@ -0,0 +1,7 @@
1
+ Gem::Specification.new "samson_hipchat", "0.0.1" do |s|
2
+ s.summary = "Samson hipchat integration"
3
+ s.authors = ["Vinh Nguyen"]
4
+ s.email = "vinh@listia.com"
5
+ s.add_runtime_dependency "hipchat", "~> 1.5"
6
+ s.files = `git ls-files`.split("\n")
7
+ end
@@ -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
@@ -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: []