buildkite-trace 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +78 -0
- data/images/build-chart.png +0 -0
- data/images/build-waterfall.png +0 -0
- data/lib/buildkite-trace.rb +7 -0
- data/lib/buildkite/trace/app.rb +31 -0
- data/lib/buildkite/trace/build_finished_event.rb +82 -0
- data/lib/buildkite/trace/client.rb +22 -0
- data/lib/buildkite/trace/event.rb +24 -0
- data/lib/buildkite/trace/job_finished_event.rb +106 -0
- data/lib/buildkite/trace/span.rb +40 -0
- data/lib/buildkite/trace/unknown_event.rb +18 -0
- data/spec/buildkite/trace/build_finished_event_spec.rb +85 -0
- data/spec/buildkite/trace/client_spec.rb +15 -0
- data/spec/buildkite/trace/event_spec.rb +31 -0
- data/spec/buildkite/trace/job_finished_event_spec.rb +109 -0
- data/spec/buildkite/trace/span_spec.rb +9 -0
- data/spec/fixtures/buildkite_build_finished.json +91 -0
- data/spec/fixtures/buildkite_job_finished.json +141 -0
- data/spec/spec_helper.rb +1 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0abdf59a8b25b2e696d5d05d5d3710df8e251f553e0cdaf245a17defae0cea06
|
4
|
+
data.tar.gz: c5b92901cd2428a65cbabb494bcef17347818f6768f80d2ea42f14c22ef52311
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 393328b187032c748ecb7d9a393ad2eeec7393d18ed226e0bf5987dd8be3747afbfe99396d23da2232fada8649c72e9c94c8e1ae3be346383015162bc08f4bb6
|
7
|
+
data.tar.gz: c8c0f9a4052728b2eb3152fbfa0169dbdfa17e29eff93e5d29b9833a39df976cf91ab8e43ddb54c15b74b83454f3e3bdde61b0051a29213f031825beb254f3d8
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2019 James Healy
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
## buildkite-trace
|
2
|
+
|
3
|
+
If you want to get your build time under control, first you need to measure it.
|
4
|
+
|
5
|
+
This is a mini rack app that accepts buildkite webhooks and submits them to a datadog agent as traces.
|
6
|
+
|
7
|
+
The traces become available in the datadog web UI, and look something like this:
|
8
|
+
|
9
|
+
![Build waterfall](images/build-waterfall.png)
|
10
|
+
|
11
|
+
The spans in the trace also generate metrics that can be used in dashboards and monitors:
|
12
|
+
|
13
|
+
![Build chart](images/build-chart.png)
|
14
|
+
|
15
|
+
### Usage
|
16
|
+
|
17
|
+
Begin by adding buildkite-trace to your `Gemfile`.
|
18
|
+
|
19
|
+
gem "buildite-trace"
|
20
|
+
|
21
|
+
Then create a `config.ru` file in the same directory, with the following content:
|
22
|
+
|
23
|
+
require 'buildkite-trace'
|
24
|
+
run Buildkite::Trace::App
|
25
|
+
|
26
|
+
Finally, run this:
|
27
|
+
|
28
|
+
bundle exec rackup
|
29
|
+
|
30
|
+
If you have an alternative method of running rack apps, that should work fine
|
31
|
+
too. A popular option is puma - add it to your Gemfile (`gem "puma"`), and
|
32
|
+
start the server with:
|
33
|
+
|
34
|
+
bundle exec puma
|
35
|
+
|
36
|
+
### Deployment
|
37
|
+
|
38
|
+
The app should be deployed to a public webserver somewhere, with a domain name
|
39
|
+
and (ideally) TLS enabled.
|
40
|
+
|
41
|
+
Once deployed, use the web UI on buildkite.com to send webhooks to:
|
42
|
+
|
43
|
+
https://yourdomain.example.com/events
|
44
|
+
|
45
|
+
In the webhook settings on buildkite.com, enable at least the following events:
|
46
|
+
|
47
|
+
* `build.finished`
|
48
|
+
* `job.finished`
|
49
|
+
|
50
|
+
The deployed service must have access to an instance of the datadog agent. Each
|
51
|
+
time it receives a webhook from buildkite, it'll translate it into trace data
|
52
|
+
that's sent to the datadog agent at `http://<dd-agent-ip>:8126/`
|
53
|
+
|
54
|
+
### Configuration
|
55
|
+
|
56
|
+
There is only one configurable value at this stage - the IP or hostname of the
|
57
|
+
datadog agent. To override the default (`127.0.0.1`) set the
|
58
|
+
`DATADOG_AGENT_HOST_IP` ENV var.
|
59
|
+
|
60
|
+
### Developing
|
61
|
+
|
62
|
+
I typically use docker to setup a consistent development. You can start a
|
63
|
+
development server like this:
|
64
|
+
|
65
|
+
./auto/start
|
66
|
+
|
67
|
+
... and post sample webhooks to it:
|
68
|
+
|
69
|
+
curl -v --data @spec/fixtures/buildkite_job_finished.json http://127.0.0.1:9393/events
|
70
|
+
curl -v --data @spec/fixtures/buildkite_build_finished.json http://127.0.0.1:9393/events
|
71
|
+
|
72
|
+
You'll need to have a datadog agent listening for traces on
|
73
|
+
http://127.0.0.1:8126, or you'll get a "Errno::ECONNREFUSED: Failed to open TCP
|
74
|
+
connection to 127.0.0.1:8126" exception.
|
75
|
+
|
76
|
+
To run the tests:
|
77
|
+
|
78
|
+
./auto/test
|
Binary file
|
Binary file
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require 'buildkite/trace/build_finished_event'
|
2
|
+
require 'buildkite/trace/job_finished_event'
|
3
|
+
require 'buildkite/trace/unknown_event'
|
4
|
+
require 'buildkite/trace/event'
|
5
|
+
require 'buildkite/trace/span'
|
6
|
+
require 'buildkite/trace/app'
|
7
|
+
require 'buildkite/trace/client'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'buildkite/trace/event'
|
3
|
+
require 'buildkite/trace/client'
|
4
|
+
|
5
|
+
module Buildkite
|
6
|
+
module Trace
|
7
|
+
class App < Sinatra::Application
|
8
|
+
get '/' do
|
9
|
+
'Buildkite Trace Server'
|
10
|
+
end
|
11
|
+
|
12
|
+
post '/events' do
|
13
|
+
request.body.rewind
|
14
|
+
data = request.body.read
|
15
|
+
event = Buildkite::Trace::Event.build(data)
|
16
|
+
span = event.to_span
|
17
|
+
if span
|
18
|
+
puts span.to_hash.inspect
|
19
|
+
trace_client = Buildkite::Trace::Client.new(datadog_hostname)
|
20
|
+
trace_client.submit_trace([span.to_hash])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def datadog_hostname
|
27
|
+
ENV.fetch("DATADOG_AGENT_HOST_IP", "127.0.0.1")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'buildkite/trace/span'
|
3
|
+
require 'digest/crc64'
|
4
|
+
|
5
|
+
module Buildkite
|
6
|
+
module Trace
|
7
|
+
|
8
|
+
# Value object that wraps raw buildkite webhook data and provides convenience
|
9
|
+
# methods for querying it
|
10
|
+
class BuildFinishedEvent
|
11
|
+
def initialize(data)
|
12
|
+
@data = data
|
13
|
+
end
|
14
|
+
|
15
|
+
def name
|
16
|
+
@data.fetch("event", "")
|
17
|
+
end
|
18
|
+
|
19
|
+
def pipeline_name
|
20
|
+
@data.fetch("pipeline", {}).fetch("name", "")
|
21
|
+
end
|
22
|
+
|
23
|
+
def pipeline_slug
|
24
|
+
@data.fetch("pipeline", {}).fetch("slug", "")
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_id
|
28
|
+
@data.fetch("build", {}).fetch("id", "")
|
29
|
+
end
|
30
|
+
|
31
|
+
def build_web_url
|
32
|
+
@data.fetch("build", {}).fetch("web_url", "")
|
33
|
+
end
|
34
|
+
|
35
|
+
def passed?
|
36
|
+
@data.fetch("build", {}).fetch("state", "") == "passed"
|
37
|
+
end
|
38
|
+
|
39
|
+
def build_branch
|
40
|
+
@data.fetch("build", {}).fetch("branch", "")
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_created_at
|
44
|
+
value = @data.fetch("build", {}).fetch("created_at", nil)
|
45
|
+
value ? DateTime.parse(value).to_time : nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_started_at
|
49
|
+
value = @data.fetch("build", {}).fetch("started_at", nil)
|
50
|
+
value ? DateTime.parse(value).to_time : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def build_finished_at
|
54
|
+
value = @data.fetch("build", {}).fetch("finished_at", nil)
|
55
|
+
value ? DateTime.parse(value).to_time : nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_span
|
59
|
+
Span.new(
|
60
|
+
trace_id: Digest::CRC64.checksum(build_id),
|
61
|
+
span_id: Digest::CRC64.checksum(build_id) + 1,
|
62
|
+
parent_id: nil,
|
63
|
+
name: "build",
|
64
|
+
resource: pipeline_slug,
|
65
|
+
service: "buildkite",
|
66
|
+
type: "custom",
|
67
|
+
start: build_started_at.to_i * 1_000_000_000,
|
68
|
+
duration: duration_in_secs * 1_000_000_000,
|
69
|
+
metrics: {_sampling_priority_v1: 2},
|
70
|
+
meta: {url: build_web_url, pipeline: pipeline_slug},
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def duration_in_secs
|
77
|
+
build_finished_at.to_i - build_started_at.to_i
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module Buildkite
|
4
|
+
module Trace
|
5
|
+
class Client
|
6
|
+
def initialize(hostname)
|
7
|
+
@uri = URI("http://#{hostname}:8126/v0.3/traces")
|
8
|
+
end
|
9
|
+
|
10
|
+
def submit_trace(array_of_spans)
|
11
|
+
array_of_traces = [array_of_spans]
|
12
|
+
http = Net::HTTP.new(@uri.host, 8126)
|
13
|
+
response = http.start do |http|
|
14
|
+
request = Net::HTTP::Put.new(@uri.request_uri, { 'Content-Type' => 'application/json'})
|
15
|
+
request.body = JSON.dump(array_of_traces)
|
16
|
+
http.request(request)
|
17
|
+
end
|
18
|
+
response.code.to_i == 200
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'buildkite/trace/build_finished_event'
|
2
|
+
require 'buildkite/trace/unknown_event'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Buildkite
|
6
|
+
module Trace
|
7
|
+
class Event
|
8
|
+
def self.build(string)
|
9
|
+
data = JSON.load(string)
|
10
|
+
|
11
|
+
case data.fetch("event", "")
|
12
|
+
when "build.finished" then
|
13
|
+
BuildFinishedEvent.new(data)
|
14
|
+
when "job.finished" then
|
15
|
+
JobFinishedEvent.new(data)
|
16
|
+
else
|
17
|
+
UnknownEvent.new(data)
|
18
|
+
end
|
19
|
+
rescue JSON::ParserError
|
20
|
+
UnknownEvent.new("event" => "error", "message" => "Invalid JSON", "body" => string)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'buildkite/trace/span'
|
3
|
+
require 'digest/crc64'
|
4
|
+
|
5
|
+
module Buildkite
|
6
|
+
module Trace
|
7
|
+
# Value object that wraps raw buildkite webhook data and provides convenience
|
8
|
+
# methods for querying it
|
9
|
+
class JobFinishedEvent
|
10
|
+
def initialize(data)
|
11
|
+
@data = data
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
@data.fetch("event", "")
|
16
|
+
end
|
17
|
+
|
18
|
+
def job_id
|
19
|
+
@data.fetch("job", {}).fetch("id","")
|
20
|
+
end
|
21
|
+
|
22
|
+
def job_name
|
23
|
+
@data.fetch("job", {}).fetch("name","")
|
24
|
+
end
|
25
|
+
|
26
|
+
def job_slug
|
27
|
+
slugorize(job_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def job_state
|
31
|
+
@data.fetch("job", {}).fetch("state","")
|
32
|
+
end
|
33
|
+
|
34
|
+
def job_web_url
|
35
|
+
@data.fetch("job", {}).fetch("web_url","")
|
36
|
+
end
|
37
|
+
|
38
|
+
def job_started_at
|
39
|
+
value = @data.fetch("job", {}).fetch("started_at", nil)
|
40
|
+
value ? DateTime.parse(value).to_time : nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def job_finished_at
|
44
|
+
value = @data.fetch("job", {}).fetch("finished_at", nil)
|
45
|
+
value ? DateTime.parse(value).to_time : nil
|
46
|
+
end
|
47
|
+
|
48
|
+
def agent_name
|
49
|
+
@data.fetch("job", {}).fetch("agent",{}).fetch("name","")
|
50
|
+
end
|
51
|
+
|
52
|
+
def agent_hostname
|
53
|
+
@data.fetch("job", {}).fetch("agent",{}).fetch("hostname","")
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_id
|
57
|
+
@data.fetch("build", {}).fetch("id","")
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_branch
|
61
|
+
@data.fetch("build", {}).fetch("branch","")
|
62
|
+
end
|
63
|
+
|
64
|
+
def pipeline_name
|
65
|
+
@data.fetch("pipeline", {}).fetch("name", "")
|
66
|
+
end
|
67
|
+
|
68
|
+
def pipeline_slug
|
69
|
+
@data.fetch("pipeline", {}).fetch("slug", "")
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_span
|
73
|
+
Span.new(
|
74
|
+
trace_id: Digest::CRC64.checksum(build_id),
|
75
|
+
span_id: Digest::CRC64.checksum(job_id),
|
76
|
+
parent_id: Digest::CRC64.checksum(build_id) + 1,
|
77
|
+
name: "build.job",
|
78
|
+
resource: job_name,
|
79
|
+
service: "buildkite",
|
80
|
+
type: "custom",
|
81
|
+
start: job_started_at.to_i * 1_000_000_000,
|
82
|
+
duration: duration_in_secs * 1_000_000_000,
|
83
|
+
metrics: {_sampling_priority_v1: 2},
|
84
|
+
meta: {url: job_web_url, pipeline: pipeline_slug},
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def duration_in_secs
|
91
|
+
job_finished_at.to_i - job_started_at.to_i
|
92
|
+
end
|
93
|
+
|
94
|
+
def slugorize(input)
|
95
|
+
result = input.to_s.downcase
|
96
|
+
result.gsub!(/['|’]/, '') # Remove apostrophes
|
97
|
+
result.gsub!('&', 'and') # Replace & with 'and'
|
98
|
+
result.gsub!(/[^a-z0-9\-]/, '-') # Get rid of anything we don't like
|
99
|
+
result.gsub!(/-+/, '-') # collapse dashes
|
100
|
+
result.gsub!(/-$/, '') # trim dashes
|
101
|
+
result.gsub!(/^-/, '') # trim dashes
|
102
|
+
result
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Buildkite
|
2
|
+
module Trace
|
3
|
+
# A value object to hold the data we will submit to datadog
|
4
|
+
class Span
|
5
|
+
attr_reader :trace_id, :span_id, :parent_id, :name, :resource
|
6
|
+
attr_reader :service, :type, :start, :duration, :metrics, :meta
|
7
|
+
|
8
|
+
def initialize(trace_id:, span_id:, parent_id:, name:, resource:, service:, type:, start:, duration:, metrics:, meta:)
|
9
|
+
@trace_id = trace_id
|
10
|
+
@span_id = span_id
|
11
|
+
@parent_id = parent_id
|
12
|
+
@name = name
|
13
|
+
@resource = resource
|
14
|
+
@service = service
|
15
|
+
@type = type
|
16
|
+
@start = start
|
17
|
+
@duration = duration
|
18
|
+
@metrics = metrics
|
19
|
+
@meta = meta
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_hash
|
23
|
+
{
|
24
|
+
trace_id: trace_id,
|
25
|
+
span_id: span_id,
|
26
|
+
parent_id: parent_id,
|
27
|
+
name: name,
|
28
|
+
resource: resource,
|
29
|
+
service: service,
|
30
|
+
type: @type,
|
31
|
+
start: start,
|
32
|
+
duration: duration,
|
33
|
+
metrics: metrics,
|
34
|
+
meta: meta,
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
describe Buildkite::Trace::BuildFinishedEvent do
|
4
|
+
let(:json_path) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "buildkite_build_finished.json")}
|
5
|
+
let(:json) { JSON.load(File.read(json_path)) }
|
6
|
+
let(:event) { Buildkite::Trace::BuildFinishedEvent.new(json)}
|
7
|
+
|
8
|
+
describe '.name' do
|
9
|
+
it "returns the correct value" do
|
10
|
+
expect(event.name).to eq "build.finished"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.build_id' do
|
15
|
+
it "returns the correct value" do
|
16
|
+
expect(event.build_id).to eq "83636ec4-0643-4d4b-9576-4b4cc9416dbc"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.build_branch' do
|
21
|
+
it "returns the branch name" do
|
22
|
+
expect(event.build_branch).to eq "master"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '.pipeline_name' do
|
27
|
+
it "returns the pipeline name" do
|
28
|
+
expect(event.pipeline_name).to eq "Bar"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '.pipeline_slug' do
|
33
|
+
it "returns the pipeline name" do
|
34
|
+
expect(event.pipeline_slug).to eq "bar"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '.build_web_url' do
|
39
|
+
it "returns with the build web_url" do
|
40
|
+
expect(event.build_web_url).to eq "https://buildkite.com/foo/bar/builds/4472"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.passed?' do
|
45
|
+
it "returns false" do
|
46
|
+
expect(event.passed?).to eq false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'build_created_at' do
|
51
|
+
it "returns correct time" do
|
52
|
+
expect(event.build_created_at).to eq Time.utc(2018,12,28,13,3,28)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'build_started_at' do
|
57
|
+
it "returns correct time" do
|
58
|
+
expect(event.build_started_at).to eq Time.utc(2018,12,28,13,3,32)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'build_finished_at' do
|
63
|
+
it "returns correct time" do
|
64
|
+
expect(event.build_finished_at).to eq Time.utc(2018,12,28,13,29,38)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '.to_span' do
|
69
|
+
let(:span) { event.to_span }
|
70
|
+
|
71
|
+
it "returns a Span instance with the correct values" do
|
72
|
+
expect(span.trace_id).to eq(18259648613135438764)
|
73
|
+
expect(span.span_id).to eq(18259648613135438765)
|
74
|
+
expect(span.parent_id).to be_nil
|
75
|
+
expect(span.name).to eq("build")
|
76
|
+
expect(span.resource).to eq("bar")
|
77
|
+
expect(span.service).to eq("buildkite")
|
78
|
+
expect(span.type).to eq("custom")
|
79
|
+
expect(span.start).to eq(1546002212000000000)
|
80
|
+
expect(span.duration).to eq(1_566_000_000_000)
|
81
|
+
expect(span.metrics).to eq({_sampling_priority_v1: 2})
|
82
|
+
expect(span.meta).to eq({:pipeline=>"bar", :url=>"https://buildkite.com/foo/bar/builds/4472"})
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
describe Buildkite::Trace::Client do
|
4
|
+
|
5
|
+
describe ".submit_trace" do
|
6
|
+
context "with valid trace data" do
|
7
|
+
it "submits the trace data to the datadog agent"
|
8
|
+
it "returns true"
|
9
|
+
end
|
10
|
+
context "with invalid trace data" do
|
11
|
+
it "returns false"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
describe Buildkite::Trace::Event do
|
4
|
+
let(:json) { JSON.dump(data) }
|
5
|
+
let(:event) { Buildkite::Trace::Event.build(json)}
|
6
|
+
|
7
|
+
context "with a build finished event" do
|
8
|
+
let(:data) { { "event" => "build.finished"} }
|
9
|
+
|
10
|
+
it "returns the correct object" do
|
11
|
+
expect(event).to be_a(Buildkite::Trace::BuildFinishedEvent)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "with a job finished event" do
|
16
|
+
let(:data) { { "event" => "job.finished"} }
|
17
|
+
|
18
|
+
it "returns the correct object" do
|
19
|
+
expect(event).to be_a(Buildkite::Trace::JobFinishedEvent)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "with another event" do
|
24
|
+
let(:data) { { "event" => "foo"} }
|
25
|
+
|
26
|
+
it "returns the correct object" do
|
27
|
+
expect(event).to be_a(Buildkite::Trace::UnknownEvent)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
describe Buildkite::Trace::JobFinishedEvent do
|
4
|
+
let(:json_path) { File.join(File.dirname(__FILE__), "..", "..", "fixtures", "buildkite_job_finished.json")}
|
5
|
+
let(:json) { JSON.load(File.read(json_path)) }
|
6
|
+
let(:event) { Buildkite::Trace::JobFinishedEvent.new(json)}
|
7
|
+
|
8
|
+
describe '.name' do
|
9
|
+
it "returns the correct value" do
|
10
|
+
expect(event.name).to eq "job.finished"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.job_id' do
|
15
|
+
it "returns the job id" do
|
16
|
+
expect(event.job_id).to eq "db30e1c2-7200-49db-b3f3-85edcbedec6e"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.job_name' do
|
21
|
+
it "returns the job name" do
|
22
|
+
expect(event.job_name).to eq ":rspec: Run Spec Group 1"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '.job_slug' do
|
27
|
+
it "returns the job slug" do
|
28
|
+
expect(event.job_slug).to eq "rspec-run-spec-group-1"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '.job_state' do
|
33
|
+
it "returns the job state" do
|
34
|
+
expect(event.job_state).to eq "passed"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '.job_web_url' do
|
39
|
+
it "returns the job URL" do
|
40
|
+
expect(event.job_web_url).to eq "https://buildkite.com/foo/bar/builds/4474#db30e1c2-7200-49db-b3f3-85edcbedec6e"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.job_started_at' do
|
45
|
+
it "returns the correct time" do
|
46
|
+
expect(event.job_started_at).to eq Time.utc(2018,12,28,13,23,43)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '.job_finished_at' do
|
51
|
+
it "returns the correct time" do
|
52
|
+
expect(event.job_finished_at).to eq Time.utc(2018,12,28,13,26,11)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '.agent_name' do
|
57
|
+
it "returns the agent name" do
|
58
|
+
expect(event.agent_name).to eq "build-robot-himem-5cd88946-g74t6-1"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '.agent_hostname' do
|
63
|
+
it "returns the agent hostname" do
|
64
|
+
expect(event.agent_hostname).to eq "build-robot-himem-5cd88946-g74t6"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '.build_id' do
|
69
|
+
it "returns the build id" do
|
70
|
+
expect(event.build_id).to eq "464b5536-643c-4d70-bdaf-cb50660099f5"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '.build_branch' do
|
75
|
+
it "returns the build branch name" do
|
76
|
+
expect(event.build_branch).to eq "master"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '.pipeline_name' do
|
81
|
+
it "returns the pipeline name" do
|
82
|
+
expect(event.pipeline_name).to eq "Bar"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '.pipeline_slug' do
|
87
|
+
it "returns the pipeline slug" do
|
88
|
+
expect(event.pipeline_slug).to eq "bar"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '.to_span' do
|
93
|
+
let(:span) { event.to_span }
|
94
|
+
|
95
|
+
it "returns a Span instance with the correct values" do
|
96
|
+
expect(span.trace_id).to eq(16600268248679578299)
|
97
|
+
expect(span.span_id).to eq(3724764218537855423)
|
98
|
+
expect(span.parent_id).to eq(16600268248679578300)
|
99
|
+
expect(span.name).to eq("build.job")
|
100
|
+
expect(span.resource).to eq(":rspec: Run Spec Group 1")
|
101
|
+
expect(span.service).to eq("buildkite")
|
102
|
+
expect(span.type).to eq("custom")
|
103
|
+
expect(span.start).to eq(1546003423000000000)
|
104
|
+
expect(span.duration).to eq(148_000_000_000)
|
105
|
+
expect(span.metrics).to eq({_sampling_priority_v1: 2})
|
106
|
+
expect(span.meta).to eq({:pipeline=>"bar", :url=>"https://buildkite.com/foo/bar/builds/4474#db30e1c2-7200-49db-b3f3-85edcbedec6e"})
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
{
|
2
|
+
"event": "build.finished",
|
3
|
+
"build": {
|
4
|
+
"id": "83636ec4-0643-4d4b-9576-4b4cc9416dbc",
|
5
|
+
"url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds/4472",
|
6
|
+
"web_url": "https://buildkite.com/foo/bar/builds/4472",
|
7
|
+
"number": 4472,
|
8
|
+
"state": "failed",
|
9
|
+
"blocked": false,
|
10
|
+
"message": "exp: will avoiding JS execution make this more reliable?",
|
11
|
+
"commit": "dbf58b93b46ae0ec2b82d85fe98f5925a946837a",
|
12
|
+
"branch": "master",
|
13
|
+
"tag": null,
|
14
|
+
"source": "webhook",
|
15
|
+
"creator": {
|
16
|
+
"id": "f98b5507-d9ca-4711-b5bb-f2bf145b9d13",
|
17
|
+
"name": "James Healy",
|
18
|
+
"email": "james@yob.id.au",
|
19
|
+
"avatar_url": "https://www.gravatar.com/avatar/febab66d54b972e5f3c04a70a5feb5b5",
|
20
|
+
"created_at": "2018-03-27 05:47:37 UTC"
|
21
|
+
},
|
22
|
+
"created_at": "2018-12-28 13:03:28 UTC",
|
23
|
+
"scheduled_at": "2018-12-28 13:03:28 UTC",
|
24
|
+
"started_at": "2018-12-28 13:03:32 UTC",
|
25
|
+
"finished_at": "2018-12-28 13:29:38 UTC",
|
26
|
+
"meta_data": {
|
27
|
+
"buildkite:git:commit": "commit dbf58b93b46ae0ec2b82d85fe98f5925a946837a\nAuthor: James Healy <james@yob.id.au>\nAuthorDate: Sat Dec 29 00:02:56 2018 +1100\nCommit: James Healy <james@yob.id.au>\nCommitDate: Sat Dec 29 00:02:56 2018 +1100\n\n exp: will avoiding JS execution make this more reliable?"
|
28
|
+
},
|
29
|
+
"pull_request": null
|
30
|
+
},
|
31
|
+
"pipeline": {
|
32
|
+
"id": "f7e3be00-737a-4832-8646-11ae7fad909b",
|
33
|
+
"url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar",
|
34
|
+
"web_url": "https://buildkite.com/foo/bar",
|
35
|
+
"name": "Bar",
|
36
|
+
"description": "",
|
37
|
+
"slug": "bar",
|
38
|
+
"repository": "git@github.com:yob/bar.git",
|
39
|
+
"branch_configuration": "",
|
40
|
+
"default_branch": "master",
|
41
|
+
"skip_queued_branch_builds": true,
|
42
|
+
"skip_queued_branch_builds_filter": "",
|
43
|
+
"cancel_running_branch_builds": false,
|
44
|
+
"cancel_running_branch_builds_filter": "",
|
45
|
+
"provider": {
|
46
|
+
"id": "github",
|
47
|
+
"settings": {
|
48
|
+
"trigger_mode": "code",
|
49
|
+
"build_pull_requests": true,
|
50
|
+
"pull_request_branch_filter_enabled": false,
|
51
|
+
"skip_pull_request_builds_for_existing_commits": true,
|
52
|
+
"build_pull_request_forks": false,
|
53
|
+
"prefix_pull_request_fork_branch_names": false,
|
54
|
+
"build_tags": false,
|
55
|
+
"publish_commit_status": true,
|
56
|
+
"publish_commit_status_per_step": false,
|
57
|
+
"separate_pull_request_statuses": false,
|
58
|
+
"publish_blocked_as_pending": false,
|
59
|
+
"repository": "yob/bar",
|
60
|
+
"pull_request_branch_filter_configuration": ""
|
61
|
+
},
|
62
|
+
"webhook_url": "https://webhook.buildkite.com/deliver/849a6755fd449c310b936150fd3585e42070c1712b7c52f757"
|
63
|
+
},
|
64
|
+
"builds_url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds",
|
65
|
+
"badge_url": "https://badge.buildkite.com/12de09c168b7ad23e83e96c62be7698f3d1102faea93b60803.svg",
|
66
|
+
"created_at": "2016-05-25 04:34:52 UTC",
|
67
|
+
"scheduled_builds_count": 0,
|
68
|
+
"running_builds_count": 1,
|
69
|
+
"scheduled_jobs_count": 4,
|
70
|
+
"running_jobs_count": 6,
|
71
|
+
"waiting_jobs_count": 0,
|
72
|
+
"steps": [
|
73
|
+
{
|
74
|
+
"type": "script",
|
75
|
+
"name": ":pipeline:",
|
76
|
+
"command": ".buildkite/upload-pipeline",
|
77
|
+
"artifact_paths": "",
|
78
|
+
"branch_configuration": "",
|
79
|
+
"env": {},
|
80
|
+
"timeout_in_minutes": null,
|
81
|
+
"agent_query_rules": [],
|
82
|
+
"concurrency": null,
|
83
|
+
"parallelism": null
|
84
|
+
}
|
85
|
+
]
|
86
|
+
},
|
87
|
+
"sender": {
|
88
|
+
"id": "f98b5507-d9ca-4711-b5bb-f2bf145b9d13",
|
89
|
+
"name": "James Healy"
|
90
|
+
}
|
91
|
+
}
|
@@ -0,0 +1,141 @@
|
|
1
|
+
{
|
2
|
+
"event": "job.finished",
|
3
|
+
"job": {
|
4
|
+
"id": "db30e1c2-7200-49db-b3f3-85edcbedec6e",
|
5
|
+
"type": "script",
|
6
|
+
"name": ":rspec: Run Spec Group 1",
|
7
|
+
"agent_query_rules": [
|
8
|
+
"queue=default"
|
9
|
+
],
|
10
|
+
"state": "passed",
|
11
|
+
"build_url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds/4474",
|
12
|
+
"web_url": "https://buildkite.com/foo/bar/builds/4474#db30e1c2-7200-49db-b3f3-85edcbedec6e",
|
13
|
+
"log_url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds/4474/jobs/db30e1c2-7200-49db-b3f3-85edcbedec6e/log",
|
14
|
+
"raw_log_url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds/4474/jobs/db30e1c2-7200-49db-b3f3-85edcbedec6e/log.txt",
|
15
|
+
"artifacts_url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds/4474/jobs/db30e1c2-7200-49db-b3f3-85edcbedec6e/artifacts",
|
16
|
+
"command": "./auto/run-tests",
|
17
|
+
"exit_status": 0,
|
18
|
+
"artifact_paths": "reports/*;",
|
19
|
+
"agent": {
|
20
|
+
"id": "673cacbc-1920-4b4b-8673-a9a0beb87822",
|
21
|
+
"url": "https://api.buildkite.com/v2/organizations/foo/agents/673cacbc-1920-4b4b-8673-a9a0beb87822",
|
22
|
+
"web_url": "https://buildkite.com/organizations/foo/agents/673cacbc-1920-4b4b-8673-a9a0beb87822",
|
23
|
+
"name": "build-robot-himem-5cd88946-g74t6-1",
|
24
|
+
"connection_state": "connected",
|
25
|
+
"ip_address": "35.189.61.14",
|
26
|
+
"hostname": "build-robot-himem-5cd88946-g74t6",
|
27
|
+
"user_agent": "buildkite-agent/3.6.0.2618 (linux; amd64)",
|
28
|
+
"version": "3.6.0",
|
29
|
+
"creator": null,
|
30
|
+
"created_at": "2018-12-28 12:19:02 UTC",
|
31
|
+
"job": null,
|
32
|
+
"last_job_finished_at": "2018-12-28 13:26:11 UTC",
|
33
|
+
"priority": 0,
|
34
|
+
"meta_data": [
|
35
|
+
"queue=default",
|
36
|
+
"himem=true"
|
37
|
+
]
|
38
|
+
},
|
39
|
+
"created_at": "2018-12-28 13:21:40 UTC",
|
40
|
+
"scheduled_at": "2018-12-28 13:17:08 UTC",
|
41
|
+
"started_at": "2018-12-28 13:23:43 UTC",
|
42
|
+
"finished_at": "2018-12-28 13:26:11 UTC",
|
43
|
+
"runnable_at": "2018-12-28 13:21:40 UTC",
|
44
|
+
"retried": false,
|
45
|
+
"retried_in_job_id": null,
|
46
|
+
"retries_count": null,
|
47
|
+
"parallel_group_index": 1,
|
48
|
+
"parallel_group_total": 5
|
49
|
+
},
|
50
|
+
"build": {
|
51
|
+
"id": "464b5536-643c-4d70-bdaf-cb50660099f5",
|
52
|
+
"url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds/4474",
|
53
|
+
"web_url": "https://buildkite.com/foo/bar/builds/4474",
|
54
|
+
"number": 4474,
|
55
|
+
"state": "running",
|
56
|
+
"blocked": false,
|
57
|
+
"message": "exp: will avoiding JS execution make this more reliable?",
|
58
|
+
"commit": "f9df15515206cf6d0ae552391b364fb3414c7958",
|
59
|
+
"branch": "master",
|
60
|
+
"tag": null,
|
61
|
+
"source": "webhook",
|
62
|
+
"creator": {
|
63
|
+
"id": "f98b5507-d9ca-4711-b5bb-f2bf145b9d13",
|
64
|
+
"name": "James Healy",
|
65
|
+
"email": "james@yob.id.au",
|
66
|
+
"avatar_url": "https://www.gravatar.com/avatar/febab66d54b972e5f3c04a70a5feb5b5",
|
67
|
+
"created_at": "2018-03-27 05:47:37 UTC"
|
68
|
+
},
|
69
|
+
"created_at": "2018-12-28 13:17:08 UTC",
|
70
|
+
"scheduled_at": "2018-12-28 13:17:07 UTC",
|
71
|
+
"started_at": "2018-12-28 13:21:31 UTC",
|
72
|
+
"finished_at": null,
|
73
|
+
"meta_data": {
|
74
|
+
"buildkite:git:commit": "commit f9df15515206cf6d0ae552391b364fb3414c7958\nAuthor: James Healy <james@yob.id.au>\nAuthorDate: Sat Dec 29 00:02:56 2018 +1100\nCommit: James Healy <james@yob.id.au>\nCommitDate: Sat Dec 29 00:16:47 2018 +1100\n\n exp: will avoiding JS execution make this more reliable?"
|
75
|
+
},
|
76
|
+
"pull_request": null
|
77
|
+
},
|
78
|
+
"pipeline": {
|
79
|
+
"id": "f7e3be00-737a-4832-8646-11ae7fad909b",
|
80
|
+
"url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar",
|
81
|
+
"web_url": "https://buildkite.com/foo/bar",
|
82
|
+
"name": "Bar",
|
83
|
+
"description": "",
|
84
|
+
"slug": "bar",
|
85
|
+
"repository": "git@github.com:yob/bar.git",
|
86
|
+
"branch_configuration": "",
|
87
|
+
"default_branch": "master",
|
88
|
+
"skip_queued_branch_builds": true,
|
89
|
+
"skip_queued_branch_builds_filter": "",
|
90
|
+
"cancel_running_branch_builds": false,
|
91
|
+
"cancel_running_branch_builds_filter": "",
|
92
|
+
"provider": {
|
93
|
+
"id": "github",
|
94
|
+
"settings": {
|
95
|
+
"trigger_mode": "code",
|
96
|
+
"build_pull_requests": true,
|
97
|
+
"pull_request_branch_filter_enabled": false,
|
98
|
+
"skip_pull_request_builds_for_existing_commits": true,
|
99
|
+
"build_pull_request_forks": false,
|
100
|
+
"prefix_pull_request_fork_branch_names": false,
|
101
|
+
"build_tags": false,
|
102
|
+
"publish_commit_status": true,
|
103
|
+
"publish_commit_status_per_step": false,
|
104
|
+
"separate_pull_request_statuses": false,
|
105
|
+
"publish_blocked_as_pending": false,
|
106
|
+
"repository": "yob/bar",
|
107
|
+
"pull_request_branch_filter_configuration": ""
|
108
|
+
},
|
109
|
+
"webhook_url": "https://webhook.buildkite.com/deliver/849a6755fd449c310b936150fd3585e42070c1712b7c52f757"
|
110
|
+
},
|
111
|
+
"builds_url": "https://api.buildkite.com/v2/organizations/foo/pipelines/bar/builds",
|
112
|
+
"badge_url": "https://badge.buildkite.com/12de09c168b7ad23e83e96c62be7698f3d1102faea93b60803.svg",
|
113
|
+
"created_at": "2016-05-25 04:34:52 UTC",
|
114
|
+
"env": {
|
115
|
+
"GITHUB_SSH_KEY": "/root/.ssh/id_rsa"
|
116
|
+
},
|
117
|
+
"scheduled_builds_count": 0,
|
118
|
+
"running_builds_count": 2,
|
119
|
+
"scheduled_jobs_count": 11,
|
120
|
+
"running_jobs_count": 6,
|
121
|
+
"waiting_jobs_count": 0,
|
122
|
+
"steps": [
|
123
|
+
{
|
124
|
+
"type": "script",
|
125
|
+
"name": ":pipeline:",
|
126
|
+
"command": ".buildkite/upload-pipeline",
|
127
|
+
"artifact_paths": "",
|
128
|
+
"branch_configuration": "",
|
129
|
+
"env": {},
|
130
|
+
"timeout_in_minutes": null,
|
131
|
+
"agent_query_rules": [],
|
132
|
+
"concurrency": null,
|
133
|
+
"parallelism": null
|
134
|
+
}
|
135
|
+
]
|
136
|
+
},
|
137
|
+
"sender": {
|
138
|
+
"id": "f98b5507-d9ca-4711-b5bb-f2bf145b9d13",
|
139
|
+
"name": "James Healy"
|
140
|
+
}
|
141
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "buildkite-trace"
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: buildkite-trace
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- James Healy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: shotgun
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: puma
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: digest-crc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sinatra
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: A mini rack app that converts buildkite webhooks into datadog APM traces
|
84
|
+
email:
|
85
|
+
- james@yob.id.au
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files:
|
89
|
+
- README.md
|
90
|
+
- MIT-LICENSE
|
91
|
+
files:
|
92
|
+
- MIT-LICENSE
|
93
|
+
- README.md
|
94
|
+
- images/build-chart.png
|
95
|
+
- images/build-waterfall.png
|
96
|
+
- lib/buildkite-trace.rb
|
97
|
+
- lib/buildkite/trace/app.rb
|
98
|
+
- lib/buildkite/trace/build_finished_event.rb
|
99
|
+
- lib/buildkite/trace/client.rb
|
100
|
+
- lib/buildkite/trace/event.rb
|
101
|
+
- lib/buildkite/trace/job_finished_event.rb
|
102
|
+
- lib/buildkite/trace/span.rb
|
103
|
+
- lib/buildkite/trace/unknown_event.rb
|
104
|
+
- spec/buildkite/trace/build_finished_event_spec.rb
|
105
|
+
- spec/buildkite/trace/client_spec.rb
|
106
|
+
- spec/buildkite/trace/event_spec.rb
|
107
|
+
- spec/buildkite/trace/job_finished_event_spec.rb
|
108
|
+
- spec/buildkite/trace/span_spec.rb
|
109
|
+
- spec/fixtures/buildkite_build_finished.json
|
110
|
+
- spec/fixtures/buildkite_job_finished.json
|
111
|
+
- spec/spec_helper.rb
|
112
|
+
homepage: http://github.com/yob/buildkite-trace
|
113
|
+
licenses:
|
114
|
+
- MIT
|
115
|
+
metadata: {}
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
require_paths:
|
119
|
+
- lib
|
120
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.9.3
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
requirements: []
|
131
|
+
rubygems_version: 3.0.1
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: A mini rack app that converts buildkite webhooks into datadog APM traces
|
135
|
+
test_files: []
|