lita-buildkite 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22989d66ceab9ce1f3a43b3df292832b2cf24d49
4
- data.tar.gz: f4fe23a71981da40f06afda34e4e56b96abaaf66
3
+ metadata.gz: f2d6d1cbb193523fc730a4fca088c95df973b850
4
+ data.tar.gz: 0c7b5cb7886c4d1c158b171a4ede9691ee44cbc6
5
5
  SHA512:
6
- metadata.gz: 4bbe9a2fcc013f1282544a886c5e768eeff3c84f67f1f0ca9ebfe0e4e9b830c6f01b40e6c491726f2922834b3ff55cc9fb150bbc35fc9d88cad6c225dc92cdaf
7
- data.tar.gz: d97d57b6c9bd821a91bbf468aa43463c8d46483104a384ab2dc3e3e5daea7761a371691df57286b0cfb4c6098e764a195122c2aba60854b69d634b3b3d9eb27d
6
+ metadata.gz: bc9b1cd17771c91682069cb3b95055bc3d5297ee9b1ce3e38f09ff4e12097f3d38ce7fe230a8ec26df5a25bbab2cec313e6b422df6455172b0d49c2957a19620
7
+ data.tar.gz: f5aa95d1bafa05f914d192e4ee24ddd059454028ddfc67fc752d3ce7ebfd076be65aab089ac06ebe832bb6943cd3e6787a6e57101f556513730679babbfb9a90
data/README.md CHANGED
@@ -30,6 +30,35 @@ a string of days with no failures, and commiserate when a master branch build fa
30
30
 
31
31
  This handler provides no additional chat commands. Yet.
32
32
 
33
+ ## Lita Events
34
+
35
+ This handler will emit some buildkite events onto the lita event bus, allowing other handlers
36
+ to respond them.
37
+
38
+ Currently, the following events are emitted:
39
+
40
+ * buildkite\_build\_finished
41
+ * buildkite\_job\_finished
42
+
43
+ To respond to the events, write a new handler that looks something like this:
44
+
45
+ class BuildkiteDebugHandler < Lita::Handlers::Handler
46
+ on :buildkite_build_finished, :debug
47
+ on :buildkite_job_finished, :debug
48
+
49
+ def debug(payload)
50
+ event = payload[:event]
51
+
52
+ robot.send_message(target, event.inspect)
53
+ end
54
+
55
+ private
56
+
57
+ def target
58
+ Source.new(room: Lita::Room.find_by_name(config.channel_name) || "general")
59
+ end
60
+ end
61
+
33
62
  ## TODO
34
63
 
35
64
  Possible ideas for new features, either via chat commands or externally triggered events:
@@ -1,5 +1,7 @@
1
1
  require "lita"
2
2
  require 'lita/buildkite_event'
3
+ require 'lita/buildkite_build_finished_event'
4
+ require 'lita/buildkite_job_finished_event'
3
5
 
4
6
  module Lita
5
7
  module Handlers
@@ -10,8 +12,15 @@ module Lita
10
12
  http.post "/buildkite", :buildkite_event
11
13
 
12
14
  def buildkite_event(request, response)
13
- event = BuildkiteEvent.new(request.body.read)
14
- robot.trigger(:buildkite_event, event: event)
15
+ event = BuildkiteEvent.build(request.body.read)
16
+ case event
17
+ when BuildkiteBuildFinishedEvent
18
+ robot.trigger(:buildkite_build_finished, event: event)
19
+ when BuildkiteJobFinishedEvent
20
+ robot.trigger(:buildkite_job_finished, event: event)
21
+ else
22
+ puts "UnsupportedEvent: #{event.class}"
23
+ end
15
24
  end
16
25
 
17
26
  end
@@ -0,0 +1,54 @@
1
+ require 'date'
2
+
3
+ # Value object that wraps raw buildkite webhook data and provides convenience
4
+ # methods for querying it
5
+ class BuildkiteBuildFinishedEvent
6
+ def initialize(data)
7
+ @data = data
8
+ end
9
+
10
+ def name
11
+ @data.fetch("event", "")
12
+ end
13
+
14
+ # deprecated
15
+ def branch
16
+ build_branch
17
+ end
18
+
19
+ # deprecated
20
+ def pipeline
21
+ pipeline_name
22
+ end
23
+
24
+ def pipeline_name
25
+ @data.fetch("pipeline", {}).fetch("name", "")
26
+ end
27
+
28
+ def pipeline_slug
29
+ @data.fetch("pipeline", {}).fetch("slug", "")
30
+ end
31
+
32
+ def passed?
33
+ @data.fetch("build", {}).fetch("state", "") == "passed"
34
+ end
35
+
36
+ def build_branch
37
+ @data.fetch("build", {}).fetch("branch", "")
38
+ end
39
+
40
+ def build_created_at
41
+ value = @data.fetch("build", {}).fetch("created_at", nil)
42
+ value ? DateTime.parse(value).to_time : nil
43
+ end
44
+
45
+ def build_started_at
46
+ value = @data.fetch("build", {}).fetch("started_at", nil)
47
+ value ? DateTime.parse(value).to_time : nil
48
+ end
49
+
50
+ def build_finished_at
51
+ value = @data.fetch("build", {}).fetch("finished_at", nil)
52
+ value ? DateTime.parse(value).to_time : nil
53
+ end
54
+ end
@@ -1,25 +1,18 @@
1
+ require 'lita/buildkite_build_finished_event'
2
+ require 'lita/buildkite_unknown_event'
1
3
  require 'json'
2
4
 
3
- # Value object that wraps raw buildkite webhook data and provides convenience
4
- # methods for querying it
5
5
  class BuildkiteEvent
6
- def initialize(data)
7
- @data = JSON.load(data)
8
- end
9
-
10
- def build_finished?
11
- @data.fetch("build", {}).fetch("finished_at", "") != ""
12
- end
13
-
14
- def branch
15
- @data.fetch("build", {}).fetch("branch", "")
16
- end
17
-
18
- def pipeline
19
- @data.fetch("pipeline", {}).fetch("name", "")
20
- end
6
+ def self.build(string)
7
+ data = JSON.load(string)
21
8
 
22
- def passed?
23
- @data.fetch("build", {}).fetch("state", "") == "passed"
9
+ case data.fetch("event", "")
10
+ when "build.finished" then
11
+ BuildkiteBuildFinishedEvent.new(data)
12
+ when "job.finished" then
13
+ BuildkiteJobFinishedEvent.new(data)
14
+ else
15
+ BuildkiteUnknownEvent.new(data)
16
+ end
24
17
  end
25
18
  end
@@ -0,0 +1,68 @@
1
+ require 'date'
2
+
3
+ # Value object that wraps raw buildkite webhook data and provides convenience
4
+ # methods for querying it
5
+ class BuildkiteJobFinishedEvent
6
+ def initialize(data)
7
+ @data = data
8
+ end
9
+
10
+ def name
11
+ @data.fetch("event", "")
12
+ end
13
+
14
+ def job_name
15
+ @data.fetch("job", {}).fetch("name","")
16
+ end
17
+
18
+ def job_slug
19
+ slugorize(job_name)
20
+ end
21
+
22
+ def job_state
23
+ @data.fetch("job", {}).fetch("state","")
24
+ end
25
+
26
+ def job_started_at
27
+ value = @data.fetch("job", {}).fetch("started_at", nil)
28
+ value ? DateTime.parse(value).to_time : nil
29
+ end
30
+
31
+ def job_finished_at
32
+ value = @data.fetch("job", {}).fetch("finished_at", nil)
33
+ value ? DateTime.parse(value).to_time : nil
34
+ end
35
+
36
+ def agent_name
37
+ @data.fetch("job", {}).fetch("agent",{}).fetch("name","")
38
+ end
39
+
40
+ def agent_hostname
41
+ @data.fetch("job", {}).fetch("agent",{}).fetch("hostname","")
42
+ end
43
+
44
+ def build_branch
45
+ @data.fetch("build", {}).fetch("branch","")
46
+ end
47
+
48
+ def pipeline_name
49
+ @data.fetch("pipeline", {}).fetch("name", "")
50
+ end
51
+
52
+ def pipeline_slug
53
+ @data.fetch("pipeline", {}).fetch("slug", "")
54
+ end
55
+
56
+ private
57
+
58
+ def slugorize(input)
59
+ result = input.to_s.downcase
60
+ result.gsub!(/['|’]/, '') # Remove apostrophes
61
+ result.gsub!('&', 'and') # Replace & with 'and'
62
+ result.gsub!(/[^a-z0-9\-]/, '-') # Get rid of anything we don't like
63
+ result.gsub!(/-+/, '-') # collapse dashes
64
+ result.gsub!(/-$/, '') # trim dashes
65
+ result.gsub!(/^-/, '') # trim dashes
66
+ result
67
+ end
68
+ end
@@ -0,0 +1,10 @@
1
+ class BuildkiteUnknownEvent
2
+ def initialize(data)
3
+ @data = data
4
+ end
5
+
6
+ def name
7
+ @data.fetch("event", "")
8
+ end
9
+
10
+ end
@@ -1,5 +1,5 @@
1
1
  require "lita"
2
- require 'lita/buildkite_event'
2
+ require 'lita/buildkite_build_finished_event'
3
3
  require 'lita/days_since_master_failure_repository'
4
4
 
5
5
  module Lita
@@ -9,12 +9,12 @@ module Lita
9
9
  class DaysSinceMasterFailure < Handler
10
10
  config :channel_name
11
11
 
12
- on :buildkite_event, :timestamp_failure
12
+ on :buildkite_build_finished, :timestamp_failure
13
13
 
14
14
  def timestamp_failure(payload)
15
15
  event = payload[:event]
16
16
 
17
- if event.branch == "master" && event.build_finished?
17
+ if event.branch == "master" && event.name == "build.finished"
18
18
  process_build_finished(event) do |msg|
19
19
  robot.send_message(target, msg)
20
20
  end
@@ -24,11 +24,12 @@ module Lita
24
24
  private
25
25
 
26
26
  def process_build_finished(event, &block)
27
+ repository = DaysSinceMasterFailureRepository.new(redis, event.pipeline)
27
28
  repository.record_result(event.passed?) do |days_since_last_failure, prev_days_since_last_failure|
28
29
  if days_since_last_failure < prev_days_since_last_failure
29
- yield "Oh Oh, #{days_since_last_failure} day(s) since the last master failure"
30
+ yield "Oh Oh, #{days_since_last_failure} day(s) since the last master failure on #{event.pipeline}"
30
31
  elsif days_since_last_failure > prev_days_since_last_failure
31
- yield "Congratulations! #{days_since_last_failure} day(s) since the last master failure"
32
+ yield "Congratulations! #{days_since_last_failure} day(s) since the last master failure on #{event.pipeline}"
32
33
  end
33
34
  end
34
35
  end
@@ -37,10 +38,6 @@ module Lita
37
38
  Source.new(room: Lita::Room.find_by_name(config.channel_name) || "general")
38
39
  end
39
40
 
40
- def repository
41
- @repository ||= DaysSinceMasterFailureRepository.new(redis)
42
- end
43
-
44
41
  end
45
42
 
46
43
  Lita.register_handler(DaysSinceMasterFailure)
@@ -1,8 +1,10 @@
1
1
  # Provides all persistence logic for the DaysSinceMasterFailure handler, insulating
2
2
  # the handler from any knowledge of redis
3
3
  class DaysSinceMasterFailureRepository
4
- def initialize(redis)
4
+ def initialize(redis, pipeline_name)
5
5
  @redis = redis
6
+ @last_failure_key = "last-failure-at-#{pipeline_name}"
7
+ @last_reported_days_key = "last-reported-days-#{pipeline_name}"
6
8
 
7
9
  initialise_last_failure_at_if_not_set
8
10
  end
@@ -24,7 +26,7 @@ class DaysSinceMasterFailureRepository
24
26
  end
25
27
 
26
28
  def touch_last_failure_at
27
- @redis.set("last-failure-at", ::Time.now.to_i)
29
+ @redis.set(@last_failure_key, ::Time.now.to_i)
28
30
  end
29
31
 
30
32
  def touch_last_reported_days
@@ -32,18 +34,18 @@ class DaysSinceMasterFailureRepository
32
34
  end
33
35
 
34
36
  def fetch_last_failure_at
35
- @redis.get("last-failure-at").to_i
37
+ @redis.get(@last_failure_key).to_i
36
38
  end
37
39
 
38
40
  def set_last_reported_days(days)
39
- @redis.set("last-reported-days", days.to_i)
41
+ @redis.set(@last_reported_days_key, days.to_i)
40
42
  end
41
43
 
42
44
  def last_reported_days
43
- @redis.get("last-reported-days").to_i
45
+ @redis.get(@last_reported_days_key).to_i
44
46
  end
45
47
 
46
48
  def initialise_last_failure_at_if_not_set
47
- @redis.setnx("last-failure-at", ::Time.now.to_i)
49
+ @redis.setnx(@last_failure_key, ::Time.now.to_i)
48
50
  end
49
51
  end
@@ -1,4 +1,5 @@
1
1
  require 'lita/buildkite'
2
- require 'lita/buildkite_event'
2
+ require 'lita/buildkite_build_finished_event'
3
+ require 'lita/buildkite_job_finished_event'
3
4
  require 'lita/days_since_master_failure'
4
5
  require 'lita/days_since_master_failure_repository'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lita-buildkite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Healy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-14 00:00:00.000000000 Z
11
+ date: 2016-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -94,7 +94,10 @@ files:
94
94
  - README.md
95
95
  - lib/lita-buildkite.rb
96
96
  - lib/lita/buildkite.rb
97
+ - lib/lita/buildkite_build_finished_event.rb
97
98
  - lib/lita/buildkite_event.rb
99
+ - lib/lita/buildkite_job_finished_event.rb
100
+ - lib/lita/buildkite_unknown_event.rb
98
101
  - lib/lita/days_since_master_failure.rb
99
102
  - lib/lita/days_since_master_failure_repository.rb
100
103
  homepage: http://github.com/conversation/lita-buildkite