flipper 0.28.3 → 1.4.2
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/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +56 -10
- data/.github/workflows/examples.yml +54 -11
- data/.github/workflows/release.yml +54 -0
- data/.superset/config.json +4 -0
- data/CLAUDE.md +93 -0
- data/Changelog.md +1 -559
- data/Gemfile +17 -8
- data/README.md +34 -29
- data/Rakefile +2 -2
- data/benchmark/typecast_ips.rb +8 -0
- data/docs/images/banner.jpg +0 -0
- data/docs/images/flipper_cloud.png +0 -0
- data/examples/cloud/app.ru +12 -0
- data/examples/cloud/backoff_policy.rb +13 -0
- data/examples/cloud/basic.rb +22 -0
- data/examples/cloud/cloud_setup.rb +20 -0
- data/examples/cloud/forked.rb +36 -0
- data/examples/cloud/import.rb +17 -0
- data/examples/cloud/poll_interval/README.md +111 -0
- data/examples/cloud/poll_interval/client.rb +108 -0
- data/examples/cloud/poll_interval/server.rb +98 -0
- data/examples/cloud/threaded.rb +33 -0
- data/examples/dsl.rb +0 -14
- data/examples/expressions.rb +237 -0
- data/examples/strict.rb +18 -0
- data/exe/flipper +5 -0
- data/flipper-cloud.gemspec +19 -0
- data/flipper.gemspec +8 -4
- data/lib/flipper/actor.rb +6 -3
- data/lib/flipper/adapter.rb +27 -1
- data/lib/flipper/adapter_builder.rb +44 -0
- data/lib/flipper/adapters/actor_limit.rb +54 -0
- data/lib/flipper/adapters/cache_base.rb +161 -0
- data/lib/flipper/adapters/dual_write.rb +7 -5
- data/lib/flipper/adapters/failover.rb +9 -7
- data/lib/flipper/adapters/failsafe.rb +2 -6
- data/lib/flipper/adapters/http/client.rb +53 -14
- data/lib/flipper/adapters/http/error.rb +2 -2
- data/lib/flipper/adapters/http.rb +56 -16
- data/lib/flipper/adapters/instrumented.rb +2 -6
- data/lib/flipper/adapters/memoizable.rb +17 -22
- data/lib/flipper/adapters/memory.rb +5 -7
- data/lib/flipper/adapters/operation_logger.rb +18 -92
- data/lib/flipper/adapters/poll.rb +16 -3
- data/lib/flipper/adapters/pstore.rb +18 -12
- data/lib/flipper/adapters/read_only.rb +8 -41
- data/lib/flipper/adapters/strict.rb +75 -0
- data/lib/flipper/adapters/sync/feature_synchronizer.rb +14 -1
- data/lib/flipper/adapters/sync/synchronizer.rb +13 -5
- data/lib/flipper/adapters/sync.rb +7 -7
- data/lib/flipper/adapters/wrapper.rb +54 -0
- data/lib/flipper/cli.rb +314 -0
- data/lib/flipper/cloud/configuration.rb +267 -0
- data/lib/flipper/cloud/dsl.rb +27 -0
- data/lib/flipper/cloud/message_verifier.rb +95 -0
- data/lib/flipper/cloud/middleware.rb +63 -0
- data/lib/flipper/cloud/migrate.rb +71 -0
- data/lib/flipper/cloud/routes.rb +14 -0
- data/lib/flipper/cloud/telemetry/backoff_policy.rb +96 -0
- data/lib/flipper/cloud/telemetry/instrumenter.rb +22 -0
- data/lib/flipper/cloud/telemetry/metric.rb +39 -0
- data/lib/flipper/cloud/telemetry/metric_storage.rb +30 -0
- data/lib/flipper/cloud/telemetry/submitter.rb +100 -0
- data/lib/flipper/cloud/telemetry.rb +191 -0
- data/lib/flipper/cloud.rb +54 -0
- data/lib/flipper/configuration.rb +25 -4
- data/lib/flipper/dsl.rb +48 -43
- data/lib/flipper/engine.rb +102 -0
- data/lib/flipper/export.rb +0 -2
- data/lib/flipper/exporters/json/export.rb +1 -1
- data/lib/flipper/exporters/json/v1.rb +1 -1
- data/lib/flipper/expression/builder.rb +73 -0
- data/lib/flipper/expression/constant.rb +25 -0
- data/lib/flipper/expression.rb +71 -0
- data/lib/flipper/expressions/all.rb +9 -0
- data/lib/flipper/expressions/any.rb +9 -0
- data/lib/flipper/expressions/boolean.rb +9 -0
- data/lib/flipper/expressions/comparable.rb +13 -0
- data/lib/flipper/expressions/equal.rb +9 -0
- data/lib/flipper/expressions/feature_enabled.rb +34 -0
- data/lib/flipper/expressions/greater_than.rb +9 -0
- data/lib/flipper/expressions/greater_than_or_equal_to.rb +9 -0
- data/lib/flipper/expressions/less_than.rb +9 -0
- data/lib/flipper/expressions/less_than_or_equal_to.rb +9 -0
- data/lib/flipper/expressions/not_equal.rb +9 -0
- data/lib/flipper/expressions/now.rb +9 -0
- data/lib/flipper/expressions/number.rb +9 -0
- data/lib/flipper/expressions/percentage.rb +9 -0
- data/lib/flipper/expressions/percentage_of_actors.rb +12 -0
- data/lib/flipper/expressions/property.rb +9 -0
- data/lib/flipper/expressions/random.rb +9 -0
- data/lib/flipper/expressions/string.rb +9 -0
- data/lib/flipper/expressions/time.rb +16 -0
- data/lib/flipper/feature.rb +63 -1
- data/lib/flipper/gate.rb +2 -1
- data/lib/flipper/gate_values.rb +5 -2
- data/lib/flipper/gates/expression.rb +75 -0
- data/lib/flipper/instrumentation/log_subscriber.rb +13 -5
- data/lib/flipper/instrumentation/statsd.rb +4 -2
- data/lib/flipper/instrumentation/statsd_subscriber.rb +2 -4
- data/lib/flipper/instrumentation/subscriber.rb +0 -4
- data/lib/flipper/metadata.rb +8 -1
- data/lib/flipper/middleware/memoizer.rb +30 -14
- data/lib/flipper/model/active_record.rb +23 -0
- data/lib/flipper/poller.rb +54 -12
- data/lib/flipper/serializers/gzip.rb +22 -0
- data/lib/flipper/serializers/json.rb +17 -0
- data/lib/flipper/spec/shared_adapter_specs.rb +82 -63
- data/lib/flipper/test/shared_adapter_test.rb +77 -58
- data/lib/flipper/test_help.rb +43 -0
- data/lib/flipper/typecast.rb +37 -9
- data/lib/flipper/types/percentage.rb +1 -1
- data/lib/flipper/version.rb +11 -1
- data/lib/flipper.rb +61 -8
- data/lib/generators/flipper/setup_generator.rb +68 -0
- data/lib/generators/flipper/templates/initializer.rb +45 -0
- data/lib/generators/flipper/templates/update/migrations/01_create_flipper_tables.rb.erb +22 -0
- data/lib/generators/flipper/templates/update/migrations/02_change_flipper_gates_value_to_text.rb.erb +18 -0
- data/lib/generators/flipper/update_generator.rb +35 -0
- data/package-lock.json +41 -0
- data/package.json +10 -0
- data/spec/fixtures/environment.rb +1 -0
- data/spec/flipper/adapter_builder_spec.rb +72 -0
- data/spec/flipper/adapter_spec.rb +21 -0
- data/spec/flipper/adapters/actor_limit_spec.rb +75 -0
- data/spec/flipper/adapters/dual_write_spec.rb +15 -2
- data/spec/flipper/adapters/failover_spec.rb +12 -0
- data/spec/flipper/adapters/http/client_spec.rb +61 -0
- data/spec/flipper/adapters/http_spec.rb +375 -74
- data/spec/flipper/adapters/instrumented_spec.rb +1 -1
- data/spec/flipper/adapters/memoizable_spec.rb +21 -21
- data/spec/flipper/adapters/operation_logger_spec.rb +2 -2
- data/spec/flipper/adapters/poll_spec.rb +41 -0
- data/spec/flipper/adapters/read_only_spec.rb +32 -17
- data/spec/flipper/adapters/strict_spec.rb +122 -0
- data/spec/flipper/adapters/sync/feature_synchronizer_spec.rb +39 -0
- data/spec/flipper/adapters/sync/synchronizer_spec.rb +87 -0
- data/spec/flipper/adapters/sync_spec.rb +13 -0
- data/spec/flipper/cli_spec.rb +217 -0
- data/spec/flipper/cloud/configuration_spec.rb +251 -0
- data/spec/flipper/cloud/dsl_spec.rb +82 -0
- data/spec/flipper/cloud/message_verifier_spec.rb +104 -0
- data/spec/flipper/cloud/middleware_spec.rb +289 -0
- data/spec/flipper/cloud/migrate_spec.rb +160 -0
- data/spec/flipper/cloud/telemetry/backoff_policy_spec.rb +107 -0
- data/spec/flipper/cloud/telemetry/metric_spec.rb +87 -0
- data/spec/flipper/cloud/telemetry/metric_storage_spec.rb +58 -0
- data/spec/flipper/cloud/telemetry/submitter_spec.rb +145 -0
- data/spec/flipper/cloud/telemetry_spec.rb +208 -0
- data/spec/flipper/cloud_spec.rb +186 -0
- data/spec/flipper/configuration_spec.rb +17 -0
- data/spec/flipper/dsl_spec.rb +34 -73
- data/spec/flipper/engine_spec.rb +374 -0
- data/spec/flipper/exporters/json/v1_spec.rb +3 -3
- data/spec/flipper/expression/builder_spec.rb +248 -0
- data/spec/flipper/expression_spec.rb +188 -0
- data/spec/flipper/expressions/all_spec.rb +15 -0
- data/spec/flipper/expressions/any_spec.rb +15 -0
- data/spec/flipper/expressions/boolean_spec.rb +15 -0
- data/spec/flipper/expressions/equal_spec.rb +24 -0
- data/spec/flipper/expressions/greater_than_or_equal_to_spec.rb +28 -0
- data/spec/flipper/expressions/greater_than_spec.rb +28 -0
- data/spec/flipper/expressions/less_than_or_equal_to_spec.rb +28 -0
- data/spec/flipper/expressions/less_than_spec.rb +32 -0
- data/spec/flipper/expressions/not_equal_spec.rb +15 -0
- data/spec/flipper/expressions/now_spec.rb +11 -0
- data/spec/flipper/expressions/number_spec.rb +21 -0
- data/spec/flipper/expressions/percentage_of_actors_spec.rb +20 -0
- data/spec/flipper/expressions/percentage_spec.rb +15 -0
- data/spec/flipper/expressions/property_spec.rb +13 -0
- data/spec/flipper/expressions/random_spec.rb +9 -0
- data/spec/flipper/expressions/string_spec.rb +11 -0
- data/spec/flipper/expressions/time_spec.rb +29 -0
- data/spec/flipper/feature_spec.rb +380 -10
- data/spec/flipper/gate_values_spec.rb +2 -2
- data/spec/flipper/gates/expression_spec.rb +190 -0
- data/spec/flipper/identifier_spec.rb +4 -5
- data/spec/flipper/instrumentation/log_subscriber_spec.rb +10 -2
- data/spec/flipper/instrumentation/statsd_subscriber_spec.rb +16 -2
- data/spec/flipper/middleware/memoizer_spec.rb +107 -7
- data/spec/flipper/model/active_record_spec.rb +72 -0
- data/spec/flipper/poller_spec.rb +347 -4
- data/spec/flipper/serializers/gzip_spec.rb +13 -0
- data/spec/flipper/serializers/json_spec.rb +13 -0
- data/spec/flipper/typecast_spec.rb +43 -7
- data/spec/flipper/types/actor_spec.rb +18 -1
- data/spec/flipper_integration_spec.rb +247 -16
- data/spec/flipper_spec.rb +92 -29
- data/spec/spec_helper.rb +24 -17
- data/spec/support/actor_names.yml +1 -0
- data/spec/support/fail_on_output.rb +8 -0
- data/spec/support/fake_backoff_policy.rb +15 -0
- data/spec/support/spec_helpers.rb +34 -8
- data/test/adapters/actor_limit_test.rb +20 -0
- data/test_rails/generators/flipper/setup_generator_test.rb +69 -0
- data/test_rails/generators/flipper/update_generator_test.rb +96 -0
- data/test_rails/helper.rb +22 -2
- data/test_rails/system/test_help_test.rb +52 -0
- metadata +139 -75
- data/.tool-versions +0 -1
- data/lib/flipper/railtie.rb +0 -47
- data/spec/flipper/railtie_spec.rb +0 -109
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c886665703939f49361ef42fb82e951383cb53bd99f2b1d902add786f6793da0
|
|
4
|
+
data.tar.gz: b7af2d5972cc409f075390871dc96b225e495133917e0c5024db297760252e73
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 338ccb2e6d9ddeaa6f6a1f20755e7799dcda40341c22831f8eda1f25df5f08bf4c61d67333e9bdebf94172107842b07e7ddb3ec7a54a2d057663f109e78f5a5d
|
|
7
|
+
data.tar.gz: bbfdb72c366e7fa334d8c3903b799366bed22d755cf6771c532d1335cccf7e9480c8a752c700a449f1ae837ae273be5b9c06ef58bc38b56570d96ef417edbded
|
data/.github/FUNDING.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
github: flippercloud
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -1,53 +1,99 @@
|
|
|
1
1
|
name: CI
|
|
2
|
-
on: [push
|
|
2
|
+
on: [push]
|
|
3
|
+
|
|
3
4
|
jobs:
|
|
4
5
|
test:
|
|
5
6
|
name: Test on ruby ${{ matrix.ruby }} and rails ${{ matrix.rails }}
|
|
6
7
|
runs-on: ubuntu-latest
|
|
8
|
+
timeout-minutes: 20
|
|
7
9
|
services:
|
|
8
10
|
redis:
|
|
9
11
|
image: redis
|
|
10
|
-
ports: [
|
|
12
|
+
ports: ["6379:6379"]
|
|
11
13
|
options: >-
|
|
12
14
|
--health-cmd "redis-cli ping"
|
|
13
15
|
--health-interval 10s
|
|
14
16
|
--health-timeout 5s
|
|
15
17
|
--health-retries 5
|
|
18
|
+
memcached:
|
|
19
|
+
image: memcached
|
|
20
|
+
ports: ["11211:11211"]
|
|
21
|
+
postgres:
|
|
22
|
+
image: postgres:13
|
|
23
|
+
ports:
|
|
24
|
+
- 5432:5432
|
|
25
|
+
env:
|
|
26
|
+
POSTGRES_USER: postgres
|
|
27
|
+
POSTGRES_PASSWORD: postgres
|
|
28
|
+
options: >-
|
|
29
|
+
--health-cmd pg_isready
|
|
30
|
+
--health-interval 10s
|
|
31
|
+
--health-timeout 5s
|
|
32
|
+
--health-retries 5
|
|
16
33
|
strategy:
|
|
34
|
+
fail-fast: false
|
|
17
35
|
matrix:
|
|
18
|
-
ruby: [
|
|
19
|
-
rails: [
|
|
36
|
+
ruby: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3"]
|
|
37
|
+
rails: ["5.2", "6.0.0", "6.1.0", "7.0.0", "7.1.0", "7.2.0", "8.0.0"]
|
|
20
38
|
exclude:
|
|
39
|
+
- ruby: "2.6"
|
|
40
|
+
rails: "7.1.0"
|
|
21
41
|
- ruby: "2.6"
|
|
22
42
|
rails: "7.0.0"
|
|
43
|
+
- ruby: "2.6"
|
|
44
|
+
rails: "7.2.0"
|
|
45
|
+
- ruby: "2.6"
|
|
46
|
+
rails: "8.0.0"
|
|
47
|
+
- ruby: "2.7"
|
|
48
|
+
rails: "7.1.0"
|
|
49
|
+
- ruby: "2.7"
|
|
50
|
+
rails: "7.2.0"
|
|
51
|
+
- ruby: "2.7"
|
|
52
|
+
rails: "8.0.0"
|
|
23
53
|
- ruby: "3.0"
|
|
24
54
|
rails: "5.2"
|
|
55
|
+
- ruby: "3.0"
|
|
56
|
+
rails: "7.2.0"
|
|
57
|
+
- ruby: "3.0"
|
|
58
|
+
rails: "8.0.0"
|
|
25
59
|
- ruby: "3.1"
|
|
26
60
|
rails: "5.2"
|
|
27
61
|
- ruby: "3.1"
|
|
28
62
|
rails: "6.0.0"
|
|
63
|
+
- ruby: "3.1"
|
|
64
|
+
rails: "8.0.0"
|
|
29
65
|
- ruby: "3.2"
|
|
30
66
|
rails: "5.2"
|
|
31
67
|
- ruby: "3.2"
|
|
32
68
|
rails: "6.0.0"
|
|
33
69
|
- ruby: "3.2"
|
|
34
70
|
rails: "6.1.0"
|
|
71
|
+
- ruby: "3.3"
|
|
72
|
+
rails: "5.2"
|
|
73
|
+
- ruby: "3.3"
|
|
74
|
+
rails: "6.0.0"
|
|
75
|
+
- ruby: "3.3"
|
|
76
|
+
rails: "6.1.0"
|
|
35
77
|
env:
|
|
36
|
-
SQLITE3_VERSION: 1.4.1
|
|
78
|
+
SQLITE3_VERSION: ${{ matrix.rails == '8.0.0' && '2.1.0' || '1.4.1' }}
|
|
37
79
|
REDIS_URL: redis://localhost:6379/0
|
|
38
80
|
CI: true
|
|
39
81
|
RAILS_VERSION: ${{ matrix.rails }}
|
|
82
|
+
MYSQL_USER: root
|
|
83
|
+
MYSQL_PASSWORD: root
|
|
84
|
+
POSTGRES_USER: postgres
|
|
85
|
+
POSTGRES_PASSWORD: postgres
|
|
40
86
|
steps:
|
|
41
|
-
- name:
|
|
42
|
-
|
|
87
|
+
- name: Set up MySQL
|
|
88
|
+
run: sudo /etc/init.d/mysql start
|
|
43
89
|
- name: Start MongoDB
|
|
44
|
-
uses: supercharge/mongodb-github-action@1.
|
|
90
|
+
uses: supercharge/mongodb-github-action@1.12.1
|
|
45
91
|
with:
|
|
46
92
|
mongodb-version: 4.0
|
|
47
93
|
- name: Check out repository code
|
|
48
|
-
uses: actions/checkout@
|
|
94
|
+
uses: actions/checkout@v6
|
|
49
95
|
- name: Do some action caching
|
|
50
|
-
uses: actions/cache@
|
|
96
|
+
uses: actions/cache@v5
|
|
51
97
|
with:
|
|
52
98
|
path: vendor/bundle
|
|
53
99
|
key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-${{ hashFiles('**/Gemfile.lock') }}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
name: Examples
|
|
2
|
-
on: [push
|
|
2
|
+
on: [push]
|
|
3
3
|
jobs:
|
|
4
4
|
test:
|
|
5
|
-
if: github.repository_owner == '
|
|
6
|
-
name:
|
|
5
|
+
if: github.repository_owner == 'flippercloud'
|
|
6
|
+
name: Example on ruby ${{ matrix.ruby }} and rails ${{ matrix.rails }}
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
|
+
timeout-minutes: 20
|
|
8
9
|
services:
|
|
9
10
|
redis:
|
|
10
11
|
image: redis
|
|
11
|
-
ports: [
|
|
12
|
+
ports: ["6379:6379"]
|
|
12
13
|
options: >-
|
|
13
14
|
--health-cmd "redis-cli ping"
|
|
14
15
|
--health-interval 10s
|
|
@@ -16,20 +17,49 @@ jobs:
|
|
|
16
17
|
--health-retries 5
|
|
17
18
|
strategy:
|
|
18
19
|
matrix:
|
|
19
|
-
ruby: [
|
|
20
|
-
rails: [
|
|
20
|
+
ruby: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3"]
|
|
21
|
+
rails: ["5.2", "6.0.0", "6.1.0", "7.0.0", "7.1.0", "7.2.0", "8.0.0"]
|
|
21
22
|
exclude:
|
|
23
|
+
- ruby: "2.6"
|
|
24
|
+
rails: "7.1.0"
|
|
22
25
|
- ruby: "2.6"
|
|
23
26
|
rails: "7.0.0"
|
|
27
|
+
- ruby: "2.6"
|
|
28
|
+
rails: "7.2.0"
|
|
29
|
+
- ruby: "2.6"
|
|
30
|
+
rails: "8.0.0"
|
|
31
|
+
- ruby: "2.7"
|
|
32
|
+
rails: "7.1.0"
|
|
33
|
+
- ruby: "2.7"
|
|
34
|
+
rails: "7.2.0"
|
|
35
|
+
- ruby: "2.7"
|
|
36
|
+
rails: "8.0.0"
|
|
24
37
|
- ruby: "3.0"
|
|
25
38
|
rails: "5.2"
|
|
39
|
+
- ruby: "3.0"
|
|
40
|
+
rails: "7.2.0"
|
|
41
|
+
- ruby: "3.0"
|
|
42
|
+
rails: "8.0.0"
|
|
26
43
|
- ruby: "3.1"
|
|
27
44
|
rails: "5.2"
|
|
28
45
|
- ruby: "3.1"
|
|
29
46
|
rails: "6.0.0"
|
|
30
|
-
|
|
47
|
+
- ruby: "3.1"
|
|
48
|
+
rails: "8.0.0"
|
|
49
|
+
- ruby: "3.2"
|
|
50
|
+
rails: "5.2"
|
|
51
|
+
- ruby: "3.2"
|
|
52
|
+
rails: "6.0.0"
|
|
53
|
+
- ruby: "3.2"
|
|
54
|
+
rails: "6.1.0"
|
|
55
|
+
- ruby: "3.3"
|
|
56
|
+
rails: "5.2"
|
|
57
|
+
- ruby: "3.3"
|
|
58
|
+
rails: "6.0.0"
|
|
59
|
+
- ruby: "3.3"
|
|
60
|
+
rails: "6.1.0"
|
|
31
61
|
env:
|
|
32
|
-
SQLITE3_VERSION: 1.4.1
|
|
62
|
+
SQLITE3_VERSION: ${{ matrix.rails == '8.0.0' && '2.1.0' || '1.4.1' }}
|
|
33
63
|
REDIS_URL: redis://localhost:6379/0
|
|
34
64
|
CI: true
|
|
35
65
|
RAILS_VERSION: ${{ matrix.rails }}
|
|
@@ -37,13 +67,13 @@ jobs:
|
|
|
37
67
|
- name: Setup memcached
|
|
38
68
|
uses: KeisukeYamashita/memcached-actions@v1
|
|
39
69
|
- name: Start MongoDB
|
|
40
|
-
uses: supercharge/mongodb-github-action@1.
|
|
70
|
+
uses: supercharge/mongodb-github-action@1.12.1
|
|
41
71
|
with:
|
|
42
72
|
mongodb-version: 4.0
|
|
43
73
|
- name: Check out repository code
|
|
44
|
-
uses: actions/checkout@
|
|
74
|
+
uses: actions/checkout@v6
|
|
45
75
|
- name: Do some action caching
|
|
46
|
-
uses: actions/cache@
|
|
76
|
+
uses: actions/cache@v5
|
|
47
77
|
with:
|
|
48
78
|
path: vendor/bundle
|
|
49
79
|
key: ${{ runner.os }}-gems-${{ matrix.ruby }}-${{ matrix.rails }}-${{ hashFiles('**/Gemfile.lock') }}
|
|
@@ -59,4 +89,17 @@ jobs:
|
|
|
59
89
|
- name: Run Examples with Rails ${{ matrix.rails }}
|
|
60
90
|
env:
|
|
61
91
|
FLIPPER_CLOUD_TOKEN: ${{ secrets.FLIPPER_CLOUD_TOKEN }}
|
|
92
|
+
FLIPPER_CLOUD_TOKEN_26_52: ${{ secrets.FLIPPER_CLOUD_TOKEN_26_52 }}
|
|
93
|
+
FLIPPER_CLOUD_TOKEN_26_60: ${{ secrets.FLIPPER_CLOUD_TOKEN_26_60 }}
|
|
94
|
+
FLIPPER_CLOUD_TOKEN_26_61: ${{ secrets.FLIPPER_CLOUD_TOKEN_26_61 }}
|
|
95
|
+
FLIPPER_CLOUD_TOKEN_27_52: ${{ secrets.FLIPPER_CLOUD_TOKEN_27_52 }}
|
|
96
|
+
FLIPPER_CLOUD_TOKEN_27_60: ${{ secrets.FLIPPER_CLOUD_TOKEN_27_60 }}
|
|
97
|
+
FLIPPER_CLOUD_TOKEN_27_61: ${{ secrets.FLIPPER_CLOUD_TOKEN_27_61 }}
|
|
98
|
+
FLIPPER_CLOUD_TOKEN_27_70: ${{ secrets.FLIPPER_CLOUD_TOKEN_27_70 }}
|
|
99
|
+
FLIPPER_CLOUD_TOKEN_30_60: ${{ secrets.FLIPPER_CLOUD_TOKEN_30_60 }}
|
|
100
|
+
FLIPPER_CLOUD_TOKEN_30_61: ${{ secrets.FLIPPER_CLOUD_TOKEN_30_61 }}
|
|
101
|
+
FLIPPER_CLOUD_TOKEN_30_70: ${{ secrets.FLIPPER_CLOUD_TOKEN_30_70 }}
|
|
102
|
+
FLIPPER_CLOUD_TOKEN_31_61: ${{ secrets.FLIPPER_CLOUD_TOKEN_31_61 }}
|
|
103
|
+
FLIPPER_CLOUD_TOKEN_31_70: ${{ secrets.FLIPPER_CLOUD_TOKEN_31_70 }}
|
|
104
|
+
RAILS_VERSION: ${{ matrix.rails }}
|
|
62
105
|
run: script/examples
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write # RubyGems trusted publishing (OIDC)
|
|
13
|
+
contents: write # Create GitHub Releases
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v6
|
|
16
|
+
|
|
17
|
+
- uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: '3.3'
|
|
20
|
+
|
|
21
|
+
- name: Build all gems
|
|
22
|
+
run: |
|
|
23
|
+
for gemspec in *.gemspec; do
|
|
24
|
+
gem build "$gemspec"
|
|
25
|
+
done
|
|
26
|
+
mkdir -p pkg
|
|
27
|
+
mv *.gem pkg/
|
|
28
|
+
echo "Built gems:"
|
|
29
|
+
ls -la pkg/
|
|
30
|
+
|
|
31
|
+
- name: Configure RubyGems credentials
|
|
32
|
+
uses: rubygems/configure-rubygems-credentials@v1.0.0
|
|
33
|
+
|
|
34
|
+
- name: Publish all gems
|
|
35
|
+
run: |
|
|
36
|
+
# Push core gem first since other gems depend on it
|
|
37
|
+
echo "Pushing flipper core gem..."
|
|
38
|
+
gem push pkg/flipper-[0-9]*.gem || echo "Core gem already pushed, continuing..."
|
|
39
|
+
|
|
40
|
+
for gem_file in pkg/flipper-*.gem; do
|
|
41
|
+
basename="$(basename "$gem_file")"
|
|
42
|
+
if [[ "$basename" =~ ^flipper-[0-9] ]]; then
|
|
43
|
+
continue
|
|
44
|
+
fi
|
|
45
|
+
echo "Pushing $basename..."
|
|
46
|
+
gem push "$gem_file" || echo "Failed to push $basename, continuing..."
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
- name: Create draft GitHub Release
|
|
50
|
+
uses: softprops/action-gh-release@v2
|
|
51
|
+
with:
|
|
52
|
+
draft: true
|
|
53
|
+
generate_release_notes: true
|
|
54
|
+
files: pkg/*.gem
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Development Commands
|
|
6
|
+
|
|
7
|
+
### Testing
|
|
8
|
+
- `bundle exec rake` - Run all tests (RSpec, Minitest, and Rails tests)
|
|
9
|
+
- `bundle exec rspec` - Run RSpec tests only
|
|
10
|
+
- `bundle exec rake spec:ui` - Run UI-specific specs
|
|
11
|
+
- `bundle exec rake test` - Run Minitest tests only
|
|
12
|
+
- `bundle exec rake test_rails` - Run Rails generator tests
|
|
13
|
+
- `script/test` - Bootstrap and run tests across multiple Rails versions (5.0-8.0)
|
|
14
|
+
|
|
15
|
+
### Development Setup
|
|
16
|
+
- `script/bootstrap` - Bundle install dependencies and setup binstubs
|
|
17
|
+
- `script/console` - Start interactive console with Flipper loaded (uses Pry)
|
|
18
|
+
- `script/server` - Start local UI server on port 9999 for testing web interface
|
|
19
|
+
|
|
20
|
+
### Releasing
|
|
21
|
+
1. Bump version in `lib/flipper/version.rb`, commit, and push to main
|
|
22
|
+
2. Tag and push: `git tag v1.x.x && git push origin v1.x.x`
|
|
23
|
+
3. GitHub Actions (`.github/workflows/release.yml`) builds and publishes all 12 gems via RubyGems trusted publishing, then creates a draft GitHub Release
|
|
24
|
+
4. Edit and publish the draft release at https://github.com/flippercloud/flipper/releases
|
|
25
|
+
|
|
26
|
+
- `bundle exec rake build` - Build all gems locally into pkg/ directory
|
|
27
|
+
- `script/release` - Manual fallback for local releases (prompts for OTP)
|
|
28
|
+
|
|
29
|
+
**After releasing**, purge the cached release URLs on flippercloud.io:
|
|
30
|
+
- `/release`
|
|
31
|
+
- `/release.json`
|
|
32
|
+
|
|
33
|
+
## Architecture Overview
|
|
34
|
+
|
|
35
|
+
Flipper is a feature flag library for Ruby with a modular adapter-based architecture:
|
|
36
|
+
|
|
37
|
+
### Core Components
|
|
38
|
+
|
|
39
|
+
**DSL Layer** (`lib/flipper/dsl.rb`):
|
|
40
|
+
- Main interface for feature flag operations
|
|
41
|
+
- Delegates to Feature instances
|
|
42
|
+
- Handles memoization and instrumentation
|
|
43
|
+
- Thread-safe instance management
|
|
44
|
+
|
|
45
|
+
**Feature** (`lib/flipper/feature.rb`):
|
|
46
|
+
- Represents individual feature flags
|
|
47
|
+
- Manages enable/disable operations through gates
|
|
48
|
+
- Handles instrumentation events
|
|
49
|
+
- Works with adapters for persistence
|
|
50
|
+
|
|
51
|
+
**Adapters** (`lib/flipper/adapters/`):
|
|
52
|
+
- Pluggable storage backends (Redis, ActiveRecord, Memory, etc.)
|
|
53
|
+
- Common interface for all storage implementations
|
|
54
|
+
- Support for caching, failover, and synchronization patterns
|
|
55
|
+
|
|
56
|
+
**Gates** (`lib/flipper/gates/`):
|
|
57
|
+
- Different targeting mechanisms:
|
|
58
|
+
- Boolean (on/off for everyone)
|
|
59
|
+
- Actor (specific users/entities)
|
|
60
|
+
- Group (predefined user groups)
|
|
61
|
+
- Percentage of Actors (rollout to X% of users)
|
|
62
|
+
- Percentage of Time (probabilistic enabling)
|
|
63
|
+
- Expression (complex conditional logic)
|
|
64
|
+
|
|
65
|
+
### Multi-Gem Structure
|
|
66
|
+
|
|
67
|
+
The project is structured as multiple gems:
|
|
68
|
+
- `flipper` - Core library
|
|
69
|
+
- `flipper-ui` - Web interface
|
|
70
|
+
- `flipper-api` - REST API
|
|
71
|
+
- `flipper-cloud` - Cloud service integration
|
|
72
|
+
- `flipper-*` - Various adapter gems (redis, active_record, mongo, etc.)
|
|
73
|
+
|
|
74
|
+
### Key Patterns
|
|
75
|
+
|
|
76
|
+
**Configuration**: Global configuration through `Flipper.configure` with per-thread instances
|
|
77
|
+
**Instrumentation**: Built-in event system for monitoring and debugging
|
|
78
|
+
**Memoization**: Automatic caching of feature checks within request/thread scope
|
|
79
|
+
**Type Safety**: Strong typing system for actors, percentages, and other values
|
|
80
|
+
|
|
81
|
+
### Serialization and HTTP
|
|
82
|
+
|
|
83
|
+
Use `Flipper::Typecast` for JSON and gzip serialization instead of calling `JSON.generate`/`JSON.parse` or `Zlib` directly:
|
|
84
|
+
- `Typecast.to_json(hash)` / `Typecast.from_json(string)` for JSON serialization
|
|
85
|
+
- `Typecast.to_gzip(string)` / `Typecast.from_gzip(string)` for gzip compression
|
|
86
|
+
|
|
87
|
+
For outbound HTTP requests, use `Flipper::Adapters::Http::Client` instead of raw `Net::HTTP`. It provides timeouts, retries (`max_retries`), SSL verification, and diagnostic headers (user-agent, client-language, client-platform, etc.). See `lib/flipper/cloud/migrate.rb` for an example.
|
|
88
|
+
|
|
89
|
+
### Testing
|
|
90
|
+
|
|
91
|
+
Uses both RSpec (currently preferred for new tests) and Minitest. Shared adapter specs ensure consistency across all storage backends. Extensive testing across multiple Rails versions (5.0-8.0).
|
|
92
|
+
|
|
93
|
+
`Flipper.configuration` is reset to nil before each spec (in `spec/spec_helper.rb`), but `Flipper::UI.configuration` is **not** globally reset. When modifying UI config in tests, set the value in `before` and reset it in `after` to match the existing pattern throughout the spec suite.
|