lita-buildkite 0.1.0 → 0.2.0

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 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