rspec-buildkite-analytics 0.4.0 → 0.6.3

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
  SHA256:
3
- metadata.gz: 44dd3ce4c2f47452f1eb52c96a2b86a7f49dd971d38350152b773dd343a85969
4
- data.tar.gz: 81fad9923f72c5a4e733b9e93917323c1037a6a0fa9ba4c0f76e9c3d0820f06b
3
+ metadata.gz: 499229f993ea2f8556a6d908f011325bf989de60c9a69a266338356b9f89426f
4
+ data.tar.gz: 901fec67b35b6ca85f61900a4cd9fa00293959892eb45e95339b6d4a6c27f527
5
5
  SHA512:
6
- metadata.gz: 6eb38e960fa8c7c8e6b4ff29070d188db20f0868c316a7b2b51051cd733793c8c86ea736385ddefa3eab04afb585d20ebef5fcf3bb7d3a2ee62513d9dcf448d5
7
- data.tar.gz: dec76a5f780c47f7f340b83501450545ccd810dbf9b0c43755d4fff300197da750b9411a49eb757f41a094d7058780a78f7a6d859fef34514105be6e97fd8765
6
+ metadata.gz: 0b7942d5c6b1abd45ff662cd52878d348bb1f9b3e2fa9fd1a6285eb7f521ac1d1f9dcc52007650dde979da9ddcbdd0506afe869708c785d033f9cf2e969eb009
7
+ data.tar.gz: c5484d6a416ac0faf663390c64d86e6c24184ddadbaa286b66407afd169444b7af9a6b9e665ead3438e87e719b5563ea0bc184c963643e17b13cdb8d3517ad1c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-buildkite-analytics (0.4.0)
4
+ rspec-buildkite-analytics (0.6.3)
5
5
  activesupport (>= 5.2, <= 7.0)
6
6
  rspec-core (~> 3.10)
7
7
  rspec-expectations (~> 3.10)
@@ -10,18 +10,17 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activesupport (6.1.4.1)
13
+ activesupport (7.0.0)
14
14
  concurrent-ruby (~> 1.0, >= 1.0.2)
15
15
  i18n (>= 1.6, < 2)
16
16
  minitest (>= 5.1)
17
17
  tzinfo (~> 2.0)
18
- zeitwerk (~> 2.3)
19
18
  concurrent-ruby (1.1.9)
20
19
  diff-lcs (1.4.4)
21
- i18n (1.8.10)
20
+ i18n (1.8.11)
22
21
  concurrent-ruby (~> 1.0)
23
- minitest (5.14.4)
24
- rake (13.0.3)
22
+ minitest (5.15.0)
23
+ rake (13.0.6)
25
24
  rspec (3.10.0)
26
25
  rspec-core (~> 3.10.0)
27
26
  rspec-expectations (~> 3.10.0)
@@ -31,14 +30,13 @@ GEM
31
30
  rspec-expectations (3.10.1)
32
31
  diff-lcs (>= 1.2.0, < 2.0)
33
32
  rspec-support (~> 3.10.0)
34
- rspec-mocks (3.10.1)
33
+ rspec-mocks (3.10.2)
35
34
  diff-lcs (>= 1.2.0, < 2.0)
36
35
  rspec-support (~> 3.10.0)
37
- rspec-support (3.10.1)
36
+ rspec-support (3.10.3)
38
37
  tzinfo (2.0.4)
39
38
  concurrent-ruby (~> 1.0)
40
39
  websocket (1.2.9)
41
- zeitwerk (2.5.1)
42
40
 
43
41
  PLATFORMS
44
42
  ruby
@@ -14,13 +14,17 @@ module RSpec::Buildkite::Analytics::CI
14
14
  "number" => ENV["BUILDKITE_BUILD_NUMBER"],
15
15
  "job_id" => ENV["BUILDKITE_JOB_ID"],
16
16
  "message" => ENV["BUILDKITE_MESSAGE"],
17
- "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"]
17
+ "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"],
18
+ "version" => RSpec::Buildkite::Analytics::VERSION,
19
+ "collector" => RSpec::Buildkite::Analytics::NAME
18
20
  }
19
21
  else
20
22
  {
21
23
  "CI" => nil,
22
24
  "key" => SecureRandom.uuid,
23
- "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"]
25
+ "debug" => ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"],
26
+ "version" => RSpec::Buildkite::Analytics::VERSION,
27
+ "collector" => RSpec::Buildkite::Analytics::NAME
24
28
  }
25
29
  end
26
30
  end
@@ -1,3 +1,5 @@
1
+ require "time"
2
+
1
3
  module RSpec::Buildkite::Analytics
2
4
  class Reporter
3
5
  RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending, :dump_summary
@@ -16,6 +18,7 @@ module RSpec::Buildkite::Analytics
16
18
 
17
19
  if trace
18
20
  trace.example = example
21
+ trace.failure_reason, trace.failure_expanded = failure_info(notification) if example.execution_result.status == :failed
19
22
  RSpec::Buildkite::Analytics.session&.write_result(trace)
20
23
  end
21
24
  end
@@ -33,7 +36,7 @@ module RSpec::Buildkite::Analytics
33
36
 
34
37
  # Write the debug file, if debug mode is enabled
35
38
  if RSpec::Buildkite::Analytics.debug_enabled
36
- filename = "#{RSpec::Buildkite::Analytics.debug_filepath}/bk-analytics-#{DateTime.current.strftime("%F-%R:%S")}-#{ENV["BUILDKITE_JOB_ID"]}.log.gz"
39
+ filename = "#{RSpec::Buildkite::Analytics.debug_filepath}/bk-analytics-#{Time.now.strftime("%F-%R:%S")}-#{ENV["BUILDKITE_JOB_ID"]}.log.gz"
37
40
 
38
41
  File.open(filename, "wb") do |f|
39
42
  gz = Zlib::GzipWriter.new(f)
@@ -43,9 +46,59 @@ module RSpec::Buildkite::Analytics
43
46
  end
44
47
  end
45
48
  end
46
-
49
+
47
50
  alias_method :example_passed, :handle_example
48
51
  alias_method :example_failed, :handle_example
49
52
  alias_method :example_pending, :handle_example
53
+
54
+ private
55
+
56
+ MULTIPLE_ERRORS = [
57
+ RSpec::Expectations::MultipleExpectationsNotMetError,
58
+ RSpec::Core::MultipleExceptionError
59
+ ]
60
+
61
+ def failure_info(notification)
62
+ failure_expanded = []
63
+
64
+ if RSpec::Buildkite::Analytics::Reporter::MULTIPLE_ERRORS.include?(notification.exception.class)
65
+ failure_reason = notification.exception.summary
66
+ notification.exception.all_exceptions.each do |exception|
67
+ # an example with multiple failures doesn't give us a
68
+ # separate message lines and backtrace object to send, so
69
+ # I've reached into RSpec internals and duplicated the
70
+ # construction of these
71
+ message_lines = RSpec::Core::Formatters::ExceptionPresenter.new(exception, notification.example).colorized_message_lines
72
+
73
+ failure_expanded << {
74
+ expanded: format_message_lines(message_lines),
75
+ backtrace: RSpec.configuration.backtrace_formatter.format_backtrace(exception.backtrace)
76
+ }
77
+ end
78
+ else
79
+ message_lines = notification.colorized_message_lines
80
+ failure_reason = strip_diff_colors(message_lines.shift)
81
+
82
+ failure_expanded << {
83
+ expanded: format_message_lines(message_lines),
84
+ backtrace: notification.formatted_backtrace
85
+ }
86
+ end
87
+
88
+ return failure_reason, failure_expanded
89
+ end
90
+
91
+ def format_message_lines(message_lines)
92
+ message_lines.map! { |l| strip_diff_colors(l) }
93
+ # the first line is sometimes blank, depending on the error reported
94
+ message_lines.shift if message_lines.first.blank?
95
+ # the last line is sometimes blank, depending on the error reported
96
+ message_lines.pop if message_lines.last.blank?
97
+ message_lines
98
+ end
99
+
100
+ def strip_diff_colors(string)
101
+ string.gsub(/\e\[([;\d]+)?m/, '')
102
+ end
50
103
  end
51
104
  end
@@ -35,13 +35,16 @@ module RSpec::Buildkite::Analytics
35
35
  attr_reader :logger
36
36
 
37
37
  def initialize(url, authorization_header, channel)
38
- @queue = Queue.new
38
+ @establish_subscription_queue = Queue.new
39
39
  @channel = channel
40
40
 
41
41
  @unconfirmed_idents = {}
42
42
  @idents_mutex = Mutex.new
43
+ @send_queue = Queue.new
43
44
  @empty = ConditionVariable.new
44
45
  @closing = false
46
+ @eot_queued = false
47
+ @eot_queued_mutex = Mutex.new
45
48
  @reconnection_mutex = Mutex.new
46
49
 
47
50
  @url = url
@@ -49,13 +52,25 @@ module RSpec::Buildkite::Analytics
49
52
 
50
53
  @logger = Logger.new
51
54
 
52
- connect
53
- rescue TimeoutError, InitialConnectionFailure => e
54
- $stderr.puts "rspec-buildkite-analytics could not establish an initial connection with Buildkite due to #{e.message}. You may be missing some data for this test suite, please contact support."
55
+ reconnection_count = 0
56
+
57
+ begin
58
+ reconnection_count += 1
59
+ connect
60
+ rescue TimeoutError, InitialConnectionFailure => e
61
+ @logger.write("rspec-buildkite-analytics could not establish an initial connection with Buildkite due to #{e}. Attempting retry #{reconnection_count} of #{MAX_RECONNECTION_ATTEMPTS}...")
62
+ if reconnection_count > MAX_RECONNECTION_ATTEMPTS
63
+ $stderr.puts "rspec-buildkite-analytics could not establish an initial connection with Buildkite due to #{e.message} after #{MAX_RECONNECTION_ATTEMPTS} attempts. You may be missing some data for this test suite, please contact support if this issue persists."
64
+ else
65
+ sleep(WAIT_BETWEEN_RECONNECTIONS)
66
+ @logger.write("retrying reconnection")
67
+ retry
68
+ end
69
+ end
70
+ init_write_thread
55
71
  end
56
72
 
57
73
  def disconnected(connection)
58
- reconnection_count = 0
59
74
  @reconnection_mutex.synchronize do
60
75
  # When the first thread detects a disconnection, it calls the disconnect method
61
76
  # with the current connection. This thread grabs the reconnection mutex and does the
@@ -69,10 +84,13 @@ module RSpec::Buildkite::Analytics
69
84
  return unless connection == @connection
70
85
  @logger.write("starting reconnection")
71
86
 
87
+ reconnection_count = 0
88
+
72
89
  begin
73
90
  reconnection_count += 1
74
91
  connect
75
- rescue SocketConnection::HandshakeError, RejectedSubscription, TimeoutError, SocketConnection::SocketError => e
92
+ init_write_thread
93
+ rescue SocketConnection::HandshakeError, RejectedSubscription, TimeoutError, InitialConnectionFailure, SocketConnection::SocketError => e
76
94
  @logger.write("failed reconnection attempt #{reconnection_count} due to #{e}")
77
95
  if reconnection_count > MAX_RECONNECTION_ATTEMPTS
78
96
  $stderr.puts "rspec-buildkite-analytics experienced a disconnection and could not reconnect to Buildkite due to #{e.message}. Please contact support."
@@ -100,7 +118,9 @@ module RSpec::Buildkite::Analytics
100
118
 
101
119
  @idents_mutex.synchronize do
102
120
  @logger.write("waiting for last confirm")
103
- # Here, we sleep for 75 seconds while waiting for the server to confirm the last idents.
121
+ # Here, we sleep for 75 seconds while waiting for the send
122
+ # queue to be drained and for the server to confirm the last
123
+ # idents.
104
124
  # We are woken up when the unconfirmed_idents is empty, and given back the mutex to
105
125
  # continue operation.
106
126
  @empty.wait(@idents_mutex, CONFIRMATION_TIMEOUT) unless @unconfirmed_idents.empty?
@@ -108,6 +128,8 @@ module RSpec::Buildkite::Analytics
108
128
 
109
129
  # Then we always disconnect cos we can't wait forever? 🤷‍♀️
110
130
  @connection.close
131
+ # We kill the write thread cos it's got a while loop in it, so it won't finish otherwise
132
+ @write_thread&.kill
111
133
  @logger.write("socket connection closed")
112
134
  end
113
135
 
@@ -121,7 +143,7 @@ module RSpec::Buildkite::Analytics
121
143
  when "welcome", "confirm_subscription"
122
144
  # Push these two messages onto the queue, so that we block on waiting for the
123
145
  # initializing phase to complete
124
- @queue.push(data)
146
+ @establish_subscription_queue.push(data)
125
147
  @logger.write("received #{data['type']}")
126
148
  when "reject_subscription"
127
149
  @logger.write("received rejected_subscription")
@@ -132,13 +154,9 @@ module RSpec::Buildkite::Analytics
132
154
  end
133
155
 
134
156
  def write_result(result)
135
- result_as_json = result.as_json
136
-
137
- add_unconfirmed_idents(result.id, result_as_json)
138
-
139
- transmit_results([result_as_json])
157
+ queue_and_track_result(result.id, result.as_hash)
140
158
 
141
- @logger.write("transmitted #{result.id}")
159
+ @logger.write("added #{result.id} to send queue")
142
160
  end
143
161
 
144
162
  def unconfirmed_idents_count
@@ -149,17 +167,6 @@ module RSpec::Buildkite::Analytics
149
167
 
150
168
  private
151
169
 
152
- def transmit_results(results_as_json)
153
- @connection.transmit({
154
- "identifier" => @channel,
155
- "command" => "message",
156
- "data" => {
157
- "action" => "record_results",
158
- "results" => results_as_json
159
- }.to_json
160
- })
161
- end
162
-
163
170
  def connect
164
171
  @logger.write("starting socket connection process")
165
172
 
@@ -179,9 +186,52 @@ module RSpec::Buildkite::Analytics
179
186
  @logger.write("connected")
180
187
  end
181
188
 
189
+ def init_write_thread
190
+ # As this method can be called multiple times in the
191
+ # reconnection process, kill prev write threads (if any) before
192
+ # setting up the new one
193
+ @write_thread&.kill
194
+
195
+ @write_thread = Thread.new do
196
+ @logger.write("hello from write thread")
197
+ # Pretty sure this eternal loop is fine cos the call to queue.pop is blocking
198
+ loop do
199
+ data = @send_queue.pop
200
+ message_type = data["action"]
201
+
202
+ if message_type == "end_of_transmission"
203
+ # Because of the unpredictable sequencing between the test suite finishing
204
+ # (EOT gets queued) and disconnections happening (retransmit results gets
205
+ # queued), we don't want to send an EOT before any retransmits are sent.
206
+ if @send_queue.length > 0
207
+ @send_queue << data
208
+ @logger.write("putting eot at back of queue")
209
+ next
210
+ end
211
+ @eot_queued_mutex.synchronize do
212
+ @eot_queued = false
213
+ end
214
+ end
215
+
216
+ @connection.transmit({
217
+ "identifier" => @channel,
218
+ "command" => "message",
219
+ "data" => data.to_json
220
+ })
221
+
222
+ if RSpec::Buildkite::Analytics.debug_enabled
223
+ ids = if message_type == "record_results"
224
+ data["results"].map { |result| result["id"] }
225
+ end
226
+ @logger.write("transmitted #{message_type} #{ids}")
227
+ end
228
+ end
229
+ end
230
+ end
231
+
182
232
  def pop_with_timeout(message_type)
183
233
  Timeout.timeout(30, RSpec::Buildkite::Analytics::TimeoutError, "Timeout: Waited 30 seconds for #{message_type}") do
184
- @queue.pop
234
+ @establish_subscription_queue.pop
185
235
  end
186
236
  end
187
237
 
@@ -201,9 +251,16 @@ module RSpec::Buildkite::Analytics
201
251
  end
202
252
  end
203
253
 
204
- def add_unconfirmed_idents(ident, data)
254
+ def queue_and_track_result(ident, result_as_hash)
205
255
  @idents_mutex.synchronize do
206
- @unconfirmed_idents[ident] = data
256
+ @unconfirmed_idents[ident] = result_as_hash
257
+
258
+ data = {
259
+ "action" => "record_results",
260
+ "results" => [result_as_hash]
261
+ }
262
+
263
+ @send_queue << data
207
264
  end
208
265
  end
209
266
 
@@ -222,23 +279,29 @@ module RSpec::Buildkite::Analytics
222
279
  #
223
280
  # However, there aren't any threads waiting on this signal until after we
224
281
  # send the EOT message, so the prior broadcasts shouldn't do anything.
225
- @empty.broadcast if @unconfirmed_idents.empty?
282
+ if @unconfirmed_idents.empty?
283
+ @empty.broadcast
284
+ @logger.write("broadcast empty")
285
+ else
286
+ @logger.write("still waiting on confirm for #{@unconfirmed_idents.keys}")
287
+ end
226
288
  end
227
289
  end
228
290
 
229
291
  def send_eot
230
- # Expect server to respond with data of indentifiers last upload part
231
-
232
- @connection.transmit({
233
- "identifier" => @channel,
234
- "command" => "message",
235
- "data" => {
292
+ @eot_queued_mutex.synchronize do
293
+ return if @eot_queued
294
+ # Expect server to respond with data of indentifiers last upload part
295
+ data = {
236
296
  "action" => "end_of_transmission",
237
297
  "examples_count" => @examples_count.to_json
238
- }.to_json
239
- })
298
+ }
240
299
 
241
- @logger.write("transmitted EOT")
300
+ @send_queue << data
301
+ @eot_queued = true
302
+
303
+ @logger.write("added EOT to send queue")
304
+ end
242
305
  end
243
306
 
244
307
  def process_message(data)
@@ -255,14 +318,19 @@ module RSpec::Buildkite::Analytics
255
318
  end
256
319
 
257
320
  def retransmit
258
- data = @idents_mutex.synchronize do
259
- @unconfirmed_idents.values
260
- end
321
+ @idents_mutex.synchronize do
322
+ results = @unconfirmed_idents.values
261
323
 
262
- # send the contents of the buffer, unless it's empty
263
- unless data.empty?
264
- @logger.write("retransmitting data")
265
- transmit_results(data)
324
+ # queue the contents of the buffer, unless it's empty
325
+ unless results.empty?
326
+ data = {
327
+ "action" => "record_results",
328
+ "results" => results
329
+ }
330
+
331
+ @send_queue << data
332
+ @logger.write("queueing up retransmitted results #{@unconfirmed_idents.keys}")
333
+ end
266
334
  end
267
335
 
268
336
  # if we were disconnected in the closing phase, then resend the EOT
@@ -110,6 +110,7 @@ module RSpec::Buildkite::Analytics
110
110
  @socket.write(frame.to_s)
111
111
  rescue Errno::EPIPE, Errno::ECONNRESET, OpenSSL::SSL::SSLError => e
112
112
  return unless @socket
113
+ return if type == :close
113
114
  @session.logger.write("got #{e}, attempting disconnected flow")
114
115
  @session.disconnected(self)
115
116
  disconnect
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/hash/indifferent_access"
4
+
3
5
  module RSpec::Buildkite::Analytics
4
6
  class Tracer
5
7
  class Span
@@ -13,15 +15,15 @@ module RSpec::Buildkite::Analytics
13
15
  @children = []
14
16
  end
15
17
 
16
- def as_json
18
+ def as_hash
17
19
  {
18
20
  section: section,
19
21
  start_at: start_at,
20
22
  end_at: end_at,
21
23
  duration: end_at - start_at,
22
24
  detail: detail,
23
- children: children.map(&:as_json),
24
- }
25
+ children: children.map(&:as_hash),
26
+ }.with_indifferent_access
25
27
  end
26
28
  end
27
29
 
@@ -57,7 +59,7 @@ module RSpec::Buildkite::Analytics
57
59
  end
58
60
 
59
61
  def history
60
- @top.as_json
62
+ @top.as_hash
61
63
  end
62
64
  end
63
65
  end
@@ -22,22 +22,15 @@ require "securerandom"
22
22
  module RSpec::Buildkite::Analytics
23
23
  class Uploader
24
24
  class Trace
25
- attr_accessor :example
25
+ attr_accessor :example, :failure_reason, :failure_expanded
26
26
  attr_reader :id, :history
27
27
 
28
28
  def initialize(example, history)
29
29
  @id = SecureRandom.uuid
30
30
  @example = example
31
31
  @history = history
32
- end
33
-
34
- def failure_message
35
- case example.exception
36
- when RSpec::Expectations::ExpectationNotMetError
37
- example.exception.message
38
- when Exception
39
- "#{example.exception.class}: #{example.exception.message}"
40
- end
32
+ @failure_reason = nil
33
+ @failure_expanded = []
41
34
  end
42
35
 
43
36
  def result_state
@@ -48,7 +41,7 @@ module RSpec::Buildkite::Analytics
48
41
  end
49
42
  end
50
43
 
51
- def as_json
44
+ def as_hash
52
45
  {
53
46
  id: @id,
54
47
  scope: example.example_group.metadata[:full_description],
@@ -57,9 +50,10 @@ module RSpec::Buildkite::Analytics
57
50
  location: example.location,
58
51
  file_name: generate_file_name(example),
59
52
  result: result_state,
60
- failure: failure_message,
53
+ failure_reason: failure_reason,
54
+ failure_expanded: failure_expanded,
61
55
  history: history,
62
- }
56
+ }.with_indifferent_access.compact
63
57
  end
64
58
 
65
59
  private
@@ -121,7 +115,8 @@ module RSpec::Buildkite::Analytics
121
115
  "Content-Type" => "application/json",
122
116
  })
123
117
  contact.body = {
124
- run_env: CI.env
118
+ run_env: CI.env,
119
+ format: "websocket"
125
120
  }.to_json
126
121
 
127
122
  response = begin
@@ -130,6 +125,8 @@ module RSpec::Buildkite::Analytics
130
125
  puts "Buildkite Test Analytics: Error communicating with the server: #{e.message}"
131
126
  end
132
127
 
128
+ return unless response
129
+
133
130
  case response.code
134
131
  when "401"
135
132
  puts "Buildkite Test Analytics: Invalid Suite API key. Please double check your Suite API key."
@@ -141,10 +138,12 @@ module RSpec::Buildkite::Analytics
141
138
  end
142
139
  else
143
140
  request_id = response.to_hash["x-request-id"]
144
- puts "Buildkite Test Analytics: Unknown error. If this error persists, please contact support+analytics@buildkite.com with this request ID `#{request_id}`."
141
+ puts "rspec-buildkite-analytics could not establish an initial connection with Buildkite. You may be missing some data for this test suite, please contact support."
145
142
  end
146
143
  else
147
- puts "Buildkite Test Analytics: No Suite API key provided. You can get the API key from your Suite settings page."
144
+ if !!ENV["BUILDKITE_BUILD_ID"]
145
+ puts "Buildkite Test Analytics: No Suite API key provided. You can get the API key from your Suite settings page."
146
+ end
148
147
  end
149
148
  end
150
149
 
@@ -3,7 +3,8 @@
3
3
  module RSpec
4
4
  module Buildkite
5
5
  module Analytics
6
- VERSION = "0.4.0"
6
+ VERSION = "0.6.3"
7
+ NAME = "rspec-buildkite"
7
8
  end
8
9
  end
9
10
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "timeout"
4
+ require "tmpdir"
4
5
 
5
6
  require_relative "analytics/version"
6
7
 
@@ -23,7 +24,7 @@ module RSpec::Buildkite::Analytics
23
24
  self.api_token = token || ENV["BUILDKITE_ANALYTICS_TOKEN"]
24
25
  self.url = url || DEFAULT_URL
25
26
  self.debug_enabled = debug_enabled || !!(ENV["BUILDKITE_ANALYTICS_DEBUG_ENABLED"])
26
- self.debug_filepath = debug_filepath || ENV["BUILDKITE_ANALYTICS_DEBUG_FILEPATH"]
27
+ self.debug_filepath = debug_filepath || ENV["BUILDKITE_ANALYTICS_DEBUG_FILEPATH"] || Dir.tmpdir
27
28
 
28
29
  require_relative "analytics/uploader"
29
30
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-buildkite-analytics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Buildkite
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-04 00:00:00.000000000 Z
11
+ date: 2022-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport