Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Hipchat hook #105

Merged
merged 1 commit into from

3 participants

@marcinbunsch

I've prepared a hook for hipchat, with tests for settings and the hook itself.

@antekpiechnik antekpiechnik merged commit 99a3103 into from
@mongrelion

@marcinbunsch Did you notice that the Hipchat hook broke the Ruby 1.8.7 build on Travis CI? https://travis-ci.org/appelier/bigtuna/jobs/2808254

@marcinbunsch

Nope, thanks for the heads up, will try to fix it soon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 16, 2012
  1. @marcinbunsch

    Hipchat hook

    marcinbunsch authored
This page is out of date. Refresh to see the latest.
View
101 lib/big_tuna/hooks/hipchat.rb
@@ -0,0 +1,101 @@
+module BigTuna
+ class Hooks::Hipchat < Hooks::Base
+ NAME = 'hipchat'
+
+ def build_fixed(build, config)
+ enqueue(config, full_msg(build, 'fixed'))
+ end
+
+ def build_still_fails(build, config)
+ enqueue(config, full_msg(build, 'still fails'))
+ end
+
+ def build_failed(build, config)
+ enqueue(config, full_msg(build, 'failed'))
+ end
+
+ class Job
+ require 'net/http'
+ require 'net/https'
+
+ def initialize(config, message)
+ @config = config
+ @message = message
+ end
+
+ def perform
+ response = send_request
+ data = response.body
+ { :message => @message, :room => @config['room_id'], :response => response, :data => data }
+ end
+
+ def send_request
+ request = create_request
+ Net::HTTP.start(uri.host, uri.port, http_options) do |http|
+ http.request request
+ end
+ end
+
+ def create_request
+ req = Net::HTTP::Post.new(uri.path)
+ req.set_form_data(payload)
+ req
+ end
+
+ def uri
+ @uri ||= URI("https://api.hipchat.com/v1/rooms/message")
+ end
+
+ def http_options
+ {
+ :use_ssl => true,
+ :verify_mode => OpenSSL::SSL::VERIFY_NONE
+ }
+ end
+
+ def payload
+ {
+ :format => 'json',
+ :auth_token => @config['token'],
+ :room_id => @config['room_id'],
+ :from => 'Big Tuna',
+ :message => @message,
+ }
+ end
+
+ end
+
+ private
+
+ def enqueue(config, message)
+ Delayed::Job.enqueue(Job.new(config, message))
+ end
+
+ def full_msg(build, status)
+ "Build #{status} in #{build.project.name}: #{commit_info(build)}"
+ end
+
+ def commit_info(build)
+ source = build.project.vcs_source
+ if source.match('github.com')
+ github_commit_link(build)
+ else
+ "#{build.commit_message} (#{build.commit[0..6]} by #{build.author})"
+ end
+ end
+
+ def github_commit_link(build)
+ source = build.project.vcs_source
+ prefix = source.sub('git@github.com:', 'https://github.com/').sub(/\.git$/, '')
+ link = "#{prefix}/commit/#{build.commit}"
+ "<a href=\"#{build_url(build)}\">#{build.commit_message}</a> (commit <a href=\"#{link}\">#{build.commit[0..6]} by #{build.author}</a>)"
+ end
+
+ def build_url(build)
+ url_host = BigTuna.config[:url_host]
+ "http://#{url_host}/builds/#{build.id}"
+ end
+
+ end
+end
+
View
6 lib/big_tuna/hooks/hipchat/_form.html.haml
@@ -0,0 +1,6 @@
+%div
+ = label_tag("token")
+ = text_area_tag("configuration[token]", @hook.configuration["token"])
+%div
+ = label_tag("room_id")
+ = text_area_tag("configuration[room_id]", @hook.configuration["room_id"])
View
21 test/integration/hooks_test.rb
@@ -85,4 +85,25 @@ class HooksTest < ActionController::IntegrationTest
click_button "Edit"
assert_status_code 200
end
+
+ test "hipchat hook has a valid configuration form" do
+ project = project_with_steps({
+ :name => "Koss",
+ :vcs_source => "test/files/repo",
+ :max_builds => 2,
+ :hooks => {"hipchat" => "hipchat"},
+ }, "ls")
+
+ visit edit_project_path(project)
+ within("#hook_hipchat") do
+ click_link "Configure"
+ end
+ assert page.has_field?("configuration_token")
+ assert page.has_field?("configuration_room_id")
+
+ click_button "Edit"
+ assert_status_code 200
+ end
+
end
+
View
108 test/unit/hipchat_hook_test.rb
@@ -0,0 +1,108 @@
+require 'test_helper'
+
+class HipchatHookTest < ActiveSupport::TestCase
+
+ include WithTestRepo
+
+ def setup
+ super
+ stub_request(:post, "https://api.hipchat.com/v1/rooms/message").
+ to_return(:status => 200, :body => "", :headers => {})
+
+ Build.any_instance.stubs(:author).returns('Bob')
+ end
+
+ test "hipchat stating the build failed" do
+ project = hipchat_project_with_steps("ls invalid_file_here")
+ hook = project.hooks.first
+ assert_difference("Delayed::Job.count", +2) do # 1 job + 1 for sending the hipchat message
+ job = project.build!
+ job.invoke_job
+ end
+ build = project.recent_build
+ jobs = run_delayed_jobs()
+
+ result = jobs.last.payload_object.perform
+ commit_sha = build.commit[0..6]
+ assert_equal "Build failed in #{project.name}: #{build.commit_message} (#{commit_sha} by #{build.author})", result[:message]
+ end
+
+ test "hipchat stating build is back to normal" do
+ project = hipchat_project_with_steps("ls invalid_file_here")
+ hook = project.hooks.first
+ project.build!
+ run_delayed_jobs()
+ project.step_lists.first.update_attributes!(:steps => "ls .")
+ project.build!
+
+ jobs = run_delayed_jobs()
+ build = project.recent_build
+ assert_equal 3, jobs.size # 1 project, 1 part, 1 hipchat message
+
+ result = jobs.last.payload_object.perform
+ commit_sha = build.commit[0..6]
+ assert_equal "Build fixed in #{project.name}: #{build.commit_message} (#{commit_sha} by #{build.author})", result[:message]
+ end
+
+ test "hipchat stating build still fails" do
+ project = hipchat_project_with_steps("ls invalid_file_here")
+ hook = project.hooks.first
+ project.build!
+ run_delayed_jobs()
+ project.build!
+
+ jobs = run_delayed_jobs()
+ build = project.recent_build
+ assert_equal 3, jobs.size # 1 project, 1 part, 1 hipchat message
+
+ result = jobs.last.payload_object.perform
+ commit_sha = build.commit[0..6]
+ assert_equal "Build still fails in #{project.name}: #{build.commit_message} (#{commit_sha} by #{build.author})", result[:message]
+ end
+
+ test "when the project is on github, a better message is generated" do
+ project = hipchat_project_with_steps("ls invalid_file_here")
+ hook = project.hooks.first
+ assert_difference("Delayed::Job.count", +2) do # 1 job + 1 for sending the hipchat message
+ job = project.build!
+ job.invoke_job
+ end
+ build = project.recent_build
+ build.project.update_attribute :vcs_source, 'git@github.com:appelier/bigtuna.git'
+ jobs = run_delayed_jobs()
+ result = jobs.last.payload_object.perform
+ commit_sha = build.commit[0..6]
+ assert_match "Build failed in #{project.name}", result[:message]
+ assert_match "https://github.com/appelier/bigtuna/commit/#{build.commit}", result[:message]
+ assert_match "#{build.commit_message}", result[:message]
+ assert_match "#{commit_sha} by #{build.author}", result[:message]
+ end
+
+ test "hipchat does not send when build is ok but was ok before" do
+ project = hipchat_project_with_steps("ls .")
+ project.build!
+ run_delayed_jobs()
+ project.build!
+ jobs = run_delayed_jobs()
+ assert_equal 2, jobs.size
+ end
+
+ private
+ def hipchat_project_with_steps(steps)
+ project = project_with_steps({
+ :name => 'repo',
+ :vcs_source => 'test/files/repo',
+ :vcs_type => 'git',
+ :max_builds => 2,
+ :hooks => {"hipchat" => "hipchat"},
+ }, steps)
+ hook = project.hooks.first
+ hook.configuration = {
+ :room_id => '1234',
+ :token => 'foobar'
+ }
+ hook.save!
+ project
+ end
+end
+
Something went wrong with that request. Please try again.