flipper 0.21.0 → 0.22.2

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: 25b07936734df32fbd0331822a97059e76ee9919db287e1073c15b338afc5924
4
- data.tar.gz: 221fbb5002318b366d022365b7597f23094d2b50215e9545d3e1c2435faa03ec
3
+ metadata.gz: 11758f40e5798d6592a7f810a32a501593f7a2a59322f8261b8d366c1686fc25
4
+ data.tar.gz: b0f7713f289ef976328f12c31d3e9249251cb2bb196c7b324dcd952eafe00c88
5
5
  SHA512:
6
- metadata.gz: 4529f945a2c71a3c776940cc091e48280e5088e080c203d478aca91e94e52855d4b5c912bae8aad2b7ca95248f42cabf62599a67f307fc98c34faf46c6361bf1
7
- data.tar.gz: 3fed3febaf673456551dea59b13b01777f9f59f9ee267424547b495b4d7f06a7cc5c50521431ef29260585c01f93e05f2c1c30c4e55d5833cfb1cb40fccfb7c3
6
+ metadata.gz: 35d55048b48cb80c10f8242cef4494224858d9bcbd7e8fb934fb12c6348ebb5538d239dad5eddfbf13fcc6cefe1e4e9eddaffecd053628d1390081b4bdf79857
7
+ data.tar.gz: bf145e26dbf12f788d708a4a1b50b3684ce8d53b32a148ee8fde1b697e008ddd0a903a81f20a83b2b78bc270faa9470255e4700e1e8d08b01c905ae4906a8040
data/.codeclimate.yml CHANGED
@@ -1,2 +1,3 @@
1
1
  exclude_patterns:
2
2
  - "lib/flipper/ui/public"
3
+ - "spec/"
@@ -1,10 +1,8 @@
1
1
  name: CI
2
- on:
3
- push:
4
- branches: [master]
5
- pull_request:
2
+ on: [push, pull_request]
6
3
  jobs:
7
- build:
4
+ test:
5
+ name: Test on ruby ${{ matrix.ruby }} and rails ${{ matrix.rails }}
8
6
  runs-on: ubuntu-latest
9
7
  services:
10
8
  redis:
@@ -18,8 +16,8 @@ jobs:
18
16
  strategy:
19
17
  matrix:
20
18
  ruby: ['2.5', '2.6', '2.7']
19
+ rails: ['5.2', '6.0.0', '6.1.0']
21
20
  env:
22
- RAILS_VERSION: 6.0.0
23
21
  SQLITE3_VERSION: 1.4.1
24
22
  REDIS_URL: redis://localhost:6379/0
25
23
  CI: true
@@ -36,10 +34,10 @@ jobs:
36
34
  uses: actions/cache@v1
37
35
  with:
38
36
  path: vendor/bundle
39
- key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
37
+ key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-${{ hashFiles('**/Gemfile.lock') }}
40
38
  restore-keys: |
41
- ${{ runner.os }}-gem-
42
- - name: Set up Ruby
39
+ ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-
40
+ - name: Set up Ruby ${{ matrix.ruby }}
43
41
  uses: actions/setup-ruby@v1
44
42
  with:
45
43
  ruby-version: ${{ matrix.ruby }}
@@ -47,11 +45,9 @@ jobs:
47
45
  run: sudo apt-get -yqq install libpq-dev
48
46
  - name: Install bundler
49
47
  run: gem install bundler
50
- - name: Run bundler
51
- run: bundle install --jobs 4 --retry 3
52
- - name: Run Rake
53
- run: bundle exec rake
54
- - name: Run Examples
48
+ - name: Run Rake with Rails ${{ matrix.rails }}
55
49
  env:
56
- FLIPPER_CLOUD_TOKEN: ${{ secrets.FLIPPER_CLOUD_TOKEN }}
57
- run: script/examples
50
+ RAILS_VERSION: ${{ matrix.rails }}
51
+ run: |
52
+ bundle install --jobs 4 --retry 3
53
+ bundle exec rake
@@ -0,0 +1,56 @@
1
+ name: Examples
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ name: Test on ruby ${{ matrix.ruby }} and rails ${{ matrix.rails }}
6
+ runs-on: ubuntu-latest
7
+ services:
8
+ redis:
9
+ image: redis
10
+ ports: ['6379:6379']
11
+ options: >-
12
+ --health-cmd "redis-cli ping"
13
+ --health-interval 10s
14
+ --health-timeout 5s
15
+ --health-retries 5
16
+ strategy:
17
+ matrix:
18
+ ruby: ['2.5', '2.6', '2.7']
19
+ rails: ['5.2', '6.0.0', '6.1.0']
20
+ env:
21
+ SQLITE3_VERSION: 1.4.1
22
+ REDIS_URL: redis://localhost:6379/0
23
+ CI: true
24
+ steps:
25
+ - name: Setup memcached
26
+ uses: KeisukeYamashita/memcached-actions@v1
27
+ - name: Start MongoDB
28
+ uses: supercharge/mongodb-github-action@1.3.0
29
+ with:
30
+ mongodb-version: 4.0
31
+ - name: Check out repository code
32
+ uses: actions/checkout@v2
33
+ - name: Do some action caching
34
+ uses: actions/cache@v1
35
+ with:
36
+ path: vendor/bundle
37
+ key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-${{ hashFiles('**/Gemfile.lock') }}
38
+ restore-keys: |
39
+ ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-
40
+ - name: Set up Ruby ${{ matrix.ruby }}
41
+ uses: actions/setup-ruby@v1
42
+ with:
43
+ ruby-version: ${{ matrix.ruby }}
44
+ - name: Install libpq-dev
45
+ run: sudo apt-get -yqq install libpq-dev
46
+ - name: Install bundler
47
+ run: gem install bundler
48
+ - name: Bundle install with Rails ${{ matrix.rails }}
49
+ env:
50
+ RAILS_VERSION: ${{ matrix.rails }}
51
+ run: bundle install --jobs 4 --retry 3
52
+ - name: Run Examples with Rails ${{ matrix.rails }}
53
+ env:
54
+ FLIPPER_CLOUD_TOKEN: ${{ secrets.FLIPPER_CLOUD_TOKEN }}
55
+ RAILS_VERSION: ${{ matrix.rails }}
56
+ run: script/examples
data/Changelog.md CHANGED
@@ -1,3 +1,31 @@
1
+ ## 0.22.2
2
+
3
+ ### Additions/Changes
4
+
5
+ * Allow adding multiple actors at once in flipper-ui via comma separation (configurable via `Flipper::UI.configuration.actors_separator`) (https://github.com/jnunemaker/flipper/pull/556)
6
+
7
+ ### Bug Fixes
8
+
9
+ * Fix railtie initialization to avoid altering middleware order (https://github.com/jnunemaker/flipper/pull/563)
10
+
11
+ ## 0.22.1
12
+
13
+ ### Additions/Changes
14
+
15
+ * Remove Octicons and replace with a pure CSS status circle (https://github.com/jnunemaker/flipper/pull/547)
16
+ * Rescue unique errors in AR and Sequel when setting value (https://github.com/jnunemaker/flipper/commit/87f5a98bce7baad7a27b75b5bce3256967769f27)
17
+ * Add a Content-Security-Policy to flipper-ui (https://github.com/jnunemaker/flipper/pull/552)
18
+ * Fix Synchronizer issue that occurs for ActiveRecord adapter (https://github.com/jnunemaker/flipper/pull/554)
19
+
20
+ ## 0.22.0
21
+
22
+ ### Additions/Changes
23
+
24
+ * Enable log subscriber by default in Rails (https://github.com/jnunemaker/flipper/pull/525)
25
+ * Remove memoizer from API and UI (https://github.com/jnunemaker/flipper/pull/527). If you are using the UI or API without configuring the default instance of Flipper, you'll need to enable memoization if you want it. For examples, see the examples/ui and examples/api directories.
26
+ * Fix SQL reserved word use in get_all for ActiveRecord and Sequel (https://github.com/jnunemaker/flipper/pull/536).
27
+ * Handle spaces in names gracefully in UI (https://github.com/jnunemaker/flipper/pull/541).
28
+
1
29
  ## 0.21.0
2
30
 
3
31
  ### Additions/Changes
data/Gemfile CHANGED
@@ -19,6 +19,7 @@ gem 'minitest-documentation'
19
19
  gem 'webmock', '~> 3.0'
20
20
  gem 'climate_control'
21
21
  gem 'redis-namespace'
22
+ gem 'webrick'
22
23
 
23
24
  group(:guard) do
24
25
  gem 'guard', '~> 2.15'
data/README.md CHANGED
@@ -157,6 +157,7 @@ A few miscellaneous docs with more info for the hungry.
157
157
  | pic | @mention | area |
158
158
  |---|---|---|
159
159
  | ![@jnunemaker](https://avatars3.githubusercontent.com/u/235?s=64) | [@jnunemaker](https://github.com/jnunemaker) | most things |
160
+ | ![@bkeepers](https://avatars3.githubusercontent.com/u/173?s=64) | [@bkeepers](https://github.com/bkeepers) | most things |
160
161
  | ![@alexwheeler](https://avatars3.githubusercontent.com/u/3260042?s=64) | [@alexwheeler](https://github.com/alexwheeler) | api |
161
162
  | ![@thetimbanks](https://avatars1.githubusercontent.com/u/471801?s=64) | [@thetimbanks](https://github.com/thetimbanks) | ui |
162
163
  | ![@lazebny](https://avatars1.githubusercontent.com/u/6276766?s=64) | [@lazebny](https://github.com/lazebny) | docker |
data/docker-compose.yml CHANGED
@@ -1,34 +1,37 @@
1
- # postgres:
2
- # container_name: flipper_postgres
3
- # image: postgres:9.4
4
- redis:
5
- container_name: flipper_redis
6
- image: redis:2.8
7
- mongo:
8
- container_name: flipper_mongo
9
- image: mongo:3.3
10
- memcached:
11
- container_name: flipper_memcached
12
- image: memcached:1.4.33
13
- app:
14
- container_name: flipper_app
15
- build: .
16
- dockerfile: Dockerfile
17
- volumes:
18
- - .:/srv/app
19
- volumes_from:
20
- - bundle_cache
21
- links:
22
- # - postgres
23
- - redis
24
- - mongo
25
- - memcached
26
- environment:
27
- - REDIS_URL=redis://redis:6379
28
- - MONGODB_HOST=mongo
29
- - MEMCACHED_URL=memcached:11211
30
- bundle_cache:
31
- container_name: flipper_bundle_cache
32
- image: busybox
33
- volumes:
34
- - /bundle_cache
1
+ version: "2.4"
2
+ services:
3
+ # postgres:
4
+ # container_name: flipper_postgres
5
+ # image: postgres:9.4
6
+ redis:
7
+ container_name: flipper_redis
8
+ image: redis:6.2.5
9
+ mongo:
10
+ container_name: flipper_mongo
11
+ image: mongo:4.4.8
12
+ memcached:
13
+ container_name: flipper_memcached
14
+ image: memcached:1.4.33
15
+ app:
16
+ container_name: flipper_app
17
+ build:
18
+ context: .
19
+ dockerfile: Dockerfile
20
+ volumes:
21
+ - .:/srv/app
22
+ volumes_from:
23
+ - bundle_cache
24
+ links:
25
+ # - postgres
26
+ - redis
27
+ - mongo
28
+ - memcached
29
+ environment:
30
+ - REDIS_URL=redis://redis:6379
31
+ - MONGODB_HOST=mongo
32
+ - MEMCACHED_URL=memcached:11211
33
+ bundle_cache:
34
+ container_name: flipper_bundle_cache
35
+ image: busybox
36
+ volumes:
37
+ - /bundle_cache
data/docs/api/README.md CHANGED
@@ -23,7 +23,7 @@ Or install it yourself as:
23
23
  ```ruby
24
24
  # config/routes.rb
25
25
  YourRailsApp::Application.routes.draw do
26
- mount Flipper::Api.app(flipper) => '/flipper/api'
26
+ mount Flipper::Api.app(Flipper) => '/flipper/api'
27
27
  end
28
28
  ```
29
29
 
@@ -34,8 +34,8 @@ There can be more than one router in your application. Make sure if you choose a
34
34
  *bad:*
35
35
  ```ruby
36
36
  YourRailsApp::Application.routes.draw do
37
- mount Flipper::UI.app(flipper) => '/flipper'
38
- mount Flipper::Api.app(flipper) => '/flipper/api'
37
+ mount Flipper::UI.app(Flipper) => '/flipper'
38
+ mount Flipper::Api.app(Flipper) => '/flipper/api'
39
39
  end
40
40
  ```
41
41
 
@@ -44,8 +44,8 @@ In this case any requests to /flipper\* will be routed to Flipper::UI - includin
44
44
  *good:*
45
45
  ```ruby
46
46
  YourRailsApp::Application.routes.draw do
47
- mount Flipper::Api.app(flipper) => '/flipper/api'
48
- mount Flipper::UI.app(flipper) => '/flipper'
47
+ mount Flipper::Api.app(Flipper) => '/flipper/api'
48
+ mount Flipper::UI.app(Flipper) => '/flipper'
49
49
  end
50
50
  ````
51
51
  For more advanced mounting techniques and for suggestions on how to mount in a non-Rails application, it is recommend that you review the [`Flipper::UI` usage documentation](https://github.com/jnunemaker/flipper/blob/master/docs/ui/README.md#usage) as the same approaches apply to `Flipper::Api`.
@@ -0,0 +1,19 @@
1
+ #
2
+ # Usage:
3
+ # # if you want it to not reload and be really fast
4
+ # bin/rackup examples/api/basic.ru -p 9999
5
+ #
6
+ # # if you want reloading
7
+ # bin/shotgun examples/api/basic.ru -p 9999
8
+ #
9
+ # http://localhost:9999/
10
+ #
11
+
12
+ require 'bundler/setup'
13
+ require "flipper/api"
14
+ require "flipper/adapters/pstore"
15
+
16
+ # You can uncomment this to get some default data:
17
+ # Flipper.enable :logging
18
+
19
+ run Flipper::Api.app
@@ -0,0 +1,37 @@
1
+ #
2
+ # Usage:
3
+ # # if you want it to not reload and be really fast
4
+ # bin/rackup examples/api/custom_memoized.ru -p 9999
5
+ #
6
+ # # if you want reloading
7
+ # bin/shotgun examples/api/custom_memoized.ru -p 9999
8
+ #
9
+ # http://localhost:9999/
10
+ #
11
+
12
+ require 'bundler/setup'
13
+ require "active_support/notifications"
14
+ require "flipper/api"
15
+ require "flipper/adapters/pstore"
16
+
17
+ adapter = Flipper::Adapters::Instrumented.new(
18
+ Flipper::Adapters::PStore.new,
19
+ instrumenter: ActiveSupport::Notifications,
20
+ )
21
+ flipper = Flipper.new(adapter)
22
+
23
+ ActiveSupport::Notifications.subscribe(/.*/, ->(*args) {
24
+ name, start, finish, id, data = args
25
+ case name
26
+ when "adapter_operation.flipper"
27
+ p data[:adapter_name] => data[:operation]
28
+ end
29
+ })
30
+
31
+ # You can uncomment this to get some default data:
32
+ # flipper[:logging].enable_percentage_of_time 5
33
+
34
+ run Flipper::Api.app(flipper) { |builder|
35
+ builder.use Flipper::Middleware::SetupEnv, flipper
36
+ builder.use Flipper::Middleware::Memoizer, preload: true
37
+ }
@@ -0,0 +1,43 @@
1
+ #
2
+ # Usage:
3
+ # # if you want it to not reload and be really fast
4
+ # bin/rackup examples/api/memoized.ru -p 9999
5
+ #
6
+ # # if you want reloading
7
+ # bin/shotgun examples/api/memoized.ru -p 9999
8
+ #
9
+ # http://localhost:9999/
10
+ #
11
+
12
+ require 'bundler/setup'
13
+ require "active_support/notifications"
14
+ require "flipper/api"
15
+ require "flipper/adapters/pstore"
16
+
17
+ Flipper.configure do |config|
18
+ config.adapter {
19
+ Flipper::Adapters::Instrumented.new(
20
+ Flipper::Adapters::PStore.new,
21
+ instrumenter: ActiveSupport::Notifications,
22
+ )
23
+ }
24
+ end
25
+
26
+ ActiveSupport::Notifications.subscribe(/.*/, ->(*args) {
27
+ name, start, finish, id, data = args
28
+ case name
29
+ when "adapter_operation.flipper"
30
+ p data[:adapter_name] => data[:operation]
31
+ end
32
+ })
33
+
34
+ Flipper.register(:admins) { |actor|
35
+ actor.respond_to?(:admin?) && actor.admin?
36
+ }
37
+
38
+ # You can uncomment this to get some default data:
39
+ # Flipper.enable :logging
40
+
41
+ run Flipper::Api.app { |builder|
42
+ builder.use Flipper::Middleware::Memoizer, preload: true
43
+ }
@@ -0,0 +1,37 @@
1
+ # Quick example of how to keep track of when a feature was last checked.
2
+ require 'bundler/setup'
3
+ require 'securerandom'
4
+ require 'active_support/notifications'
5
+ require 'flipper'
6
+
7
+ class FlipperSubscriber
8
+ def self.stats
9
+ @stats ||= {}
10
+ end
11
+
12
+ def call(name, start, finish, id, payload)
13
+ if payload[:operation] == :enabled?
14
+ feature_name = payload.fetch(:feature_name)
15
+ self.class.stats[feature_name] = Time.now
16
+ end
17
+ end
18
+
19
+ ActiveSupport::Notifications.subscribe(/feature_operation.flipper/, new)
20
+ end
21
+
22
+ Flipper.configure do |config|
23
+ config.default {
24
+ Flipper.new(config.adapter, instrumenter: ActiveSupport::Notifications)
25
+ }
26
+ end
27
+
28
+ Flipper.enabled?(:search)
29
+ Flipper.enabled?(:booyeah)
30
+ Flipper.enabled?(:hooray)
31
+ sleep 1
32
+ Flipper.enabled?(:booyeah)
33
+ Flipper.enabled?(:hooray)
34
+ sleep 1
35
+ Flipper.enabled?(:hooray)
36
+
37
+ pp FlipperSubscriber.stats
@@ -37,7 +37,8 @@ module Flipper
37
37
  # Sync all the gate values.
38
38
  remote_get_all.each do |feature_key, remote_gates_hash|
39
39
  feature = Feature.new(feature_key, @local)
40
- local_gates_hash = local_get_all[feature_key] || @local.default_config
40
+ # Check if feature_key is in hash before accessing to prevent unintended hash modification
41
+ local_gates_hash = local_get_all.key?(feature_key) ? local_get_all[feature_key] : @local.default_config
41
42
  local_gate_values = GateValues.new(local_gates_hash)
42
43
  remote_gate_values = GateValues.new(remote_gates_hash)
43
44
  FeatureSynchronizer.new(feature, local_gate_values, remote_gate_values).call
@@ -15,7 +15,7 @@ module Flipper
15
15
  # use Flipper::Middleware::Memoizer
16
16
  #
17
17
  # # using with preload_all features
18
- # use Flipper::Middleware::Memoizer, preload_all: true
18
+ # use Flipper::Middleware::Memoizer, preload: true
19
19
  #
20
20
  # # using with preload specific features
21
21
  # use Flipper::Middleware::Memoizer, preload: [:stats, :search, :some_feature]
@@ -5,7 +5,8 @@ module Flipper
5
5
  env_key: "flipper",
6
6
  memoize: true,
7
7
  preload: true,
8
- instrumenter: ActiveSupport::Notifications
8
+ instrumenter: ActiveSupport::Notifications,
9
+ log: true
9
10
  )
10
11
  end
11
12
 
@@ -17,7 +18,7 @@ module Flipper
17
18
  end
18
19
  end
19
20
 
20
- initializer "flipper.memoizer", after: :load_config_initializers do |app|
21
+ initializer "flipper.memoizer" do |app|
21
22
  config = app.config.flipper
22
23
 
23
24
  if config.memoize
@@ -29,6 +30,13 @@ module Flipper
29
30
  end
30
31
  end
31
32
 
33
+ initializer "flipper.log" do |app|
34
+ config = app.config.flipper
35
+ if config.log && config.instrumenter == ActiveSupport::Notifications
36
+ require "flipper/instrumentation/log_subscriber"
37
+ end
38
+ end
39
+
32
40
  initializer "flipper.identifier" do
33
41
  ActiveSupport.on_load(:active_record) do
34
42
  ActiveRecord::Base.include Flipper::Identifier
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.21.0'.freeze
2
+ VERSION = '0.22.2'.freeze
3
3
  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.21.0
4
+ version: 0.22.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-09 00:00:00.000000000 Z
11
+ date: 2021-10-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -19,6 +19,7 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - ".codeclimate.yml"
21
21
  - ".github/workflows/ci.yml"
22
+ - ".github/workflows/examples.yml"
22
23
  - CODE_OF_CONDUCT.md
23
24
  - Changelog.md
24
25
  - Dockerfile
@@ -37,6 +38,9 @@ files:
37
38
  - docs/http/README.md
38
39
  - docs/images/banner.jpg
39
40
  - docs/read-only/README.md
41
+ - examples/api/basic.ru
42
+ - examples/api/custom_memoized.ru
43
+ - examples/api/memoized.ru
40
44
  - examples/basic.rb
41
45
  - examples/configuring_default.rb
42
46
  - examples/dsl.rb
@@ -47,6 +51,7 @@ files:
47
51
  - examples/importing.rb
48
52
  - examples/individual_actor.rb
49
53
  - examples/instrumentation.rb
54
+ - examples/instrumentation_last_accessed_at.rb
50
55
  - examples/memoizing.rb
51
56
  - examples/percentage_of_actors.rb
52
57
  - examples/percentage_of_actors_enabled_check.rb