flipper 0.26.0 → 0.27.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +13 -11
  3. data/.github/workflows/examples.yml +5 -10
  4. data/Changelog.md +16 -0
  5. data/Gemfile +6 -3
  6. data/benchmark/enabled_ips.rb +10 -0
  7. data/benchmark/enabled_profile.rb +20 -0
  8. data/benchmark/instrumentation_ips.rb +21 -0
  9. data/benchmark/typecast_ips.rb +19 -0
  10. data/examples/api/basic.ru +3 -4
  11. data/examples/api/custom_memoized.ru +3 -4
  12. data/examples/api/memoized.ru +3 -4
  13. data/flipper.gemspec +0 -2
  14. data/lib/flipper/adapter.rb +23 -7
  15. data/lib/flipper/adapters/http.rb +11 -3
  16. data/lib/flipper/adapters/instrumented.rb +25 -2
  17. data/lib/flipper/adapters/memoizable.rb +19 -2
  18. data/lib/flipper/adapters/memory.rb +56 -39
  19. data/lib/flipper/adapters/operation_logger.rb +16 -3
  20. data/lib/flipper/adapters/poll/poller.rb +2 -125
  21. data/lib/flipper/adapters/poll.rb +4 -0
  22. data/lib/flipper/dsl.rb +1 -5
  23. data/lib/flipper/export.rb +26 -0
  24. data/lib/flipper/exporter.rb +17 -0
  25. data/lib/flipper/exporters/json/export.rb +32 -0
  26. data/lib/flipper/exporters/json/v1.rb +33 -0
  27. data/lib/flipper/feature.rb +22 -18
  28. data/lib/flipper/feature_check_context.rb +4 -4
  29. data/lib/flipper/gate_values.rb +0 -16
  30. data/lib/flipper/gates/actor.rb +2 -12
  31. data/lib/flipper/gates/boolean.rb +1 -1
  32. data/lib/flipper/gates/group.rb +4 -8
  33. data/lib/flipper/gates/percentage_of_actors.rb +9 -11
  34. data/lib/flipper/gates/percentage_of_time.rb +1 -2
  35. data/lib/flipper/instrumentation/subscriber.rb +8 -0
  36. data/lib/flipper/poller.rb +117 -0
  37. data/lib/flipper/spec/shared_adapter_specs.rb +23 -0
  38. data/lib/flipper/test/shared_adapter_test.rb +24 -0
  39. data/lib/flipper/typecast.rb +28 -15
  40. data/lib/flipper/version.rb +1 -1
  41. data/lib/flipper.rb +2 -1
  42. data/spec/fixtures/flipper_pstore_1679087600.json +46 -0
  43. data/spec/flipper/adapter_spec.rb +29 -2
  44. data/spec/flipper/adapters/http_spec.rb +25 -3
  45. data/spec/flipper/adapters/instrumented_spec.rb +28 -10
  46. data/spec/flipper/adapters/memoizable_spec.rb +30 -10
  47. data/spec/flipper/adapters/memory_spec.rb +3 -1
  48. data/spec/flipper/adapters/operation_logger_spec.rb +29 -10
  49. data/spec/flipper/dsl_spec.rb +20 -3
  50. data/spec/flipper/export_spec.rb +13 -0
  51. data/spec/flipper/exporter_spec.rb +16 -0
  52. data/spec/flipper/exporters/json/export_spec.rb +60 -0
  53. data/spec/flipper/exporters/json/v1_spec.rb +33 -0
  54. data/spec/flipper/feature_check_context_spec.rb +12 -12
  55. data/spec/flipper/gate_values_spec.rb +2 -33
  56. data/spec/flipper/gates/percentage_of_actors_spec.rb +1 -1
  57. data/spec/flipper/instrumentation/log_subscriber_spec.rb +10 -0
  58. data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +10 -0
  59. data/spec/flipper/poller_spec.rb +47 -0
  60. data/spec/flipper/typecast_spec.rb +82 -3
  61. data/spec/flipper_spec.rb +7 -1
  62. data/spec/spec_helper.rb +1 -1
  63. data/spec/support/skippable.rb +18 -0
  64. metadata +25 -3
  65. 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(KeyError)
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(KeyError)
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(KeyError)
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 an integer))
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 an integer))
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: thing || Flipper::Types::Actor.new(Flipper::Actor.new(1))
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.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 an integer))
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 float))
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::Adapters::Poll::Poller.reset if defined?(Flipper::Adapters::Poll::Poller)
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.26.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: 2022-12-05 00:00:00.000000000 Z
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 }}