flipper 0.26.0 → 0.27.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 +4 -4
- data/.github/workflows/ci.yml +13 -11
- data/.github/workflows/examples.yml +5 -10
- data/Changelog.md +16 -0
- data/Gemfile +6 -3
- data/benchmark/enabled_ips.rb +10 -0
- data/benchmark/enabled_profile.rb +20 -0
- data/benchmark/instrumentation_ips.rb +21 -0
- data/benchmark/typecast_ips.rb +19 -0
- data/examples/api/basic.ru +3 -4
- data/examples/api/custom_memoized.ru +3 -4
- data/examples/api/memoized.ru +3 -4
- data/flipper.gemspec +0 -2
- data/lib/flipper/adapter.rb +23 -7
- data/lib/flipper/adapters/http.rb +11 -3
- data/lib/flipper/adapters/instrumented.rb +25 -2
- data/lib/flipper/adapters/memoizable.rb +19 -2
- data/lib/flipper/adapters/memory.rb +56 -39
- data/lib/flipper/adapters/operation_logger.rb +16 -3
- data/lib/flipper/adapters/poll/poller.rb +2 -125
- data/lib/flipper/adapters/poll.rb +4 -0
- data/lib/flipper/dsl.rb +1 -5
- data/lib/flipper/export.rb +26 -0
- data/lib/flipper/exporter.rb +17 -0
- data/lib/flipper/exporters/json/export.rb +32 -0
- data/lib/flipper/exporters/json/v1.rb +33 -0
- data/lib/flipper/feature.rb +22 -18
- data/lib/flipper/feature_check_context.rb +4 -4
- data/lib/flipper/gate_values.rb +0 -16
- data/lib/flipper/gates/actor.rb +2 -12
- data/lib/flipper/gates/boolean.rb +1 -1
- data/lib/flipper/gates/group.rb +4 -8
- data/lib/flipper/gates/percentage_of_actors.rb +9 -11
- data/lib/flipper/gates/percentage_of_time.rb +1 -2
- data/lib/flipper/instrumentation/subscriber.rb +8 -0
- data/lib/flipper/poller.rb +117 -0
- data/lib/flipper/spec/shared_adapter_specs.rb +23 -0
- data/lib/flipper/test/shared_adapter_test.rb +24 -0
- data/lib/flipper/typecast.rb +28 -15
- data/lib/flipper/version.rb +1 -1
- data/lib/flipper.rb +2 -1
- data/spec/fixtures/flipper_pstore_1679087600.json +46 -0
- data/spec/flipper/adapter_spec.rb +29 -2
- data/spec/flipper/adapters/http_spec.rb +25 -3
- data/spec/flipper/adapters/instrumented_spec.rb +28 -10
- data/spec/flipper/adapters/memoizable_spec.rb +30 -10
- data/spec/flipper/adapters/memory_spec.rb +3 -1
- data/spec/flipper/adapters/operation_logger_spec.rb +29 -10
- data/spec/flipper/dsl_spec.rb +20 -3
- data/spec/flipper/export_spec.rb +13 -0
- data/spec/flipper/exporter_spec.rb +16 -0
- data/spec/flipper/exporters/json/export_spec.rb +60 -0
- data/spec/flipper/exporters/json/v1_spec.rb +33 -0
- data/spec/flipper/feature_check_context_spec.rb +12 -12
- data/spec/flipper/gate_values_spec.rb +2 -33
- data/spec/flipper/gates/percentage_of_actors_spec.rb +1 -1
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +10 -0
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +10 -0
- data/spec/flipper/poller_spec.rb +47 -0
- data/spec/flipper/typecast_spec.rb +82 -3
- data/spec/flipper_spec.rb +7 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/support/skippable.rb +18 -0
- metadata +25 -3
- data/.github/workflows/release.yml +0 -44
@@ -11,7 +11,7 @@ RSpec.describe Flipper::FeatureCheckContext do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'initializes just fine' do
|
14
|
-
instance = described_class.new(options)
|
14
|
+
instance = described_class.new(**options)
|
15
15
|
expect(instance.feature_name).to eq(feature_name)
|
16
16
|
expect(instance.values).to eq(values)
|
17
17
|
expect(instance.thing).to eq(thing)
|
@@ -20,46 +20,46 @@ RSpec.describe Flipper::FeatureCheckContext do
|
|
20
20
|
it 'requires feature_name' do
|
21
21
|
options.delete(:feature_name)
|
22
22
|
expect do
|
23
|
-
described_class.new(options)
|
24
|
-
end.to raise_error(
|
23
|
+
described_class.new(**options)
|
24
|
+
end.to raise_error(ArgumentError)
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'requires values' do
|
28
28
|
options.delete(:values)
|
29
29
|
expect do
|
30
|
-
described_class.new(options)
|
31
|
-
end.to raise_error(
|
30
|
+
described_class.new(**options)
|
31
|
+
end.to raise_error(ArgumentError)
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'requires thing' do
|
35
35
|
options.delete(:thing)
|
36
36
|
expect do
|
37
|
-
described_class.new(options)
|
38
|
-
end.to raise_error(
|
37
|
+
described_class.new(**options)
|
38
|
+
end.to raise_error(ArgumentError)
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'knows actors_value' do
|
42
42
|
args = options.merge(values: Flipper::GateValues.new(actors: Set['User;1']))
|
43
|
-
expect(described_class.new(args).actors_value).to eq(Set['User;1'])
|
43
|
+
expect(described_class.new(**args).actors_value).to eq(Set['User;1'])
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'knows groups_value' do
|
47
47
|
args = options.merge(values: Flipper::GateValues.new(groups: Set['admins']))
|
48
|
-
expect(described_class.new(args).groups_value).to eq(Set['admins'])
|
48
|
+
expect(described_class.new(**args).groups_value).to eq(Set['admins'])
|
49
49
|
end
|
50
50
|
|
51
51
|
it 'knows boolean_value' do
|
52
|
-
instance = described_class.new(options.merge(values: Flipper::GateValues.new(boolean: true)))
|
52
|
+
instance = described_class.new(**options.merge(values: Flipper::GateValues.new(boolean: true)))
|
53
53
|
expect(instance.boolean_value).to eq(true)
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'knows percentage_of_actors_value' do
|
57
57
|
args = options.merge(values: Flipper::GateValues.new(percentage_of_actors: 14))
|
58
|
-
expect(described_class.new(args).percentage_of_actors_value).to eq(14)
|
58
|
+
expect(described_class.new(**args).percentage_of_actors_value).to eq(14)
|
59
59
|
end
|
60
60
|
|
61
61
|
it 'knows percentage_of_time_value' do
|
62
62
|
args = options.merge(values: Flipper::GateValues.new(percentage_of_time: 41))
|
63
|
-
expect(described_class.new(args).percentage_of_time_value).to eq(41)
|
63
|
+
expect(described_class.new(**args).percentage_of_time_value).to eq(41)
|
64
64
|
end
|
65
65
|
end
|
@@ -80,13 +80,13 @@ RSpec.describe Flipper::GateValues do
|
|
80
80
|
it 'raises argument error for percentage of time value that cannot be converted to an integer' do
|
81
81
|
expect do
|
82
82
|
described_class.new(percentage_of_time: ['asdf'])
|
83
|
-
end.to raise_error(ArgumentError, %(["asdf"] cannot be converted to
|
83
|
+
end.to raise_error(ArgumentError, %(["asdf"] cannot be converted to a percentage))
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'raises argument error for percentage of actors value that cannot be converted to an int' do
|
87
87
|
expect do
|
88
88
|
described_class.new(percentage_of_actors: ['asdf'])
|
89
|
-
end.to raise_error(ArgumentError, %(["asdf"] cannot be converted to
|
89
|
+
end.to raise_error(ArgumentError, %(["asdf"] cannot be converted to a percentage))
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'raises argument error for actors value that cannot be converted to a set' do
|
@@ -100,35 +100,4 @@ RSpec.describe Flipper::GateValues do
|
|
100
100
|
described_class.new(groups: 'asdf')
|
101
101
|
end.to raise_error(ArgumentError, %("asdf" cannot be converted to a set))
|
102
102
|
end
|
103
|
-
|
104
|
-
describe '#[]' do
|
105
|
-
it 'can read the boolean value' do
|
106
|
-
expect(described_class.new(boolean: true)[:boolean]).to be(true)
|
107
|
-
expect(described_class.new(boolean: true)['boolean']).to be(true)
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'can read the actors value' do
|
111
|
-
expect(described_class.new(actors: Set[1, 2])[:actors]).to eq(Set[1, 2])
|
112
|
-
expect(described_class.new(actors: Set[1, 2])['actors']).to eq(Set[1, 2])
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'can read the groups value' do
|
116
|
-
expect(described_class.new(groups: Set[:admins])[:groups]).to eq(Set[:admins])
|
117
|
-
expect(described_class.new(groups: Set[:admins])['groups']).to eq(Set[:admins])
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'can read the percentage of time value' do
|
121
|
-
expect(described_class.new(percentage_of_time: 15)[:percentage_of_time]).to eq(15)
|
122
|
-
expect(described_class.new(percentage_of_time: 15)['percentage_of_time']).to eq(15)
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'can read the percentage of actors value' do
|
126
|
-
expect(described_class.new(percentage_of_actors: 15)[:percentage_of_actors]).to eq(15)
|
127
|
-
expect(described_class.new(percentage_of_actors: 15)['percentage_of_actors']).to eq(15)
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'returns nil for value that is not present' do
|
131
|
-
expect(described_class.new({})['not legit']).to be(nil)
|
132
|
-
end
|
133
|
-
end
|
134
103
|
end
|
@@ -9,7 +9,7 @@ RSpec.describe Flipper::Gates::PercentageOfActors do
|
|
9
9
|
Flipper::FeatureCheckContext.new(
|
10
10
|
feature_name: feature,
|
11
11
|
values: Flipper::GateValues.new(percentage_of_actors: percentage_of_actors_value),
|
12
|
-
thing:
|
12
|
+
thing: Flipper::Types::Actor.new(thing || Flipper::Actor.new(1))
|
13
13
|
)
|
14
14
|
end
|
15
15
|
|
@@ -2,6 +2,12 @@ require 'logger'
|
|
2
2
|
require 'flipper/adapters/instrumented'
|
3
3
|
require 'flipper/instrumentation/log_subscriber'
|
4
4
|
|
5
|
+
begin
|
6
|
+
require 'active_support/isolated_execution_state'
|
7
|
+
rescue LoadError
|
8
|
+
# ActiveSupport::IsolatedExecutionState is only available in Rails 5.2+
|
9
|
+
end
|
10
|
+
|
5
11
|
RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
6
12
|
let(:adapter) do
|
7
13
|
memory = Flipper::Adapters::Memory.new
|
@@ -26,6 +32,10 @@ RSpec.describe Flipper::Instrumentation::LogSubscriber do
|
|
26
32
|
described_class.logger = nil
|
27
33
|
end
|
28
34
|
|
35
|
+
after(:all) do
|
36
|
+
ActiveSupport::Notifications.unsubscribe("flipper")
|
37
|
+
end
|
38
|
+
|
29
39
|
let(:log) { @io.string }
|
30
40
|
|
31
41
|
context 'feature enabled checks' do
|
@@ -2,6 +2,12 @@ require 'flipper/adapters/instrumented'
|
|
2
2
|
require 'flipper/instrumentation/statsd'
|
3
3
|
require 'statsd'
|
4
4
|
|
5
|
+
begin
|
6
|
+
require 'active_support/isolated_execution_state'
|
7
|
+
rescue LoadError
|
8
|
+
# ActiveSupport::IsolatedExecutionState is only available in Rails 5.2+
|
9
|
+
end
|
10
|
+
|
5
11
|
RSpec.describe Flipper::Instrumentation::StatsdSubscriber do
|
6
12
|
let(:statsd_client) { Statsd.new }
|
7
13
|
let(:socket) { FakeUDPSocket.new }
|
@@ -25,6 +31,10 @@ RSpec.describe Flipper::Instrumentation::StatsdSubscriber do
|
|
25
31
|
Thread.current[:statsd_socket] = nil
|
26
32
|
end
|
27
33
|
|
34
|
+
after(:all) do
|
35
|
+
ActiveSupport::Notifications.unsubscribe("flipper")
|
36
|
+
end
|
37
|
+
|
28
38
|
def assert_timer(metric)
|
29
39
|
regex = /#{Regexp.escape metric}\:\d+\|ms/
|
30
40
|
result = socket.buffer.detect { |op| op.first =~ regex }
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "flipper/poller"
|
2
|
+
|
3
|
+
RSpec.describe Flipper::Poller do
|
4
|
+
let(:remote_adapter) { Flipper::Adapters::Memory.new }
|
5
|
+
let(:remote) { Flipper.new(remote_adapter) }
|
6
|
+
let(:local) { Flipper.new(subject.adapter) }
|
7
|
+
|
8
|
+
subject do
|
9
|
+
described_class.new(
|
10
|
+
remote_adapter: remote_adapter,
|
11
|
+
start_automatically: false,
|
12
|
+
interval: Float::INFINITY
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
before do
|
17
|
+
allow(subject).to receive(:loop).and_yield # Make loop just call once
|
18
|
+
allow(subject).to receive(:sleep) # Disable sleep
|
19
|
+
allow(Thread).to receive(:new).and_yield # Disable separate thread
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#adapter" do
|
23
|
+
it "always returns same memory adapter instance" do
|
24
|
+
expect(subject.adapter).to be_a(Flipper::Adapters::Memory)
|
25
|
+
expect(subject.adapter.object_id).to eq(subject.adapter.object_id)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#sync" do
|
30
|
+
it "syncs remote adapter to local adapter" do
|
31
|
+
remote.enable :polling
|
32
|
+
|
33
|
+
expect(local.enabled?(:polling)).to be(false)
|
34
|
+
subject.sync
|
35
|
+
expect(local.enabled?(:polling)).to be(true)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#start" do
|
40
|
+
it "starts the poller thread" do
|
41
|
+
expect(Thread).to receive(:new).and_yield
|
42
|
+
expect(subject).to receive(:loop).and_yield
|
43
|
+
expect(subject).to receive(:sync)
|
44
|
+
subject.start
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -56,7 +56,7 @@ RSpec.describe Flipper::Typecast do
|
|
56
56
|
nil => 0,
|
57
57
|
'' => 0,
|
58
58
|
0 => 0,
|
59
|
-
0.0 => 0
|
59
|
+
0.0 => 0,
|
60
60
|
1 => 1,
|
61
61
|
1.1 => 1.1,
|
62
62
|
'0.01' => 0.01,
|
@@ -100,13 +100,13 @@ RSpec.describe Flipper::Typecast do
|
|
100
100
|
it 'raises argument error for bad integer percentage' do
|
101
101
|
expect do
|
102
102
|
described_class.to_percentage(['asdf'])
|
103
|
-
end.to raise_error(ArgumentError, %(["asdf"] cannot be converted to
|
103
|
+
end.to raise_error(ArgumentError, %(["asdf"] cannot be converted to a percentage))
|
104
104
|
end
|
105
105
|
|
106
106
|
it 'raises argument error for bad float percentage' do
|
107
107
|
expect do
|
108
108
|
described_class.to_percentage(['asdf.0'])
|
109
|
-
end.to raise_error(ArgumentError, %(["asdf.0"] cannot be converted to a
|
109
|
+
end.to raise_error(ArgumentError, %(["asdf.0"] cannot be converted to a percentage))
|
110
110
|
end
|
111
111
|
|
112
112
|
it 'raises argument error for set value that cannot be converted to a set' do
|
@@ -114,4 +114,83 @@ RSpec.describe Flipper::Typecast do
|
|
114
114
|
described_class.to_set('asdf')
|
115
115
|
end.to raise_error(ArgumentError, %("asdf" cannot be converted to a set))
|
116
116
|
end
|
117
|
+
|
118
|
+
describe "#features_hash" do
|
119
|
+
it "returns new hash" do
|
120
|
+
hash = {
|
121
|
+
"search" => {
|
122
|
+
boolean: nil,
|
123
|
+
}
|
124
|
+
}
|
125
|
+
result = described_class.features_hash(hash)
|
126
|
+
expect(result).not_to be(hash)
|
127
|
+
expect(result["search"]).not_to be(hash["search"])
|
128
|
+
end
|
129
|
+
|
130
|
+
it "converts gate value arrays to sets" do
|
131
|
+
hash = {
|
132
|
+
"search" => {
|
133
|
+
boolean: nil,
|
134
|
+
groups: ['a', 'b'],
|
135
|
+
actors: ['User;1'],
|
136
|
+
percentage_of_actors: nil,
|
137
|
+
percentage_of_time: nil,
|
138
|
+
},
|
139
|
+
}
|
140
|
+
result = described_class.features_hash(hash)
|
141
|
+
expect(result).to eq({
|
142
|
+
"search" => {
|
143
|
+
boolean: nil,
|
144
|
+
groups: Set['a', 'b'],
|
145
|
+
actors: Set['User;1'],
|
146
|
+
percentage_of_actors: nil,
|
147
|
+
percentage_of_time: nil,
|
148
|
+
},
|
149
|
+
})
|
150
|
+
end
|
151
|
+
|
152
|
+
it "converts gate value boolean and integers to strings" do
|
153
|
+
hash = {
|
154
|
+
"search" => {
|
155
|
+
boolean: true,
|
156
|
+
groups: Set.new,
|
157
|
+
actors: Set.new,
|
158
|
+
percentage_of_actors: 10,
|
159
|
+
percentage_of_time: 15,
|
160
|
+
},
|
161
|
+
}
|
162
|
+
result = described_class.features_hash(hash)
|
163
|
+
expect(result).to eq({
|
164
|
+
"search" => {
|
165
|
+
boolean: "true",
|
166
|
+
groups: Set.new,
|
167
|
+
actors: Set.new,
|
168
|
+
percentage_of_actors: "10",
|
169
|
+
percentage_of_time: "15",
|
170
|
+
},
|
171
|
+
})
|
172
|
+
end
|
173
|
+
|
174
|
+
it "converts string gate keys to symbols" do
|
175
|
+
hash = {
|
176
|
+
"search" => {
|
177
|
+
"boolean" => nil,
|
178
|
+
"groups" => Set.new,
|
179
|
+
"actors" => Set.new,
|
180
|
+
"percentage_of_actors" => nil,
|
181
|
+
"percentage_of_time" => nil,
|
182
|
+
},
|
183
|
+
}
|
184
|
+
result = described_class.features_hash(hash)
|
185
|
+
expect(result).to eq({
|
186
|
+
"search" => {
|
187
|
+
boolean: nil,
|
188
|
+
groups: Set.new,
|
189
|
+
actors: Set.new,
|
190
|
+
percentage_of_actors: nil,
|
191
|
+
percentage_of_time: nil,
|
192
|
+
},
|
193
|
+
})
|
194
|
+
end
|
195
|
+
end
|
117
196
|
end
|
data/spec/flipper_spec.rb
CHANGED
@@ -202,6 +202,12 @@ RSpec.describe Flipper do
|
|
202
202
|
expect(described_class.enabled?(:search)).to be(true)
|
203
203
|
end
|
204
204
|
|
205
|
+
it 'delegates export to instance' do
|
206
|
+
described_class.enable(:search)
|
207
|
+
expect(described_class.export).to eq(described_class.adapter.export)
|
208
|
+
expect(described_class.export(format: :json)).to eq(described_class.adapter.export(format: :json))
|
209
|
+
end
|
210
|
+
|
205
211
|
it 'delegates adapter to instance' do
|
206
212
|
expect(described_class.adapter).to eq(described_class.instance.adapter)
|
207
213
|
end
|
@@ -222,7 +228,7 @@ RSpec.describe Flipper do
|
|
222
228
|
end
|
223
229
|
|
224
230
|
it 'delegates sync stuff to instance for Flipper::Cloud' do
|
225
|
-
stub = stub_request(:get, "https://www.flippercloud.io/adapter/features").
|
231
|
+
stub = stub_request(:get, "https://www.flippercloud.io/adapter/features?exclude_gate_names=true").
|
226
232
|
with({
|
227
233
|
headers: {
|
228
234
|
'Flipper-Cloud-Token'=>'asdf',
|
data/spec/spec_helper.rb
CHANGED
@@ -22,7 +22,7 @@ Dir[FlipperRoot.join('spec/support/**/*.rb')].sort.each { |f| require f }
|
|
22
22
|
|
23
23
|
RSpec.configure do |config|
|
24
24
|
config.before(:example) do
|
25
|
-
Flipper::
|
25
|
+
Flipper::Poller.reset if defined?(Flipper::Poller)
|
26
26
|
Flipper.unregister_groups
|
27
27
|
Flipper.configuration = nil
|
28
28
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.before(:all) do
|
3
|
+
$skip = false
|
4
|
+
end
|
5
|
+
|
6
|
+
def skip_on_error(error, message, &block)
|
7
|
+
# Premptively skip if we've already skipped
|
8
|
+
skip(message) if $skip
|
9
|
+
block.call
|
10
|
+
rescue error
|
11
|
+
if ENV["CI"]
|
12
|
+
raise
|
13
|
+
else
|
14
|
+
$skip = true
|
15
|
+
skip(message)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flipper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.27.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -35,7 +35,6 @@ files:
|
|
35
35
|
- ".github/dependabot.yml"
|
36
36
|
- ".github/workflows/ci.yml"
|
37
37
|
- ".github/workflows/examples.yml"
|
38
|
-
- ".github/workflows/release.yml"
|
39
38
|
- ".rspec"
|
40
39
|
- ".tool-versions"
|
41
40
|
- CODE_OF_CONDUCT.md
|
@@ -45,6 +44,10 @@ files:
|
|
45
44
|
- LICENSE
|
46
45
|
- README.md
|
47
46
|
- Rakefile
|
47
|
+
- benchmark/enabled_ips.rb
|
48
|
+
- benchmark/enabled_profile.rb
|
49
|
+
- benchmark/instrumentation_ips.rb
|
50
|
+
- benchmark/typecast_ips.rb
|
48
51
|
- docker-compose.yml
|
49
52
|
- docs/DockerCompose.md
|
50
53
|
- docs/README.md
|
@@ -93,6 +96,10 @@ files:
|
|
93
96
|
- lib/flipper/configuration.rb
|
94
97
|
- lib/flipper/dsl.rb
|
95
98
|
- lib/flipper/errors.rb
|
99
|
+
- lib/flipper/export.rb
|
100
|
+
- lib/flipper/exporter.rb
|
101
|
+
- lib/flipper/exporters/json/export.rb
|
102
|
+
- lib/flipper/exporters/json/v1.rb
|
96
103
|
- lib/flipper/feature.rb
|
97
104
|
- lib/flipper/feature_check_context.rb
|
98
105
|
- lib/flipper/gate.rb
|
@@ -112,6 +119,7 @@ files:
|
|
112
119
|
- lib/flipper/metadata.rb
|
113
120
|
- lib/flipper/middleware/memoizer.rb
|
114
121
|
- lib/flipper/middleware/setup_env.rb
|
122
|
+
- lib/flipper/poller.rb
|
115
123
|
- lib/flipper/railtie.rb
|
116
124
|
- lib/flipper/registry.rb
|
117
125
|
- lib/flipper/spec/shared_adapter_specs.rb
|
@@ -126,6 +134,7 @@ files:
|
|
126
134
|
- lib/flipper/types/percentage_of_time.rb
|
127
135
|
- lib/flipper/version.rb
|
128
136
|
- spec/fixtures/feature.json
|
137
|
+
- spec/fixtures/flipper_pstore_1679087600.json
|
129
138
|
- spec/flipper/actor_spec.rb
|
130
139
|
- spec/flipper/adapter_spec.rb
|
131
140
|
- spec/flipper/adapters/dual_write_spec.rb
|
@@ -144,6 +153,10 @@ files:
|
|
144
153
|
- spec/flipper/adapters/sync_spec.rb
|
145
154
|
- spec/flipper/configuration_spec.rb
|
146
155
|
- spec/flipper/dsl_spec.rb
|
156
|
+
- spec/flipper/export_spec.rb
|
157
|
+
- spec/flipper/exporter_spec.rb
|
158
|
+
- spec/flipper/exporters/json/export_spec.rb
|
159
|
+
- spec/flipper/exporters/json/v1_spec.rb
|
147
160
|
- spec/flipper/feature_check_context_spec.rb
|
148
161
|
- spec/flipper/feature_spec.rb
|
149
162
|
- spec/flipper/gate_spec.rb
|
@@ -160,6 +173,7 @@ files:
|
|
160
173
|
- spec/flipper/instrumenters/noop_spec.rb
|
161
174
|
- spec/flipper/middleware/memoizer_spec.rb
|
162
175
|
- spec/flipper/middleware/setup_env_spec.rb
|
176
|
+
- spec/flipper/poller_spec.rb
|
163
177
|
- spec/flipper/railtie_spec.rb
|
164
178
|
- spec/flipper/registry_spec.rb
|
165
179
|
- spec/flipper/typecast_spec.rb
|
@@ -174,6 +188,7 @@ files:
|
|
174
188
|
- spec/spec_helper.rb
|
175
189
|
- spec/support/descriptions.yml
|
176
190
|
- spec/support/fake_udp_socket.rb
|
191
|
+
- spec/support/skippable.rb
|
177
192
|
- spec/support/spec_helpers.rb
|
178
193
|
- test/adapters/memory_test.rb
|
179
194
|
- test/adapters/pstore_test.rb
|
@@ -205,6 +220,7 @@ specification_version: 4
|
|
205
220
|
summary: Feature flipper for ANYTHING
|
206
221
|
test_files:
|
207
222
|
- spec/fixtures/feature.json
|
223
|
+
- spec/fixtures/flipper_pstore_1679087600.json
|
208
224
|
- spec/flipper/actor_spec.rb
|
209
225
|
- spec/flipper/adapter_spec.rb
|
210
226
|
- spec/flipper/adapters/dual_write_spec.rb
|
@@ -223,6 +239,10 @@ test_files:
|
|
223
239
|
- spec/flipper/adapters/sync_spec.rb
|
224
240
|
- spec/flipper/configuration_spec.rb
|
225
241
|
- spec/flipper/dsl_spec.rb
|
242
|
+
- spec/flipper/export_spec.rb
|
243
|
+
- spec/flipper/exporter_spec.rb
|
244
|
+
- spec/flipper/exporters/json/export_spec.rb
|
245
|
+
- spec/flipper/exporters/json/v1_spec.rb
|
226
246
|
- spec/flipper/feature_check_context_spec.rb
|
227
247
|
- spec/flipper/feature_spec.rb
|
228
248
|
- spec/flipper/gate_spec.rb
|
@@ -239,6 +259,7 @@ test_files:
|
|
239
259
|
- spec/flipper/instrumenters/noop_spec.rb
|
240
260
|
- spec/flipper/middleware/memoizer_spec.rb
|
241
261
|
- spec/flipper/middleware/setup_env_spec.rb
|
262
|
+
- spec/flipper/poller_spec.rb
|
242
263
|
- spec/flipper/railtie_spec.rb
|
243
264
|
- spec/flipper/registry_spec.rb
|
244
265
|
- spec/flipper/typecast_spec.rb
|
@@ -253,6 +274,7 @@ test_files:
|
|
253
274
|
- spec/spec_helper.rb
|
254
275
|
- spec/support/descriptions.yml
|
255
276
|
- spec/support/fake_udp_socket.rb
|
277
|
+
- spec/support/skippable.rb
|
256
278
|
- spec/support/spec_helpers.rb
|
257
279
|
- test/adapters/memory_test.rb
|
258
280
|
- test/adapters/pstore_test.rb
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# https://andrewm.codes/blog/automating-ruby-gem-releases-with-github-actions/
|
2
|
-
name: release
|
3
|
-
|
4
|
-
on:
|
5
|
-
push:
|
6
|
-
branches:
|
7
|
-
- main
|
8
|
-
|
9
|
-
jobs:
|
10
|
-
release-please:
|
11
|
-
runs-on: ubuntu-latest
|
12
|
-
steps:
|
13
|
-
- uses: google-github-actions/release-please-action@v3
|
14
|
-
id: release
|
15
|
-
with:
|
16
|
-
release-type: ruby
|
17
|
-
package-name: flipper
|
18
|
-
bump-minor-pre-major: true
|
19
|
-
version-file: "lib/flipper/version.rb"
|
20
|
-
# Checkout code if release was created
|
21
|
-
- uses: actions/checkout@v3
|
22
|
-
if: ${{ steps.release.outputs.release_created }}
|
23
|
-
# Setup ruby if a release was created
|
24
|
-
- uses: ruby/setup-ruby@v1
|
25
|
-
with:
|
26
|
-
ruby-version: 3.0.0
|
27
|
-
if: ${{ steps.release.outputs.release_created }}
|
28
|
-
# Bundle install
|
29
|
-
- run: bundle install
|
30
|
-
if: ${{ steps.release.outputs.release_created }}
|
31
|
-
# Publish
|
32
|
-
- name: publish gem
|
33
|
-
run: |
|
34
|
-
mkdir -p $HOME/.gem
|
35
|
-
touch $HOME/.gem/credentials
|
36
|
-
chmod 0600 $HOME/.gem/credentials
|
37
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
38
|
-
gem build *.gemspec
|
39
|
-
gem push *.gem
|
40
|
-
env:
|
41
|
-
# Make sure to update the secret name
|
42
|
-
# if yours isn't named RUBYGEMS_AUTH_TOKEN
|
43
|
-
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
44
|
-
if: ${{ steps.release.outputs.release_created }}
|