openfeature-sdk 0.6.4 → 0.6.6

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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/.ruby-version +1 -1
  4. data/.tool-versions +1 -1
  5. data/.yardopts +5 -0
  6. data/CHANGELOG.md +20 -0
  7. data/CLAUDE.md +4 -1
  8. data/CONTRIBUTING.md +15 -1
  9. data/Gemfile +17 -2
  10. data/Gemfile.lock +98 -67
  11. data/README.md +24 -8
  12. data/Rakefile +14 -0
  13. data/SECURITY.md +10 -0
  14. data/Steepfile +7 -0
  15. data/examples/basic_usage.rb +22 -0
  16. data/examples/custom_provider.rb +56 -0
  17. data/examples/rails_integration.rb +60 -0
  18. data/lib/open_feature/sdk/api.rb +1 -0
  19. data/lib/open_feature/sdk/client.rb +2 -3
  20. data/lib/open_feature/sdk/configuration.rb +26 -13
  21. data/lib/open_feature/sdk/evaluation_error.rb +28 -0
  22. data/lib/open_feature/sdk/hooks/hook_executor.rb +5 -5
  23. data/lib/open_feature/sdk/hooks/logging_hook.rb +1 -2
  24. data/lib/open_feature/sdk/provider/in_memory_provider.rb +24 -0
  25. data/lib/open_feature/sdk/provider_event.rb +5 -1
  26. data/lib/open_feature/sdk/provider_state_registry.rb +2 -2
  27. data/lib/open_feature/sdk/version.rb +1 -1
  28. data/openfeature-sdk.gemspec +34 -0
  29. data/rbs_collection.lock.yaml +292 -0
  30. data/rbs_collection.yaml +14 -0
  31. data/renovate.json +1 -1
  32. data/sig/open_feature/sdk/api.rbs +35 -0
  33. data/sig/open_feature/sdk/client.rbs +49 -0
  34. data/sig/open_feature/sdk/client_metadata.rbs +11 -0
  35. data/sig/open_feature/sdk/configuration.rbs +44 -0
  36. data/sig/open_feature/sdk/evaluation_context.rbs +19 -0
  37. data/sig/open_feature/sdk/evaluation_context_builder.rbs +7 -0
  38. data/sig/open_feature/sdk/evaluation_details.rbs +19 -0
  39. data/sig/open_feature/sdk/evaluation_error.rbs +11 -0
  40. data/sig/open_feature/sdk/event_dispatcher.rbs +24 -0
  41. data/sig/open_feature/sdk/hooks/hints.rbs +30 -0
  42. data/sig/open_feature/sdk/hooks/hook.rbs +19 -0
  43. data/sig/open_feature/sdk/hooks/hook_context.rbs +18 -0
  44. data/sig/open_feature/sdk/hooks/hook_executor.rbs +20 -0
  45. data/sig/open_feature/sdk/hooks/logging_hook.rbs +25 -0
  46. data/sig/open_feature/sdk/provider/error_code.rbs +16 -0
  47. data/sig/open_feature/sdk/provider/event_emitter.rbs +16 -0
  48. data/sig/open_feature/sdk/provider/in_memory_provider.rbs +46 -0
  49. data/sig/open_feature/sdk/provider/no_op_provider.rbs +25 -0
  50. data/sig/open_feature/sdk/provider/provider_metadata.rbs +11 -0
  51. data/sig/open_feature/sdk/provider/reason.rbs +17 -0
  52. data/sig/open_feature/sdk/provider/resolution_details.rbs +19 -0
  53. data/sig/open_feature/sdk/provider.rbs +24 -0
  54. data/sig/open_feature/sdk/provider_event.rbs +14 -0
  55. data/sig/open_feature/sdk/provider_initialization_error.rbs +11 -0
  56. data/sig/open_feature/sdk/provider_state.rbs +13 -0
  57. data/sig/open_feature/sdk/provider_state_registry.rbs +22 -0
  58. data/sig/open_feature/sdk/telemetry.rbs +29 -0
  59. data/sig/open_feature/sdk/thread_local_transaction_context_propagator.rbs +12 -0
  60. data/sig/open_feature/sdk/tracking_event_details.rbs +10 -0
  61. data/sig/open_feature/sdk/transaction_context_propagator.rbs +11 -0
  62. data/sig/open_feature/sdk/version.rbs +5 -0
  63. data/sig/open_feature/sdk.rbs +22 -0
  64. metadata +54 -140
  65. data/.simplecov +0 -12
  66. data/docs/plans/2026-03-07-telemetry-utility-design.md +0 -98
  67. data/docs/plans/2026-03-07-telemetry-utility-plan.md +0 -578
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4aa61c48f017d3311bfce9022a5e08d023ee1e2c09eb8799ff0e0a8424cf9fe3
4
- data.tar.gz: 8c559636076a0ec01911e9057d57cde4e430a7bc4b2543835dcd90527e0f0c0e
3
+ metadata.gz: 500c09c5333475a75aeff77cdab714c1360f4c14a84c28f9f16fe3b0dc42cb8f
4
+ data.tar.gz: 4d760e25308fad1ea762e8547260f87dea3474a8861eadd25993cfd2dde55b04
5
5
  SHA512:
6
- metadata.gz: 0f683b0d315b225259e540fb9f7d86f60a7e334c1501b7f05d45d677d1e7ee6cfb951b463514c05d9c64b5b413935d1bdf95cd684aa5f05136ed87a6cf2ba122
7
- data.tar.gz: 618dcac7749c461bb77b92f7f7b68e2071b4b71825d05330bb18a08df3a929019ef0fa8d12d79b117fdd3fce431d48f5e15d2f90aa884fa4f28b1226229f9db0
6
+ metadata.gz: 4bfda5295966ab245426ecaa0d2dbb440b7f273833193906b9fd91fd6ffeb41e5b49e652a9d05dbf6679c08cfc434c4733d34384dfc1d64be995194f3938cdf1
7
+ data.tar.gz: 2359651d7407cdd30e41e15e4d764efc47565e025b2046adbc4942da0c25d62396bd5e52991626d728b675b123aa52bcce733f8ebc71703112ebe77d6704e96e
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.6.4"
2
+ ".": "0.6.6"
3
3
  }
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 4.0.1
1
+ 4.0.7
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 4.0.1
1
+ ruby 4.0.7
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --markup markdown
2
+ --output-dir doc
3
+ lib/**/*.rb
4
+ - README.md
5
+ - CHANGELOG.md
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.6](https://github.com/open-feature/ruby-sdk/compare/v0.6.5...v0.6.6) (2026-10-22)
4
+
5
+
6
+ ### Features
7
+
8
+ * add PROVIDER_RECONCILING and PROVIDER_CONTEXT_CHANGED events ([#338](https://github.com/open-feature/ruby-sdk/issues/338)) ([2b93aa4](https://github.com/open-feature/ruby-sdk/commit/2b93aa4daf7087a818d0b758c7978e7ad3c1c589))
9
+ * support variant flags in InMemoryProvider ([#340](https://github.com/open-feature/ruby-sdk/issues/340)) ([1e4b168](https://github.com/open-feature/ruby-sdk/commit/1e4b168373e39522c4884e34383730d48772b95f))
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * carry provider error codes through hooks ([#339](https://github.com/open-feature/ruby-sdk/issues/339)) ([b9e586c](https://github.com/open-feature/ruby-sdk/commit/b9e586c518a4b8e85facbb90e123c347b0db33e5))
15
+
16
+ ## [0.6.5](https://github.com/open-feature/ruby-sdk/compare/v0.6.4...v0.6.5) (2026-03-18)
17
+
18
+
19
+ ### Features
20
+
21
+ * add RBS type signatures with Steep type checking ([#251](https://github.com/open-feature/ruby-sdk/issues/251)) ([506e999](https://github.com/open-feature/ruby-sdk/commit/506e9992e6c8b7222b2ae2eb3b1c2fb3d5d148a6))
22
+
3
23
  ## [0.6.4](https://github.com/open-feature/ruby-sdk/compare/v0.6.3...v0.6.4) (2026-03-07)
4
24
 
5
25
 
data/CLAUDE.md CHANGED
@@ -4,15 +4,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4
4
 
5
5
  ## Overview
6
6
 
7
- This is the official OpenFeature SDK for Ruby — an implementation of the [OpenFeature specification](https://openfeature.dev) providing a vendor-agnostic API for feature flag evaluation. Published as the `openfeature-sdk` gem. Requires Ruby >= 3.1.
7
+ This is the official OpenFeature SDK for Ruby — an implementation of the [OpenFeature specification](https://openfeature.dev) providing a vendor-agnostic API for feature flag evaluation. Published as the `openfeature-sdk` gem. Requires Ruby >= 3.4.
8
8
 
9
9
  ## Commands
10
10
 
11
+ - **Install dependencies:** `bundle install`
11
12
  - **Run all tests:** `bundle exec rspec`
12
13
  - **Run a single test file:** `bundle exec rspec spec/open_feature/sdk/client_spec.rb`
13
14
  - **Run a specific test by line:** `bundle exec rspec spec/open_feature/sdk/client_spec.rb:43`
14
15
  - **Lint:** `bundle exec standardrb`
15
16
  - **Lint with autofix:** `bundle exec standardrb --fix`
17
+ - **Type check:** `bundle exec steep check`
16
18
  - **Default rake (tests + lint):** `bundle exec rake`
17
19
 
18
20
  Note: Linting uses [Standard Ruby](https://github.com/standardrb/standard) (configured via the `standard` gem), which enforces double-quoted strings and its own opinionated style. There is no `.rubocop.yml` — Standard manages RuboCop configuration internally. Do not use `bundle exec rubocop` directly as a stale RuboCop server may apply different rules; always use `bundle exec standardrb`.
@@ -47,5 +49,6 @@ Providers can be registered for specific domains. `Configuration#provider(domain
47
49
 
48
50
  - All `.rb` files must have `# frozen_string_literal: true` as the first line.
49
51
  - Tests live under `spec/` and mirror the `lib/` structure. `spec/specification/` contains tests mapped to OpenFeature spec requirements.
52
+ - RBS type signatures live under `sig/` and mirror the `lib/` structure. When changing any file under `lib/`, always update the corresponding `.rbs` file under `sig/` to reflect the new or modified method signatures, constants, or class structure. Run `bundle exec steep check` to verify type correctness after changes.
50
53
  - Always sign git commits using the `-S` flag.
51
54
  - Always include DCO sign-off in commits using the `-s` flag (i.e., `git commit -s -S`). This adds a `Signed-off-by` trailer required by the project's CI.
data/CONTRIBUTING.md CHANGED
@@ -7,7 +7,7 @@ You can contribute to this project from a Windows, macOS or Linux machine.
7
7
  On all platforms, the minimum requirements are:
8
8
 
9
9
  * Git client and command line tools.
10
- * Ruby 3.0 or higher
10
+ * Ruby 3.4 or higher
11
11
 
12
12
  ## Pull Request
13
13
 
@@ -50,6 +50,20 @@ To run unit tests and other checks:
50
50
  bundle exec rake
51
51
  ```
52
52
 
53
+ #### Spec conformance tests (Gherkin)
54
+
55
+ The project includes Gherkin-based conformance tests that verify compliance with the OpenFeature specification:
56
+
57
+ ```bash
58
+ bundle exec cucumber
59
+ ```
60
+
61
+ #### Linting
62
+
63
+ This project uses [Standard Ruby](https://github.com/standardrb/standard) for code style enforcement.
64
+ Run `bundle exec standardrb` to check, or `bundle exec standardrb --fix` to auto-fix.
65
+ Do not run `bundle exec rubocop` directly, as a stale RuboCop server may apply different rules.
66
+
53
67
  ### How to Receive Comments
54
68
 
55
69
  * If the PR is not ready for review, please mark it as
data/Gemfile CHANGED
@@ -5,5 +5,20 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in openfeature-sdk.gemspec
6
6
  gemspec
7
7
 
8
- gem "cucumber", "~> 10.0", group: :test
9
- gem "logger", group: :test
8
+ group :development, :test do
9
+ gem "debug"
10
+ gem "markly"
11
+ gem "rake", "~> 13.0"
12
+ gem "rspec", "~> 3.13.0"
13
+ gem "standard"
14
+ gem "standard-performance"
15
+ gem "simplecov", "~> 1.3.0"
16
+ gem "simplecov-cobertura", "~> 4.0"
17
+ gem "steep", "~> 2.0"
18
+ gem "timecop", "~> 0.9.10"
19
+ end
20
+
21
+ group :test do
22
+ gem "cucumber", "~> 11.0"
23
+ gem "logger"
24
+ end
data/Gemfile.lock CHANGED
@@ -1,109 +1,119 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openfeature-sdk (0.6.4)
4
+ openfeature-sdk (0.6.6)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.3)
10
10
  base64 (0.3.0)
11
- bigdecimal (4.0.1)
11
+ bigdecimal (4.1.3)
12
12
  builder (3.3.0)
13
- cucumber (10.2.0)
13
+ concurrent-ruby (1.3.8)
14
+ csv (3.3.6)
15
+ cucumber (11.1.1)
14
16
  base64 (~> 0.2)
15
17
  builder (~> 3.2)
16
18
  cucumber-ci-environment (> 9, < 12)
17
- cucumber-core (> 15, < 17)
19
+ cucumber-core (>= 16.2.0, < 17)
18
20
  cucumber-cucumber-expressions (> 17, < 20)
19
- cucumber-html-formatter (> 21, < 23)
21
+ cucumber-html-formatter (> 21, < 24)
20
22
  diff-lcs (~> 1.5)
21
23
  logger (~> 1.6)
22
24
  mini_mime (~> 1.1)
23
25
  multi_test (~> 1.1)
24
- sys-uname (~> 1.3)
26
+ sys-uname (~> 1.5)
25
27
  cucumber-ci-environment (11.0.0)
26
28
  cucumber-core (16.2.0)
27
29
  cucumber-gherkin (> 36, < 40)
28
30
  cucumber-messages (> 31, < 33)
29
31
  cucumber-tag-expressions (> 6, < 9)
30
- cucumber-cucumber-expressions (19.0.0)
32
+ cucumber-cucumber-expressions (19.0.1)
31
33
  bigdecimal
32
- cucumber-gherkin (39.0.0)
34
+ cucumber-gherkin (39.1.0)
33
35
  cucumber-messages (>= 31, < 33)
34
- cucumber-html-formatter (22.3.0)
36
+ cucumber-html-formatter (23.1.0)
35
37
  cucumber-messages (> 23, < 33)
36
- cucumber-messages (32.2.0)
38
+ cucumber-messages (32.3.1)
37
39
  cucumber-tag-expressions (8.1.0)
38
- date (3.5.1)
39
40
  debug (1.11.1)
40
41
  irb (~> 1.10)
41
42
  reline (>= 0.3.8)
42
43
  diff-lcs (1.6.2)
43
- docile (1.4.1)
44
- erb (6.0.2)
45
- ffi (1.17.3)
46
- io-console (0.8.2)
47
- irb (1.17.0)
44
+ erb (6.0.7)
45
+ ffi (1.17.4)
46
+ fileutils (1.8.1)
47
+ io-console (0.9.4)
48
+ irb (1.18.0)
48
49
  pp (>= 0.6.0)
49
50
  prism (>= 1.3.0)
50
51
  rdoc (>= 4.0.0)
51
52
  reline (>= 0.4.2)
52
- json (2.18.1)
53
- language_server-protocol (3.17.0.5)
53
+ json (3.1.0)
54
+ language_server-protocol (3.17.0.6)
54
55
  lint_roller (1.1.0)
56
+ listen (3.10.1)
57
+ logger
58
+ rb-fsevent (~> 0.10, >= 0.10.3)
59
+ rb-inotify (~> 0.9, >= 0.9.10)
55
60
  logger (1.7.0)
56
- markly (0.15.2)
61
+ markly (0.19.0)
57
62
  memoist3 (1.0.0)
58
63
  mini_mime (1.1.5)
59
64
  multi_test (1.1.0)
60
- parallel (1.27.0)
61
- parser (3.3.10.2)
65
+ parallel (2.3.0)
66
+ parser (3.3.12.0)
62
67
  ast (~> 2.4.1)
63
68
  racc
64
- pp (0.6.3)
69
+ pp (0.6.4)
65
70
  prettyprint
66
- prettyprint (0.2.0)
71
+ prettyprint (0.2.1)
67
72
  prism (1.9.0)
68
- psych (5.3.1)
69
- date
70
- stringio
71
73
  racc (1.8.1)
72
74
  rainbow (3.1.1)
73
- rake (13.3.1)
74
- rdoc (7.2.0)
75
+ rake (13.4.2)
76
+ rb-fsevent (0.11.2)
77
+ rb-inotify (0.11.1)
78
+ ffi (~> 1.0)
79
+ rbs (4.2.0)
80
+ logger
81
+ prism (>= 1.6.0)
82
+ tsort
83
+ rdoc (8.1.0)
75
84
  erb
76
- psych (>= 4.0.0)
85
+ prism (>= 1.6.0)
86
+ rbs (>= 4.0.0)
77
87
  tsort
78
- regexp_parser (2.11.3)
79
- reline (0.6.3)
88
+ regexp_parser (2.13.1)
89
+ reline (0.7.0)
80
90
  io-console (~> 0.5)
81
91
  rexml (3.4.4)
82
- rspec (3.12.0)
83
- rspec-core (~> 3.12.0)
84
- rspec-expectations (~> 3.12.0)
85
- rspec-mocks (~> 3.12.0)
86
- rspec-core (3.12.3)
87
- rspec-support (~> 3.12.0)
88
- rspec-expectations (3.12.4)
92
+ rspec (3.13.2)
93
+ rspec-core (~> 3.13.0)
94
+ rspec-expectations (~> 3.13.0)
95
+ rspec-mocks (~> 3.13.0)
96
+ rspec-core (3.13.6)
97
+ rspec-support (~> 3.13.0)
98
+ rspec-expectations (3.13.5)
89
99
  diff-lcs (>= 1.2.0, < 2.0)
90
- rspec-support (~> 3.12.0)
91
- rspec-mocks (3.12.7)
100
+ rspec-support (~> 3.13.0)
101
+ rspec-mocks (3.13.8)
92
102
  diff-lcs (>= 1.2.0, < 2.0)
93
- rspec-support (~> 3.12.0)
94
- rspec-support (3.12.2)
95
- rubocop (1.84.2)
96
- json (~> 2.3)
103
+ rspec-support (~> 3.13.0)
104
+ rspec-support (3.13.7)
105
+ rubocop (1.91.0)
106
+ json (>= 2.3)
97
107
  language_server-protocol (~> 3.17.0.2)
98
108
  lint_roller (~> 1.1.0)
99
- parallel (~> 1.10)
109
+ parallel (>= 1.10)
100
110
  parser (>= 3.3.0.2)
101
111
  rainbow (>= 2.2.2, < 4.0)
102
112
  regexp_parser (>= 2.9.3, < 3.0)
103
113
  rubocop-ast (>= 1.49.0, < 2.0)
104
114
  ruby-progressbar (~> 1.7)
105
115
  unicode-display_width (>= 2.4.0, < 4.0)
106
- rubocop-ast (1.49.0)
116
+ rubocop-ast (1.50.0)
107
117
  parser (>= 3.3.7.2)
108
118
  prism (~> 1.7)
109
119
  rubocop-performance (1.26.1)
@@ -111,19 +121,15 @@ GEM
111
121
  rubocop (>= 1.75.0, < 2.0)
112
122
  rubocop-ast (>= 1.47.1, < 2.0)
113
123
  ruby-progressbar (1.13.0)
114
- simplecov (0.22.0)
115
- docile (~> 1.1)
116
- simplecov-html (~> 0.11)
117
- simplecov_json_formatter (~> 0.1)
118
- simplecov-cobertura (3.1.0)
124
+ securerandom (0.4.1)
125
+ simplecov (1.3.2)
126
+ simplecov-cobertura (4.0.0)
119
127
  rexml
120
- simplecov (~> 0.19)
121
- simplecov-html (0.13.2)
122
- simplecov_json_formatter (0.1.4)
123
- standard (1.54.0)
128
+ simplecov (~> 1.0)
129
+ standard (1.57.0)
124
130
  language_server-protocol (~> 3.17.0.2)
125
131
  lint_roller (~> 1.0)
126
- rubocop (~> 1.84.0)
132
+ rubocop (~> 1.91.0)
127
133
  standard-custom (~> 1.0.0)
128
134
  standard-performance (~> 1.8)
129
135
  standard-custom (1.0.2)
@@ -132,15 +138,39 @@ GEM
132
138
  standard-performance (1.9.0)
133
139
  lint_roller (~> 1.1)
134
140
  rubocop-performance (~> 1.26.0)
135
- stringio (3.2.0)
136
- sys-uname (1.5.0)
141
+ steep (2.1.0)
142
+ concurrent-ruby (>= 1.1.10)
143
+ csv (>= 3.0.9)
144
+ fileutils (>= 1.1.0)
145
+ json (>= 2.1.0)
146
+ language_server-protocol (>= 3.17.0.4, < 4.0)
147
+ listen (~> 3.0)
148
+ logger (>= 1.3.0)
149
+ parser (>= 3.2)
150
+ prism (>= 0.25.0)
151
+ rainbow (>= 2.2.2, < 4.0)
152
+ rbs (~> 4.2)
153
+ securerandom (>= 0.1)
154
+ strscan (>= 1.0.0)
155
+ terminal-table (>= 2, < 5)
156
+ uri (>= 0.12.0)
157
+ strscan (3.1.8)
158
+ sys-uname (1.5.1)
159
+ ffi (~> 1.1)
160
+ memoist3 (~> 1.0.0)
161
+ sys-uname (1.5.1-universal-mingw32)
137
162
  ffi (~> 1.1)
138
163
  memoist3 (~> 1.0.0)
139
- timecop (0.9.10)
164
+ win32ole
165
+ terminal-table (4.0.0)
166
+ unicode-display_width (>= 1.1.1, < 4)
167
+ timecop (0.9.11)
140
168
  tsort (0.2.0)
141
- unicode-display_width (3.2.0)
142
- unicode-emoji (~> 4.1)
143
- unicode-emoji (4.2.0)
169
+ unicode-display_width (3.3.0)
170
+ unicode-emoji (~> 4.3)
171
+ unicode-emoji (4.3.0)
172
+ uri (1.1.2)
173
+ win32ole (1.9.3)
144
174
 
145
175
  PLATFORMS
146
176
  arm64-darwin-21
@@ -156,18 +186,19 @@ PLATFORMS
156
186
  x86_64-linux
157
187
 
158
188
  DEPENDENCIES
159
- cucumber (~> 10.0)
189
+ cucumber (~> 11.0)
160
190
  debug
161
191
  logger
162
192
  markly
163
193
  openfeature-sdk!
164
194
  rake (~> 13.0)
165
- rspec (~> 3.12.0)
166
- simplecov (~> 0.22.0)
167
- simplecov-cobertura (~> 3.0)
195
+ rspec (~> 3.13.0)
196
+ simplecov (~> 1.3.0)
197
+ simplecov-cobertura (~> 4.0)
168
198
  standard
169
199
  standard-performance
200
+ steep (~> 2.0)
170
201
  timecop (~> 0.9.10)
171
202
 
172
203
  BUNDLED WITH
173
- 2.3.25
204
+ 4.0.12
data/README.md CHANGED
@@ -17,11 +17,20 @@
17
17
  </a>
18
18
  <!-- x-release-please-start-version -->
19
19
 
20
- <a href="https://github.com/open-feature/ruby-sdk/releases/tag/v0.6.4">
21
- <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.6.4&color=blue&style=for-the-badge" />
20
+ <a href="https://github.com/open-feature/ruby-sdk/releases/tag/v0.6.6">
21
+ <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.6.6&color=blue&style=for-the-badge" />
22
22
  </a>
23
23
 
24
24
  <!-- x-release-please-end -->
25
+ <a href="https://github.com/open-feature/ruby-sdk/actions/workflows/main.yml">
26
+ <img alt="Build" src="https://img.shields.io/github/actions/workflow/status/open-feature/ruby-sdk/main.yml?style=for-the-badge" />
27
+ </a>
28
+ <a href="https://rubygems.org/gems/openfeature-sdk">
29
+ <img alt="Gem Version" src="https://img.shields.io/gem/v/openfeature-sdk?style=for-the-badge&color=red" />
30
+ </a>
31
+ <a href="https://codecov.io/gh/open-feature/ruby-sdk">
32
+ <img alt="Code Coverage" src="https://img.shields.io/codecov/c/github/open-feature/ruby-sdk?style=for-the-badge" />
33
+ </a>
25
34
  <br/>
26
35
  <a href="https://bestpractices.coreinfrastructure.org/projects/9337">
27
36
  <img alt="CII Best Practices" src="https://bestpractices.coreinfrastructure.org/projects/9337/badge" />
@@ -41,6 +50,8 @@
41
50
  | Ruby 3.4.x | Windows, MacOS, Linux |
42
51
  | Ruby 4.0.x | Windows, MacOS, Linux |
43
52
 
53
+ This project supports all Ruby versions in active maintenance per the [Ruby maintenance schedule](https://www.ruby-lang.org/en/downloads/branches/).
54
+
44
55
  ### Install
45
56
 
46
57
  Install the gem and add to the application's Gemfile by executing:
@@ -59,7 +70,6 @@ gem install openfeature-sdk
59
70
 
60
71
  ```ruby
61
72
  require 'open_feature/sdk'
62
- require 'json' # For JSON.dump
63
73
 
64
74
  # API Initialization and configuration
65
75
 
@@ -68,7 +78,13 @@ OpenFeature::SDK.configure do |config|
68
78
  config.set_provider(OpenFeature::SDK::Provider::InMemoryProvider.new(
69
79
  {
70
80
  "flag1" => true,
71
- "flag2" => 1
81
+ "flag2" => 1,
82
+ # Variant flags report a variant and reason, and can target on the evaluation context
83
+ "flag3" => OpenFeature::SDK::Provider::InMemoryProvider::Flag.new(
84
+ variants: {"on" => true, "off" => false},
85
+ default_variant: "off",
86
+ context_evaluator: ->(ctx) { "on" if ctx&.targeting_key == "beta-user" }
87
+ )
72
88
  }
73
89
  ))
74
90
  end
@@ -80,7 +96,7 @@ client = OpenFeature::SDK.build_client
80
96
  bool_value = client.fetch_boolean_value(flag_key: 'boolean_flag', default_value: false)
81
97
 
82
98
  # a details method is also available for more information about the flag evaluation
83
- # see `ResolutionDetails` for more info
99
+ # see `EvaluationDetails` for more info
84
100
  bool_details = client.fetch_boolean_details(flag_key: 'boolean_flag', default_value: false)
85
101
 
86
102
  # fetching string value feature flag
@@ -115,6 +131,7 @@ object = client.fetch_object_value(flag_key: 'object_value', default_value: { na
115
131
 
116
132
  [Providers](https://openfeature.dev/docs/reference/concepts/provider) are an abstraction between a flag management system and the OpenFeature SDK.
117
133
  Look [here](https://openfeature.dev/ecosystem?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=Ruby) for a complete list of available providers.
134
+
118
135
  If the provider you're looking for hasn't been created yet, see the [develop a provider](#develop-a-provider) section to learn how to build it yourself.
119
136
 
120
137
  Once you've added a provider as a dependency, it can be registered with OpenFeature like this:
@@ -146,9 +163,6 @@ rescue OpenFeature::SDK::ProviderInitializationError => e
146
163
  puts "Original error: #{e.original_error}"
147
164
  end
148
165
 
149
- # With custom timeout (default is 30 seconds)
150
- OpenFeature::SDK.set_provider_and_wait(my_provider, timeout: 60)
151
-
152
166
  # Domain-specific provider
153
167
  OpenFeature::SDK.set_provider_and_wait(my_provider, domain: "feature-flags")
154
168
 
@@ -442,6 +456,8 @@ class MyProvider
442
456
 
443
457
  def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
444
458
  # Retrieve a boolean value from provider source
459
+ # To signal an error, return ResolutionDetails with an error_code, or raise
460
+ # OpenFeature::SDK::EvaluationError.new("message", error_code: OpenFeature::SDK::Provider::ErrorCode::FLAG_NOT_FOUND)
445
461
  end
446
462
 
447
463
  def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
data/Rakefile CHANGED
@@ -7,9 +7,23 @@ RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  require "standard/rake"
9
9
 
10
+ begin
11
+ require "yard"
12
+ YARD::Rake::YardocTask.new
13
+ rescue LoadError
14
+ # YARD not available
15
+ end
16
+
10
17
  desc "Run Cucumber Gherkin feature tests"
11
18
  task :cucumber do
12
19
  sh "bundle exec cucumber"
13
20
  end
14
21
 
22
+ begin
23
+ require "steep/rake_task"
24
+ Steep::RakeTask.new
25
+ rescue LoadError
26
+ # Steep not available
27
+ end
28
+
15
29
  task default: %i[spec standard]
data/SECURITY.md ADDED
@@ -0,0 +1,10 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ If you discover a security vulnerability, please report it responsibly.
6
+ Do NOT open a public GitHub issue.
7
+
8
+ Please email security concerns to: cncf-openfeature-contributors@lists.cncf.io
9
+
10
+ We will acknowledge receipt within 48 hours and provide a timeline for a fix.
data/Steepfile ADDED
@@ -0,0 +1,7 @@
1
+ D = Steep::Diagnostic
2
+
3
+ target :lib do
4
+ signature "sig"
5
+ check "lib"
6
+ configure_code_diagnostics(D::Ruby.lenient)
7
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open_feature/sdk"
4
+
5
+ # Configure OpenFeature with the in-memory provider for demonstration
6
+ OpenFeature::SDK.configure do |config|
7
+ config.set_provider(OpenFeature::SDK::Provider::InMemoryProvider.new(
8
+ "v2_enabled" => true,
9
+ "welcome_message" => "Hello, OpenFeature!",
10
+ "item_limit" => 42,
11
+ "theme" => {"color" => "blue", "mode" => "dark"}
12
+ ))
13
+ end
14
+
15
+ # Create a client
16
+ client = OpenFeature::SDK.build_client
17
+
18
+ # Evaluate different flag types
19
+ puts client.fetch_boolean_value(flag_key: "v2_enabled", default_value: false)
20
+ puts client.fetch_string_value(flag_key: "welcome_message", default_value: "default")
21
+ puts client.fetch_number_value(flag_key: "item_limit", default_value: 10)
22
+ puts client.fetch_object_value(flag_key: "theme", default_value: {})
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open_feature/sdk"
4
+
5
+ # A minimal custom provider demonstrating the duck type interface.
6
+ # Any object implementing the fetch_*_value methods works as a provider.
7
+ class MyProvider
8
+ def metadata
9
+ OpenFeature::SDK::Provider::ProviderMetadata.new(name: "my-provider")
10
+ end
11
+
12
+ def init(evaluation_context = nil)
13
+ # Perform setup (connect to flag service, load config, etc.)
14
+ end
15
+
16
+ def shutdown
17
+ # Clean up resources
18
+ end
19
+
20
+ def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
21
+ OpenFeature::SDK::Provider::ResolutionDetails.new(
22
+ value: true,
23
+ reason: "STATIC",
24
+ variant: "on"
25
+ )
26
+ end
27
+
28
+ # The remaining methods return the default value for brevity.
29
+ # A real provider would look up each flag_key in its flag management system.
30
+ def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
31
+ OpenFeature::SDK::Provider::ResolutionDetails.new(value: default_value)
32
+ end
33
+
34
+ def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
35
+ OpenFeature::SDK::Provider::ResolutionDetails.new(value: default_value)
36
+ end
37
+
38
+ def fetch_integer_value(flag_key:, default_value:, evaluation_context: nil)
39
+ OpenFeature::SDK::Provider::ResolutionDetails.new(value: default_value)
40
+ end
41
+
42
+ def fetch_float_value(flag_key:, default_value:, evaluation_context: nil)
43
+ OpenFeature::SDK::Provider::ResolutionDetails.new(value: default_value)
44
+ end
45
+
46
+ def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
47
+ OpenFeature::SDK::Provider::ResolutionDetails.new(value: default_value)
48
+ end
49
+ end
50
+
51
+ OpenFeature::SDK.configure do |config|
52
+ config.set_provider(MyProvider.new)
53
+ end
54
+
55
+ client = OpenFeature::SDK.build_client
56
+ puts client.fetch_boolean_value(flag_key: "any_flag", default_value: false)