ld-eventsource 2.1.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/ld-eventsource/client.rb +39 -46
- data/lib/ld-eventsource/events.rb +5 -1
- data/lib/ld-eventsource/impl/backoff.rb +5 -1
- data/lib/ld-eventsource/impl/buffered_line_reader.rb +82 -0
- data/lib/ld-eventsource/impl/event_parser.rb +26 -14
- data/lib/ld-eventsource/version.rb +1 -1
- metadata +5 -29
- data/.circleci/config.yml +0 -39
- data/.gitignore +0 -17
- data/.ldrelease/circleci/linux/execute.sh +0 -18
- data/.ldrelease/circleci/mac/execute.sh +0 -18
- data/.ldrelease/circleci/template/build.sh +0 -19
- data/.ldrelease/circleci/template/gems-setup.sh +0 -16
- data/.ldrelease/circleci/template/prepare.sh +0 -17
- data/.ldrelease/circleci/template/publish.sh +0 -19
- data/.ldrelease/circleci/template/test.sh +0 -10
- data/.ldrelease/circleci/template/update-version.sh +0 -8
- data/.ldrelease/circleci/windows/execute.ps1 +0 -19
- data/.ldrelease/config.yml +0 -22
- data/CHANGELOG.md +0 -35
- data/Gemfile +0 -3
- data/ld-eventsource.gemspec +0 -30
- data/scripts/gendocs.sh +0 -12
- data/scripts/release.sh +0 -30
- data/spec/backoff_spec.rb +0 -52
- data/spec/client_spec.rb +0 -444
- data/spec/event_parser_spec.rb +0 -100
- data/spec/http_stub.rb +0 -83
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3ce08e7a1cf60a7a5dbbe1dfdaa98c4391a625a05b91e47907e80f02ad5a301
|
4
|
+
data.tar.gz: 35009bae9547b7db1bfbd9e4561e58594d6471d44b379436e43d78894fbcfb6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7c0915fddc58ed5629eda81b30b7d843a7689ae58ebe01e45f0451d125aa4033d8ad47f50832645b64a97662155cd9ff0e2fa077fc269a604f9bc6ef8a5a27d
|
7
|
+
data.tar.gz: 0a0b2dc61b40ec7b48d32ff3449a70712d9e1ea17e2708eb62d7fce68b5f61d722709d6b244efdf908c47d6ed43cc0e70eec8fe80006478658ce3838f837737a
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
LaunchDarkly SSE Client for Ruby
|
2
2
|
================================
|
3
3
|
|
4
|
-
[![Gem Version](https://badge.fury.io/rb/ld-eventsource.svg)](http://badge.fury.io/rb/ld-eventsource) [![Circle CI](https://circleci.com/gh/launchdarkly/ruby-eventsource/tree/
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/ld-eventsource.svg)](http://badge.fury.io/rb/ld-eventsource) [![Circle CI](https://circleci.com/gh/launchdarkly/ruby-eventsource/tree/main.svg?style=svg)](https://circleci.com/gh/launchdarkly/ruby-eventsource/tree/main)
|
5
5
|
|
6
6
|
A client for the [Server-Sent Events](https://www.w3.org/TR/eventsource/) protocol. This implementation runs on a worker thread, and uses the [`http`](https://rubygems.org/gems/http) gem to manage a persistent connection. Its primary purpose is to support the [LaunchDarkly SDK for Ruby](https://github.com/launchdarkly/ruby-client), but it can be used independently.
|
7
7
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "ld-eventsource/impl/backoff"
|
2
|
+
require "ld-eventsource/impl/buffered_line_reader"
|
2
3
|
require "ld-eventsource/impl/event_parser"
|
3
4
|
require "ld-eventsource/events"
|
4
5
|
require "ld-eventsource/errors"
|
@@ -128,11 +129,12 @@ module SSE
|
|
128
129
|
read: read_timeout,
|
129
130
|
connect: connect_timeout
|
130
131
|
})
|
131
|
-
@
|
132
|
+
@cxn = nil
|
132
133
|
@lock = Mutex.new
|
133
134
|
|
134
135
|
@backoff = Impl::Backoff.new(reconnect_time || DEFAULT_RECONNECT_TIME, MAX_RECONNECT_TIME,
|
135
136
|
reconnect_reset_interval: reconnect_reset_interval)
|
137
|
+
@first_attempt = true
|
136
138
|
|
137
139
|
@on = { event: ->(_) {}, error: ->(_) {} }
|
138
140
|
@last_id = last_event_id
|
@@ -203,47 +205,14 @@ module SSE
|
|
203
205
|
|
204
206
|
def reset_http
|
205
207
|
@http_client.close if !@http_client.nil?
|
206
|
-
|
207
|
-
@buffer = ""
|
208
|
-
end
|
209
|
-
|
210
|
-
def read_lines
|
211
|
-
Enumerator.new do |gen|
|
212
|
-
loop do
|
213
|
-
line = read_line
|
214
|
-
break if line.nil?
|
215
|
-
gen.yield line
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
def read_line
|
221
|
-
loop do
|
222
|
-
@lock.synchronize do
|
223
|
-
i = @buffer.index(/[\r\n]/)
|
224
|
-
if !i.nil? && !(i == @buffer.length - 1 && @buffer[i] == "\r")
|
225
|
-
i += 1 if (@buffer[i] == "\r" && @buffer[i + 1] == "\n")
|
226
|
-
return @buffer.slice!(0, i + 1).force_encoding(Encoding::UTF_8)
|
227
|
-
end
|
228
|
-
end
|
229
|
-
return nil if !read_chunk_into_buffer
|
230
|
-
end
|
208
|
+
close_connection
|
231
209
|
end
|
232
210
|
|
233
|
-
def
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
data = @cxn.readpartial
|
238
|
-
rescue HTTP::TimeoutError
|
239
|
-
# We rethrow this as our own type so the caller doesn't have to know the httprb API
|
240
|
-
raise Errors::ReadTimeoutError.new(@read_timeout)
|
211
|
+
def close_connection
|
212
|
+
@lock.synchronize do
|
213
|
+
@cxn.connection.close if !@cxn.nil?
|
214
|
+
@cxn = nil
|
241
215
|
end
|
242
|
-
return false if data == nil
|
243
|
-
@buffer << data
|
244
|
-
# We are piping the content through the parser so that it can handle things like chunked
|
245
|
-
# encoding for us. The content ends up being appended to @buffer via our callback.
|
246
|
-
true
|
247
216
|
end
|
248
217
|
|
249
218
|
def default_logger
|
@@ -255,13 +224,16 @@ module SSE
|
|
255
224
|
|
256
225
|
def run_stream
|
257
226
|
while !@stopped.value
|
258
|
-
|
227
|
+
close_connection
|
259
228
|
begin
|
260
|
-
|
229
|
+
resp = connect
|
230
|
+
@lock.synchronize do
|
231
|
+
@cxn = resp
|
232
|
+
end
|
261
233
|
# There's a potential race if close was called in the middle of the previous line, i.e. after we
|
262
234
|
# connected but before @cxn was set. Checking the variable again is a bit clunky but avoids that.
|
263
235
|
return if @stopped.value
|
264
|
-
read_stream(
|
236
|
+
read_stream(resp) if !resp.nil?
|
265
237
|
rescue => e
|
266
238
|
# When we deliberately close the connection, it will usually trigger an exception. The exact type
|
267
239
|
# of exception depends on the specific Ruby runtime. But @stopped will always be set in this case.
|
@@ -283,7 +255,8 @@ module SSE
|
|
283
255
|
def connect
|
284
256
|
loop do
|
285
257
|
return if @stopped.value
|
286
|
-
interval = @backoff.next_interval
|
258
|
+
interval = @first_attempt ? 0 : @backoff.next_interval
|
259
|
+
@first_attempt = false
|
287
260
|
if interval > 0
|
288
261
|
@logger.info { "Will retry connection after #{'%.3f' % interval} seconds" }
|
289
262
|
sleep(interval)
|
@@ -326,7 +299,27 @@ module SSE
|
|
326
299
|
# it can automatically reset itself if enough time passes between failures.
|
327
300
|
@backoff.mark_success
|
328
301
|
|
329
|
-
|
302
|
+
chunks = Enumerator.new do |gen|
|
303
|
+
loop do
|
304
|
+
if @stopped.value
|
305
|
+
break
|
306
|
+
else
|
307
|
+
begin
|
308
|
+
data = cxn.readpartial
|
309
|
+
# readpartial gives us a string, which may not be a valid UTF-8 string because a
|
310
|
+
# multi-byte character might not yet have been fully read, but BufferedLineReader
|
311
|
+
# will handle that.
|
312
|
+
rescue HTTP::TimeoutError
|
313
|
+
# For historical reasons, we rethrow this as our own type
|
314
|
+
raise Errors::ReadTimeoutError.new(@read_timeout)
|
315
|
+
end
|
316
|
+
break if data.nil?
|
317
|
+
gen.yield data
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
event_parser = Impl::EventParser.new(Impl::BufferedLineReader.lines_from(chunks), @last_id)
|
322
|
+
|
330
323
|
event_parser.items.each do |item|
|
331
324
|
return if @stopped.value
|
332
325
|
case item
|
@@ -341,7 +334,7 @@ module SSE
|
|
341
334
|
|
342
335
|
def dispatch_event(event)
|
343
336
|
@logger.debug { "Received event: #{event}" }
|
344
|
-
@last_id = event.id
|
337
|
+
@last_id = event.id if !event.id.nil?
|
345
338
|
|
346
339
|
# Pass the event to the caller
|
347
340
|
@on[:event].call(event)
|
@@ -364,7 +357,7 @@ module SSE
|
|
364
357
|
'Cache-Control' => 'no-cache',
|
365
358
|
'User-Agent' => 'ruby-eventsource'
|
366
359
|
}
|
367
|
-
h['Last-Event-Id'] = @last_id if !@last_id.nil?
|
360
|
+
h['Last-Event-Id'] = @last_id if !@last_id.nil? && @last_id != ""
|
368
361
|
h.merge(@headers)
|
369
362
|
end
|
370
363
|
end
|
@@ -11,6 +11,10 @@ module SSE
|
|
11
11
|
# if there were multiple `data:` lines, they are concatenated with newlines
|
12
12
|
# @!attribute id
|
13
13
|
# @return [String] the string that appeared after `id:` in the stream if any, or nil
|
14
|
+
# @!attribute last_event_id
|
15
|
+
# @return [String] the `id:` value that was most recently seen in an event from
|
16
|
+
# this stream; this differs from the `id` property in that it retains the same value
|
17
|
+
# in subsequent events if they do not provide their own `id:`
|
14
18
|
#
|
15
|
-
StreamEvent = Struct.new(:type, :data, :id)
|
19
|
+
StreamEvent = Struct.new(:type, :data, :id, :last_event_id)
|
16
20
|
end
|
@@ -41,7 +41,11 @@ module SSE
|
|
41
41
|
@last_good_time = nil
|
42
42
|
target = ([@base_interval * (2 ** @attempts), @max_interval].min).to_f
|
43
43
|
@attempts += 1
|
44
|
-
|
44
|
+
if target == 0
|
45
|
+
0 # in some Ruby versions it's illegal to call rand(0)
|
46
|
+
else
|
47
|
+
(target / 2) + @jitter_rand.rand(target / 2)
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
#
|
@@ -0,0 +1,82 @@
|
|
1
|
+
|
2
|
+
module SSE
|
3
|
+
module Impl
|
4
|
+
class BufferedLineReader
|
5
|
+
#
|
6
|
+
# Reads a series of data chunks from an enumerator, and returns an enumerator that
|
7
|
+
# parses/aggregates these into text lines. The line terminator may be CR, LF, or
|
8
|
+
# CRLF for each line; terminators are not included in the returned lines. When the
|
9
|
+
# input data runs out, the output enumerator ends and does not include any partially
|
10
|
+
# completed line.
|
11
|
+
#
|
12
|
+
# @param [Enumerator] chunks an enumerator that will yield strings from a stream -
|
13
|
+
# these are treated as raw UTF-8 bytes, regardless of the string's declared encoding
|
14
|
+
# (so it is OK if a multi-byte character is split across chunks); if the declared
|
15
|
+
# encoding of the chunk is not ASCII-8BIT, it will be changed to ASCII-8BIT in place
|
16
|
+
# @return [Enumerator] an enumerator that will yield one line at a time in UTF-8
|
17
|
+
#
|
18
|
+
def self.lines_from(chunks)
|
19
|
+
buffer = "".b
|
20
|
+
position = 0
|
21
|
+
line_start = 0
|
22
|
+
last_char_was_cr = false
|
23
|
+
|
24
|
+
Enumerator.new do |gen|
|
25
|
+
chunks.each do |chunk|
|
26
|
+
chunk.force_encoding("ASCII-8BIT")
|
27
|
+
buffer << chunk
|
28
|
+
|
29
|
+
loop do
|
30
|
+
# Search for a line break in any part of the buffer that we haven't yet seen.
|
31
|
+
i = buffer.index(/[\r\n]/, position)
|
32
|
+
if i.nil?
|
33
|
+
# There isn't a line break yet, so we'll keep accumulating data in the buffer, using
|
34
|
+
# position to keep track of where we left off scanning. We can also discard any previously
|
35
|
+
# parsed lines from the buffer at this point.
|
36
|
+
if line_start > 0
|
37
|
+
buffer.slice!(0, line_start)
|
38
|
+
line_start = 0
|
39
|
+
end
|
40
|
+
position = buffer.length
|
41
|
+
break
|
42
|
+
end
|
43
|
+
|
44
|
+
ch = buffer[i]
|
45
|
+
if i == 0 && ch == "\n" && last_char_was_cr
|
46
|
+
# This is just the dangling LF of a CRLF pair
|
47
|
+
last_char_was_cr = false
|
48
|
+
i += 1
|
49
|
+
position = i
|
50
|
+
line_start = i
|
51
|
+
next
|
52
|
+
end
|
53
|
+
|
54
|
+
line = buffer[line_start, i - line_start].force_encoding("UTF-8")
|
55
|
+
# Calling force_encoding just declares that we believe the encoding of this string to be
|
56
|
+
# UTF-8 (which is the only encoding allowed in the SSE protocol); it doesn't cause any
|
57
|
+
# re-decoding of the string. The previous line-parsing steps were done on raw 8-bit
|
58
|
+
# strings so that it won't try to do any UTF-8 decoding on intermediate slices.
|
59
|
+
|
60
|
+
last_char_was_cr = false
|
61
|
+
i += 1
|
62
|
+
if ch == "\r"
|
63
|
+
if i == buffer.length
|
64
|
+
last_char_was_cr = true # We'll break the line here, but be on watch for a dangling LF
|
65
|
+
elsif buffer[i] == "\n"
|
66
|
+
i += 1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
if i == buffer.length
|
70
|
+
buffer = ""
|
71
|
+
i = 0
|
72
|
+
end
|
73
|
+
position = i
|
74
|
+
line_start = i
|
75
|
+
gen.yield line
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -20,10 +20,12 @@ module SSE
|
|
20
20
|
#
|
21
21
|
# Constructs an instance of EventParser.
|
22
22
|
#
|
23
|
-
# @param [Enumerator] lines an enumerator that will yield one line of text at a time
|
23
|
+
# @param [Enumerator] lines an enumerator that will yield one line of text at a time;
|
24
|
+
# the lines should not include line terminators
|
24
25
|
#
|
25
|
-
def initialize(lines)
|
26
|
+
def initialize(lines, last_event_id = nil)
|
26
27
|
@lines = lines
|
28
|
+
@last_event_id = last_event_id
|
27
29
|
reset_buffers
|
28
30
|
end
|
29
31
|
|
@@ -31,17 +33,19 @@ module SSE
|
|
31
33
|
def items
|
32
34
|
Enumerator.new do |gen|
|
33
35
|
@lines.each do |line|
|
34
|
-
line.chomp!
|
35
36
|
if line.empty?
|
36
37
|
event = maybe_create_event
|
37
38
|
reset_buffers
|
38
39
|
gen.yield event if !event.nil?
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
elsif (pos = line.index(':'))
|
41
|
+
name = line.slice(0...pos)
|
42
|
+
|
43
|
+
pos += 1 # skip colon
|
44
|
+
pos += 1 if pos < line.length && line[pos] == ' ' # skip optional single space, per SSE spec
|
45
|
+
line = line.slice(pos..-1)
|
46
|
+
|
47
|
+
item = process_field(name, line)
|
48
|
+
gen.yield item if !item.nil?
|
45
49
|
end
|
46
50
|
end
|
47
51
|
end
|
@@ -53,6 +57,7 @@ module SSE
|
|
53
57
|
@id = nil
|
54
58
|
@type = nil
|
55
59
|
@data = ""
|
60
|
+
@have_data = false
|
56
61
|
end
|
57
62
|
|
58
63
|
def process_field(name, value)
|
@@ -60,10 +65,17 @@ module SSE
|
|
60
65
|
when "event"
|
61
66
|
@type = value.to_sym
|
62
67
|
when "data"
|
63
|
-
|
64
|
-
|
68
|
+
if @have_data
|
69
|
+
@data << "\n" << value
|
70
|
+
else
|
71
|
+
@data = value
|
72
|
+
end
|
73
|
+
@have_data = true
|
65
74
|
when "id"
|
66
|
-
|
75
|
+
if !value.include?("\x00")
|
76
|
+
@id = value
|
77
|
+
@last_event_id = value
|
78
|
+
end
|
67
79
|
when "retry"
|
68
80
|
if /^(?<num>\d+)$/ =~ value
|
69
81
|
return SetRetryInterval.new(num.to_i)
|
@@ -73,8 +85,8 @@ module SSE
|
|
73
85
|
end
|
74
86
|
|
75
87
|
def maybe_create_event
|
76
|
-
return nil if
|
77
|
-
StreamEvent.new(@type || :message, @data, @id)
|
88
|
+
return nil if !@have_data
|
89
|
+
StreamEvent.new(@type || :message, @data, @id, @last_event_id)
|
78
90
|
end
|
79
91
|
end
|
80
92
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ld-eventsource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LaunchDarkly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -107,36 +107,16 @@ executables: []
|
|
107
107
|
extensions: []
|
108
108
|
extra_rdoc_files: []
|
109
109
|
files:
|
110
|
-
- ".circleci/config.yml"
|
111
|
-
- ".gitignore"
|
112
|
-
- ".ldrelease/circleci/linux/execute.sh"
|
113
|
-
- ".ldrelease/circleci/mac/execute.sh"
|
114
|
-
- ".ldrelease/circleci/template/build.sh"
|
115
|
-
- ".ldrelease/circleci/template/gems-setup.sh"
|
116
|
-
- ".ldrelease/circleci/template/prepare.sh"
|
117
|
-
- ".ldrelease/circleci/template/publish.sh"
|
118
|
-
- ".ldrelease/circleci/template/test.sh"
|
119
|
-
- ".ldrelease/circleci/template/update-version.sh"
|
120
|
-
- ".ldrelease/circleci/windows/execute.ps1"
|
121
|
-
- ".ldrelease/config.yml"
|
122
|
-
- CHANGELOG.md
|
123
|
-
- Gemfile
|
124
110
|
- LICENSE
|
125
111
|
- README.md
|
126
|
-
- ld-eventsource.gemspec
|
127
112
|
- lib/ld-eventsource.rb
|
128
113
|
- lib/ld-eventsource/client.rb
|
129
114
|
- lib/ld-eventsource/errors.rb
|
130
115
|
- lib/ld-eventsource/events.rb
|
131
116
|
- lib/ld-eventsource/impl/backoff.rb
|
117
|
+
- lib/ld-eventsource/impl/buffered_line_reader.rb
|
132
118
|
- lib/ld-eventsource/impl/event_parser.rb
|
133
119
|
- lib/ld-eventsource/version.rb
|
134
|
-
- scripts/gendocs.sh
|
135
|
-
- scripts/release.sh
|
136
|
-
- spec/backoff_spec.rb
|
137
|
-
- spec/client_spec.rb
|
138
|
-
- spec/event_parser_spec.rb
|
139
|
-
- spec/http_stub.rb
|
140
120
|
homepage: https://github.com/launchdarkly/ruby-eventsource
|
141
121
|
licenses:
|
142
122
|
- Apache-2.0
|
@@ -156,12 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
136
|
- !ruby/object:Gem::Version
|
157
137
|
version: '0'
|
158
138
|
requirements: []
|
159
|
-
rubygems_version: 3.
|
139
|
+
rubygems_version: 3.3.16
|
160
140
|
signing_key:
|
161
141
|
specification_version: 4
|
162
142
|
summary: LaunchDarkly SSE client
|
163
|
-
test_files:
|
164
|
-
- spec/backoff_spec.rb
|
165
|
-
- spec/client_spec.rb
|
166
|
-
- spec/event_parser_spec.rb
|
167
|
-
- spec/http_stub.rb
|
143
|
+
test_files: []
|
data/.circleci/config.yml
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# This CircleCI configuration was generated by Releaser for a specific release. It is not to be used
|
2
|
-
# for regular CI builds. Be aware that rerunning this build may cause it to repeat release actions
|
3
|
-
# such as publishing to a package manager. However, it will not perform any Git actions other than
|
4
|
-
# reading the repository.
|
5
|
-
version: 2.1
|
6
|
-
workflows:
|
7
|
-
test:
|
8
|
-
jobs:
|
9
|
-
- release_linux:
|
10
|
-
context: org-global
|
11
|
-
jobs:
|
12
|
-
release_linux:
|
13
|
-
docker:
|
14
|
-
- image: cimg/ruby:2.5
|
15
|
-
environment:
|
16
|
-
LD_RELEASE_CIRCLECI_TYPE: linux
|
17
|
-
LD_RELEASE_BRANCH: "master"
|
18
|
-
LD_RELEASE_CIRCLECI_BRANCH: ""
|
19
|
-
LD_RELEASE_DOCS_GITHUB_PAGES: ""
|
20
|
-
LD_RELEASE_DOCS_TITLE: ""
|
21
|
-
LD_RELEASE_PROJECT: "ruby-eventsource"
|
22
|
-
LD_RELEASE_PROJECT_TEMPLATE: "ruby"
|
23
|
-
LD_RELEASE_VERSION: "2.1.0"
|
24
|
-
steps:
|
25
|
-
- checkout
|
26
|
-
- run:
|
27
|
-
name: "Releaser: prepare"
|
28
|
-
command: .ldrelease/circleci/mac/execute.sh prepare .ldrelease/circleci/template/prepare.sh
|
29
|
-
- run:
|
30
|
-
name: "Releaser: build"
|
31
|
-
command: .ldrelease/circleci/mac/execute.sh build .ldrelease/circleci/template/build.sh
|
32
|
-
- run:
|
33
|
-
name: "Releaser: test"
|
34
|
-
command: .ldrelease/circleci/mac/execute.sh test .ldrelease/circleci/template/test.sh
|
35
|
-
- run:
|
36
|
-
name: "Releaser: publish"
|
37
|
-
command: .ldrelease/circleci/mac/execute.sh publish .ldrelease/circleci/template/publish.sh
|
38
|
-
- store_artifacts:
|
39
|
-
path: artifacts
|
data/.gitignore
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -ue
|
4
|
-
|
5
|
-
# Performs a delegated release step in a CircleCI Linux container. This mechanism is described
|
6
|
-
# in scripts/circleci/README.md. All of the necessary environment variables should already be
|
7
|
-
# in the generated CircleCI configuration.
|
8
|
-
|
9
|
-
mkdir -p artifacts
|
10
|
-
|
11
|
-
export LD_RELEASE_TEMP_DIR=/tmp/project-releaser-temp
|
12
|
-
mkdir -p ${LD_RELEASE_TEMP_DIR}
|
13
|
-
|
14
|
-
STEP="$1"
|
15
|
-
SCRIPT="$2"
|
16
|
-
echo
|
17
|
-
echo "[${STEP}] executing ${SCRIPT}"
|
18
|
-
"./${SCRIPT}"
|
@@ -1,18 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -ue
|
4
|
-
|
5
|
-
# Performs a delegated release step in a CircleCI Mac container. This mechanism is described
|
6
|
-
# in scripts/circleci/README.md. All of the necessary environment variables should already be
|
7
|
-
# in the generated CircleCI configuration.
|
8
|
-
|
9
|
-
mkdir -p artifacts
|
10
|
-
|
11
|
-
export LD_RELEASE_TEMP_DIR=/tmp/project-releaser-temp
|
12
|
-
mkdir -p ${LD_RELEASE_TEMP_DIR}
|
13
|
-
|
14
|
-
STEP="$1"
|
15
|
-
SCRIPT="$2"
|
16
|
-
echo
|
17
|
-
echo "[${STEP}] executing ${SCRIPT}"
|
18
|
-
"./${SCRIPT}"
|
@@ -1,19 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -ue
|
4
|
-
|
5
|
-
# Standard build.sh for Ruby-based projects that publish a gem
|
6
|
-
|
7
|
-
echo "Using gem $(gem --version)"
|
8
|
-
|
9
|
-
#shellcheck source=/dev/null
|
10
|
-
source "$(dirname "$0")/gems-setup.sh"
|
11
|
-
|
12
|
-
echo; echo "Installing dependencies"
|
13
|
-
${BUNDLER_COMMAND} install
|
14
|
-
|
15
|
-
# Build Ruby Gem - this assumes there is a single .gemspec file in the main project directory
|
16
|
-
# Note that the gemspec must be able to get the project version either from $LD_RELEASE_VERSION,
|
17
|
-
# or from somewhere in the source code that the project-specific update-version.sh has updated.
|
18
|
-
echo "Running gem build"
|
19
|
-
gem build ./*.gemspec || { echo "gem build failed" >&2; exit 1; }
|
@@ -1,16 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
# helper script to set GEM_HOME, PATH, and BUNDLER_COMMAND for Ruby - must be sourced, not executed
|
4
|
-
|
5
|
-
mkdir -p "${LD_RELEASE_TEMP_DIR}/gems"
|
6
|
-
export GEM_HOME="${LD_RELEASE_TEMP_DIR}/gems"
|
7
|
-
export PATH="${GEM_HOME}/bin:${PATH}"
|
8
|
-
|
9
|
-
# also, determine whether we'll need to run a specific version of Bundler
|
10
|
-
|
11
|
-
GEMSPEC_BUNDLER_VERSION=$(sed -n -e "s/.*['\"]bundler['\"], *['\"]\([^'\"]*\)['\"]/\1/p" ./*.gemspec | tr -d ' ')
|
12
|
-
if [ -n "${GEMSPEC_BUNDLER_VERSION}" ]; then
|
13
|
-
BUNDLER_COMMAND="bundler _${GEMSPEC_BUNDLER_VERSION}_"
|
14
|
-
else
|
15
|
-
BUNDLER_COMMAND="bundler"
|
16
|
-
fi
|
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -ue
|
4
|
-
|
5
|
-
echo "Using gem $(gem --version)"
|
6
|
-
|
7
|
-
#shellcheck source=/dev/null
|
8
|
-
source "$(dirname "$0")/gems-setup.sh"
|
9
|
-
|
10
|
-
# If the gemspec specifies a certain version of bundler, we need to make sure we install that version.
|
11
|
-
echo "Installing bundler"
|
12
|
-
if [ -n "${GEMSPEC_BUNDLER_VERSION:-}" ]; then
|
13
|
-
GEMSPEC_OPTIONS="-v ${GEMSPEC_BUNDLER_VERSION}"
|
14
|
-
else
|
15
|
-
GEMSPEC_OPTIONS=""
|
16
|
-
fi
|
17
|
-
gem install bundler ${GEMSPEC_OPTIONS} || { echo "installing bundler failed" >&2; exit 1; }
|
@@ -1,19 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -ue
|
4
|
-
|
5
|
-
# Standard publish.sh for Ruby-based projects - we can assume build.sh has already been run
|
6
|
-
|
7
|
-
#shellcheck source=/dev/null
|
8
|
-
source "$(dirname "$0")/gems-setup.sh"
|
9
|
-
|
10
|
-
# If we're running in CircleCI, the RubyGems credentials will be in an environment
|
11
|
-
# variable and should be copied to the variable the gem command expects
|
12
|
-
if [ -n "${LD_RELEASE_RUBYGEMS_API_KEY:-}" ]; then
|
13
|
-
export GEM_HOST_API_KEY="${LD_RELEASE_RUBYGEMS_API_KEY}"
|
14
|
-
fi
|
15
|
-
|
16
|
-
# Since all Releaser builds are clean builds, we can assume that the only .gem file here
|
17
|
-
# is the one we just built
|
18
|
-
echo "Running gem push"
|
19
|
-
gem push ./*.gem || { echo "gem push failed" >&2; exit 1; }
|
@@ -1,8 +0,0 @@
|
|
1
|
-
#!/bin/bash
|
2
|
-
|
3
|
-
set -ue
|
4
|
-
|
5
|
-
# Standard update-version.sh for Ruby-based projects - this will work only if the version string
|
6
|
-
# is in a source file under lib/ that has a line like his: VERSION = "2.0.0"
|
7
|
-
|
8
|
-
"$(dirname "$0")/../update-version-constant.sh" lib '*.rb'
|
@@ -1,19 +0,0 @@
|
|
1
|
-
param(
|
2
|
-
[string]$step,
|
3
|
-
[string]$script
|
4
|
-
)
|
5
|
-
|
6
|
-
# Performs a delegated release step in a CircleCI Windows container using PowerShell. This
|
7
|
-
# mechanism is described in scripts/circleci/README.md. All of the necessary environment
|
8
|
-
# variables should already be in the generated CircleCI configuration.
|
9
|
-
|
10
|
-
$ErrorActionPreference = "Stop"
|
11
|
-
|
12
|
-
New-Item -Path "./artifacts" -ItemType "directory" -Force | Out-Null
|
13
|
-
|
14
|
-
$env:LD_RELEASE_TEMP_DIR = "$env:TEMP\project-releaser-temp"
|
15
|
-
New-Item -Path $env:LD_RELEASE_TEMP_DIR -ItemType "directory" -Force | Out-Null
|
16
|
-
|
17
|
-
Write-Host
|
18
|
-
Write-Host "[$step] executing $script"
|
19
|
-
& "./$script"
|