flipper 1.1.1 → 1.1.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: a399f5f1ee9a91cdc05d7d47ac2b5a337e1f27ed076dbd39ff7ce952f445d80c
4
- data.tar.gz: 129babef74f77cae24886e92078af369ee31652a3b41e14b5921d55a236e41ec
3
+ metadata.gz: 0045f824274ad425560681d88802488af7e79ec6f67a228f61ec02ab3b90016a
4
+ data.tar.gz: e8b934abcf93152ea294c4ec1071063084888b13640df3f2aaf34b9d6a5c9cbe
5
5
  SHA512:
6
- metadata.gz: 0c5d6b3f364e5f50ff7e7df4642c3a31659be1f56bcb5a313b976fcfc677271536202454c890ef9e6b17be69cdaf750eeb73e02217122b986f23fb77694d4229
7
- data.tar.gz: 0bce7c2195a3759034d3b46666bef74c3c808835a0dc27f8d8ab6cc2f99182f0a2751a9c0dd6d6c0522bd8f40754bfe2f36a001989311d9b62341c8dafcad4ff
6
+ metadata.gz: 831624665d1c63d16bf7f724d82622c4838006a9889c30f674f151cab1633961e32689cbf383de2b83cce16c8ff183037959cc06f5a804aa1ab63a93252992ab
7
+ data.tar.gz: ceb9a261463a6bce77f975317aacb2931d03773926c51186422e8430c0601f428690c4199f50ae1a19892d6f011f404ebe18d30e58c786263cbc2f14728f5727
@@ -13,6 +13,18 @@ jobs:
13
13
  --health-interval 10s
14
14
  --health-timeout 5s
15
15
  --health-retries 5
16
+ postgres:
17
+ image: postgres:13
18
+ ports:
19
+ - 5432:5432
20
+ env:
21
+ POSTGRES_USER: postgres
22
+ POSTGRES_PASSWORD: postgres
23
+ options: >-
24
+ --health-cmd pg_isready
25
+ --health-interval 10s
26
+ --health-timeout 5s
27
+ --health-retries 5
16
28
  strategy:
17
29
  matrix:
18
30
  ruby: ['2.6', '2.7', '3.0', '3.1', '3.2']
@@ -41,7 +53,13 @@ jobs:
41
53
  REDIS_URL: redis://localhost:6379/0
42
54
  CI: true
43
55
  RAILS_VERSION: ${{ matrix.rails }}
56
+ MYSQL_USER: root
57
+ MYSQL_PASSWORD: root
58
+ POSTGRES_USER: postgres
59
+ POSTGRES_PASSWORD: postgres
44
60
  steps:
61
+ - name: Set up MySQL
62
+ run: sudo /etc/init.d/mysql start
45
63
  - name: Setup memcached
46
64
  uses: KeisukeYamashita/memcached-actions@v1
47
65
  - name: Start MongoDB
data/Changelog.md CHANGED
@@ -2,13 +2,25 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## v1.1.1
5
+ ## 1.1.2
6
+
7
+ ### Bug Fixes
8
+
9
+ - Fix ActiveRecord adapter when table doesn't exist (https://github.com/flippercloud/flipper/pull/786).
10
+ - Fix ActiveRecord adapter when using MySQL with expressions (https://github.com/flippercloud/flipper/pull/790)
11
+ - Fix an error where the Rails integration in `Flipper::Engine` was not properly delegating a class method to the instance (https://github.com/flippercloud/flipper/pull/788)
12
+
13
+ ### Additions/Changes
14
+
15
+ - Added `$ rails generate flipper:update` to generate necessary schema migrations (https://github.com/flippercloud/flipper/pull/787)
16
+
17
+ ## 1.1.1
6
18
 
7
19
  ### Bug Fixes
8
20
 
9
21
  - Whoops! Anyone not using flipper-active_record would hit a missing require because of our fancy gemspecs (https://github.com/flippercloud/flipper/pull/785).
10
22
 
11
- ## v1.1.0
23
+ ## 1.1.0
12
24
 
13
25
  ### Additions/Changes
14
26
 
@@ -30,12 +42,9 @@ All notable changes to this project will be documented in this file.
30
42
  ```
31
43
  - Handle deprecation of Rack::File in Rack 3.1 (https://github.com/flippercloud/flipper/pull/773).
32
44
  - Human readable actor names in flipper-ui (https://github.com/flippercloud/flipper/pull/737).
33
- - Expressions are now available and considered "alpha". They are not yet documented, but you can see examples in [examples/expressions.rb](examples/expressions.rb). Those using the `flipper-active_record` adapter will want to migrate the database so it can store JSON expressions (https://github.com/flippercloud/flipper/pull/692)
45
+ - Expressions are now available and considered "alpha". They are not yet documented, but you can see examples in [examples/expressions.rb](examples/expressions.rb). Those using the `flipper-active_record` adapter will want to [migrate the database](See https://github.com/flippercloud/flipper/issues/557) so it can store JSON expressions (https://github.com/flippercloud/flipper/pull/692)
34
46
  ```
35
- $ rails generate migration change_flipper_gates_value_to_text
36
- ```
37
- ```ruby
38
- change_column :flipper_gates, :value, :text
47
+ $ rails generate flipper:update && rails db:migrate
39
48
  ```
40
49
  - Allow head requests to api (https://github.com/flippercloud/flipper/pull/759)
41
50
  - Cloud Telemetry alpha (https://github.com/flippercloud/flipper/pull/775).
data/Gemfile CHANGED
@@ -25,6 +25,8 @@ gem 'benchmark-ips'
25
25
  gem 'stackprof-webnav'
26
26
  gem 'flamegraph'
27
27
  gem 'climate_control'
28
+ gem 'mysql2'
29
+ gem 'pg'
28
30
 
29
31
  group(:guard) do
30
32
  gem 'guard'
data/README.md CHANGED
@@ -4,14 +4,14 @@
4
4
 
5
5
  # Flipper
6
6
 
7
- > Beautiful, performant feature flags for Ruby.
7
+ > Beautiful, performant feature flags for Ruby and Rails.
8
8
 
9
9
  Flipper gives you control over who has access to features in your app.
10
10
 
11
- * Enable or disable features for everyone, specific actors, groups of actors, a percentage of actors, or a percentage of time.
12
- * Configure your feature flags from the console or a web UI.
13
- * Regardless of what data store you are using, Flipper can performantly store your feature flags.
14
- * Use [Flipper Cloud](#flipper-cloud) to cascade features from multiple environments, share settings with your team, control permissions, keep an audit history, and rollback.
11
+ - Enable or disable features for everyone, specific actors, groups of actors, a percentage of actors, or a percentage of time.
12
+ - Configure your feature flags from the console or a web UI.
13
+ - Regardless of what data store you are using, Flipper can performantly store your feature flags.
14
+ - Use [Flipper Cloud](#flipper-cloud) to cascade features from multiple environments, share settings with your team, control permissions, keep an audit history, and rollback.
15
15
 
16
16
  Control your software — don't let it control you.
17
17
 
@@ -72,13 +72,13 @@ Read more about [getting started with Flipper](https://flippercloud.io/docs?utm_
72
72
 
73
73
  Like Flipper and want more? Check out [Flipper Cloud](https://www.flippercloud.io?utm_source=oss&utm_medium=readme&utm_campaign=check_out), which comes with:
74
74
 
75
- * **multiple environments** — production, staging, per continent, whatever you need. Every environment inherits from production by default and every project comes with a [project overview page](https://blog.flippercloud.io/project-overview/) that shows each feature and its status in each environment.
76
- * **personal environments** — everyone on your team gets a personal environment (that inherits from production) which they can modify however they want without stepping on anyone else's toes.
77
- * **permissions** — grant access to everyone in your organization or lockdown each project to particular people. You can even limit access to a particular environment (like production) to specific people.
78
- * **audit history** — every feature change and who made it.
79
- * **rollbacks** — enable or disable a feature accidentally? No problem. You can roll back to any point in the audit history with a single click.
80
- * **maintenance** — we'll keep the lights on for you. We also have handy webhooks and background polling for keeping your app in sync with Cloud, so **our availability won't affect yours**. All your feature flag reads are local to your app.
81
- * **everything in one place** — no need to bounce around from different application UIs or IRB consoles.
75
+ - **multiple environments** — production, staging, per continent, whatever you need. Every environment inherits from production by default and every project comes with a [project overview page](https://blog.flippercloud.io/project-overview/) that shows each feature and its status in each environment.
76
+ - **personal environments** — everyone on your team gets a personal environment (that inherits from production) which they can modify however they want without stepping on anyone else's toes.
77
+ - **permissions** — grant access to everyone in your organization or lockdown each project to particular people. You can even limit access to a particular environment (like production) to specific people.
78
+ - **audit history** — every feature change and who made it.
79
+ - **rollbacks** — enable or disable a feature accidentally? No problem. You can roll back to any point in the audit history with a single click.
80
+ - **maintenance** — we'll keep the lights on for you. We also have handy webhooks and background polling for keeping your app in sync with Cloud, so **our availability won't affect yours**. All your feature flag reads are local to your app.
81
+ - **everything in one place** — no need to bounce around from different application UIs or IRB consoles.
82
82
 
83
83
  [![Flipper Cloud Screenshot](docs/images/flipper_cloud.png)](https://www.flippercloud.io?utm_source=oss&utm_medium=readme&utm_campaign=screenshot)
84
84
 
@@ -103,11 +103,11 @@ We also have a [free plan](https://www.flippercloud.io?utm_source=oss&utm_medium
103
103
 
104
104
  ## Brought To You By
105
105
 
106
- | pic | @mention | area |
107
- |---|---|---|
108
- | ![@jnunemaker](https://avatars3.githubusercontent.com/u/235?s=64) | [@jnunemaker](https://github.com/jnunemaker) | most things |
109
- | ![@bkeepers](https://avatars3.githubusercontent.com/u/173?s=64) | [@bkeepers](https://github.com/bkeepers) | most things |
110
- | ![@dpep](https://avatars3.githubusercontent.com/u/918804?s=64) | [@dpep](https://github.com/dpep) | tbd |
111
- | ![@alexwheeler](https://avatars3.githubusercontent.com/u/3260042?s=64) | [@alexwheeler](https://github.com/alexwheeler) | api |
112
- | ![@thetimbanks](https://avatars1.githubusercontent.com/u/471801?s=64) | [@thetimbanks](https://github.com/thetimbanks) | ui |
113
- | ![@lazebny](https://avatars1.githubusercontent.com/u/6276766?s=64) | [@lazebny](https://github.com/lazebny) | docker |
106
+ | pic | @mention | area |
107
+ | ---------------------------------------------------------------------- | ---------------------------------------------- | ----------- |
108
+ | ![@jnunemaker](https://avatars3.githubusercontent.com/u/235?s=64) | [@jnunemaker](https://github.com/jnunemaker) | most things |
109
+ | ![@bkeepers](https://avatars3.githubusercontent.com/u/173?s=64) | [@bkeepers](https://github.com/bkeepers) | most things |
110
+ | ![@dpep](https://avatars3.githubusercontent.com/u/918804?s=64) | [@dpep](https://github.com/dpep) | tbd |
111
+ | ![@alexwheeler](https://avatars3.githubusercontent.com/u/3260042?s=64) | [@alexwheeler](https://github.com/alexwheeler) | api |
112
+ | ![@thetimbanks](https://avatars1.githubusercontent.com/u/471801?s=64) | [@thetimbanks](https://github.com/thetimbanks) | ui |
113
+ | ![@lazebny](https://avatars1.githubusercontent.com/u/6276766?s=64) | [@lazebny](https://github.com/lazebny) | docker |
data/flipper.gemspec CHANGED
@@ -23,7 +23,7 @@ ignored_test_files.flatten!.uniq!
23
23
  Gem::Specification.new do |gem|
24
24
  gem.authors = ['John Nunemaker']
25
25
  gem.email = 'support@flippercloud.io'
26
- gem.summary = 'Beautiful, performant feature flags for Ruby.'
26
+ gem.summary = 'Beautiful, performant feature flags for Ruby and Rails.'
27
27
  gem.homepage = 'https://www.flippercloud.io/docs'
28
28
  gem.license = 'MIT'
29
29
 
@@ -70,7 +70,7 @@ module Flipper
70
70
  !!ENV["FLIPPER_CLOUD_TOKEN"]
71
71
  end
72
72
 
73
- def default_strict_value
73
+ def self.default_strict_value
74
74
  value = ENV["FLIPPER_STRICT"]
75
75
  if value.in?(["warn", "raise", "noop"])
76
76
  value.to_sym
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.1.2'.freeze
3
3
  end
@@ -0,0 +1,22 @@
1
+ class CreateFlipperTables < ActiveRecord::Migration<%= migration_version %>
2
+ def up
3
+ create_table :flipper_features do |t|
4
+ t.string :key, null: false
5
+ t.timestamps null: false
6
+ end
7
+ add_index :flipper_features, :key, unique: true
8
+
9
+ create_table :flipper_gates do |t|
10
+ t.string :feature_key, null: false
11
+ t.string :key, null: false
12
+ t.string :value
13
+ t.timestamps null: false
14
+ end
15
+ add_index :flipper_gates, [:feature_key, :key, :value], unique: true
16
+ end
17
+
18
+ def down
19
+ drop_table :flipper_gates
20
+ drop_table :flipper_features
21
+ end
22
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ChangeFlipperGatesValueToText < ActiveRecord::Migration<%= migration_version %>
4
+ def up
5
+ # Ensure this incremental update migration is idempotent
6
+ return unless connection.column_exists? :flipper_gates, :value, :string
7
+
8
+ if index_exists? :flipper_gates, [:feature_key, :key, :value]
9
+ remove_index :flipper_gates, [:feature_key, :key, :value]
10
+ end
11
+ change_column :flipper_gates, :value, :text
12
+ add_index :flipper_gates, [:feature_key, :key, :value], unique: true, length: { value: 255 }
13
+ end
14
+
15
+ def down
16
+ change_column :flipper_gates, :value, :string
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/active_record'
5
+
6
+ module Flipper
7
+ module Generators
8
+ #
9
+ # Rails generator used for updating Flipper in a Rails application.
10
+ # Run it with +bin/rails g flipper:update+ in your console.
11
+ #
12
+ class UpdateGenerator < Rails::Generators::Base
13
+ include ActiveRecord::Generators::Migration
14
+
15
+ TEMPLATES = File.join(File.dirname(__FILE__), 'templates/update')
16
+ source_paths << TEMPLATES
17
+
18
+ # Generates incremental migration files unless they already exist.
19
+ # All migrations should be idempotent e.g. +add_index+ is guarded with +if_index_exists?+
20
+ def update_migration_files
21
+ migration_templates = Dir.children(File.join(TEMPLATES, 'migrations')).sort
22
+ migration_templates.each do |template_file|
23
+ destination_file = template_file.match(/^\d*_(.*\.rb)/)[1] # 01_create_flipper_tables.rb.erb => create_flipper_tables.rb
24
+ migration_template "migrations/#{template_file}", File.join(db_migrate_path, destination_file), skip: true
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def migration_version
31
+ "[#{ActiveRecord::VERSION::STRING.to_f}]"
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,96 @@
1
+ require "helper"
2
+ require "generators/flipper/update_generator"
3
+
4
+ class UpdateGeneratorTest < Rails::Generators::TestCase
5
+ tests Flipper::Generators::UpdateGenerator
6
+ ROOT = File.expand_path("../../../../tmp/generators", __FILE__)
7
+ destination ROOT
8
+ setup :prepare_destination
9
+
10
+ setup do
11
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
12
+ end
13
+
14
+ teardown do
15
+ ActiveRecord::Base.connection.close
16
+ end
17
+
18
+ test "generates migrations" do
19
+ run_generator
20
+
21
+ assert_migration "db/migrate/create_flipper_tables.rb" do |migration|
22
+ assert_method :up, migration do |up|
23
+ assert_match(/create_table :flipper_features/, up)
24
+ assert_match(/create_table :flipper_gates/, up)
25
+ end
26
+
27
+ assert_method :down, migration do |down|
28
+ assert_match(/drop_table :flipper_features/, down)
29
+ assert_match(/drop_table :flipper_gates/, down)
30
+ end
31
+ end
32
+
33
+ assert_migration "db/migrate/change_flipper_gates_value_to_text.rb" do |migration|
34
+ [:up, :down].each do |dir|
35
+ assert_method :up, migration do |method|
36
+ assert_match(/change_column/, method)
37
+ end
38
+ end
39
+ end
40
+
41
+ require_migrations
42
+
43
+ silence { CreateFlipperTables.migrate(:up) }
44
+ assert ActiveRecord::Base.connection.table_exists?(:flipper_features)
45
+ assert ActiveRecord::Base.connection.table_exists?(:flipper_gates)
46
+
47
+ assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :string)
48
+ silence { ChangeFlipperGatesValueToText.migrate(:up) }
49
+ assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :text)
50
+
51
+ silence { ChangeFlipperGatesValueToText.migrate(:down) }
52
+ assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :string)
53
+
54
+ silence { CreateFlipperTables.migrate(:down) }
55
+ refute ActiveRecord::Base.connection.table_exists?(:flipper_features)
56
+ refute ActiveRecord::Base.connection.table_exists?(:flipper_gates)
57
+ end
58
+
59
+ test "ChangeFlipperGatesValueToText is a noop if value is already text" do
60
+ self.class.generator_class = Flipper::Generators::ActiveRecordGenerator
61
+ run_generator
62
+
63
+ self.class.generator_class = Flipper::Generators::UpdateGenerator
64
+ run_generator
65
+
66
+ assert_migration "db/migrate/create_flipper_tables.rb" do |migration|
67
+ assert_method :up, migration do |up|
68
+ assert_match /text :value/, up
69
+ end
70
+ end
71
+
72
+ assert_migration "db/migrate/change_flipper_gates_value_to_text.rb"
73
+
74
+ require_migrations
75
+
76
+ silence { CreateFlipperTables.migrate(:up) }
77
+ assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :text)
78
+
79
+ assert_nothing_raised do
80
+ silence { ChangeFlipperGatesValueToText.migrate(:up) }
81
+ end
82
+ assert ActiveRecord::Base.connection.column_exists?(:flipper_gates, :value, :text)
83
+ end
84
+
85
+ def require_migrations
86
+ # If these are not reloaded, then test order can cause failures
87
+ Object.send(:remove_const, :CreateFlipperTables) if defined?(::CreateFlipperTables)
88
+ Object.send(:remove_const, :ChangeFlipperGatesValueToText) if defined?(::ChangeFlipperGatesValueToText)
89
+
90
+ Dir.glob("#{ROOT}/db/migrate/*.rb").each do |file|
91
+ assert_nothing_raised do
92
+ load file
93
+ end
94
+ end
95
+ end
96
+ end
data/test_rails/helper.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
- require 'bundler'
3
- Bundler.setup(:default)
2
+ require 'bundler/setup'
3
+ require 'minitest/autorun'
4
4
  require 'rails'
5
5
  require 'rails/test_help'
6
6
 
@@ -9,3 +9,20 @@ begin
9
9
  rescue NoMethodError
10
10
  # no biggie, means we are on older version of AS that doesn't have this option
11
11
  end
12
+
13
+ def silence
14
+ # Store the original stderr and stdout in order to restore them later
15
+ original_stderr = $stderr
16
+ original_stdout = $stdout
17
+
18
+ # Redirect stderr and stdout
19
+ output = $stderr = $stdout = StringIO.new
20
+
21
+ yield
22
+
23
+ $stderr = original_stderr
24
+ $stdout = original_stdout
25
+
26
+ # Return output
27
+ output.string
28
+ 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: 1.1.1
4
+ version: 1.1.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: 2023-12-09 00:00:00.000000000 Z
11
+ date: 2023-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -185,6 +185,9 @@ files:
185
185
  - lib/flipper/types/percentage_of_actors.rb
186
186
  - lib/flipper/types/percentage_of_time.rb
187
187
  - lib/flipper/version.rb
188
+ - lib/generators/flipper/templates/update/migrations/01_create_flipper_tables.rb.erb
189
+ - lib/generators/flipper/templates/update/migrations/02_change_flipper_gates_value_to_text.rb.erb
190
+ - lib/generators/flipper/update_generator.rb
188
191
  - spec/fixtures/feature.json
189
192
  - spec/fixtures/flipper_pstore_1679087600.json
190
193
  - spec/flipper/actor_spec.rb
@@ -284,6 +287,7 @@ files:
284
287
  - test/adapters/memory_test.rb
285
288
  - test/adapters/pstore_test.rb
286
289
  - test/test_helper.rb
290
+ - test_rails/generators/flipper/update_generator_test.rb
287
291
  - test_rails/helper.rb
288
292
  homepage: https://www.flippercloud.io/docs
289
293
  licenses:
@@ -312,7 +316,7 @@ requirements: []
312
316
  rubygems_version: 3.4.10
313
317
  signing_key:
314
318
  specification_version: 4
315
- summary: Beautiful, performant feature flags for Ruby.
319
+ summary: Beautiful, performant feature flags for Ruby and Rails.
316
320
  test_files:
317
321
  - spec/fixtures/feature.json
318
322
  - spec/fixtures/flipper_pstore_1679087600.json