openfeature-sdk 0.6.4 → 0.6.5
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/.release-please-manifest.json +1 -1
- data/.ruby-version +1 -1
- data/.simplecov +1 -0
- data/.tool-versions +1 -1
- data/.yardopts +5 -0
- data/CHANGELOG.md +7 -0
- data/CLAUDE.md +3 -0
- data/CONTRIBUTING.md +15 -1
- data/Gemfile +17 -2
- data/Gemfile.lock +72 -13
- data/README.md +14 -2
- data/Rakefile +14 -0
- data/SECURITY.md +10 -0
- data/Steepfile +7 -0
- data/examples/basic_usage.rb +22 -0
- data/examples/custom_provider.rb +56 -0
- data/examples/rails_integration.rb +60 -0
- data/lib/open_feature/sdk/version.rb +1 -1
- data/openfeature-sdk.gemspec +34 -0
- data/rbs_collection.lock.yaml +292 -0
- data/rbs_collection.yaml +14 -0
- data/sig/open_feature/sdk/api.rbs +35 -0
- data/sig/open_feature/sdk/client.rbs +49 -0
- data/sig/open_feature/sdk/client_metadata.rbs +11 -0
- data/sig/open_feature/sdk/configuration.rbs +43 -0
- data/sig/open_feature/sdk/evaluation_context.rbs +19 -0
- data/sig/open_feature/sdk/evaluation_context_builder.rbs +7 -0
- data/sig/open_feature/sdk/evaluation_details.rbs +19 -0
- data/sig/open_feature/sdk/event_dispatcher.rbs +24 -0
- data/sig/open_feature/sdk/hooks/hints.rbs +30 -0
- data/sig/open_feature/sdk/hooks/hook.rbs +19 -0
- data/sig/open_feature/sdk/hooks/hook_context.rbs +18 -0
- data/sig/open_feature/sdk/hooks/hook_executor.rbs +20 -0
- data/sig/open_feature/sdk/hooks/logging_hook.rbs +25 -0
- data/sig/open_feature/sdk/provider/error_code.rbs +16 -0
- data/sig/open_feature/sdk/provider/event_emitter.rbs +16 -0
- data/sig/open_feature/sdk/provider/in_memory_provider.rbs +35 -0
- data/sig/open_feature/sdk/provider/no_op_provider.rbs +25 -0
- data/sig/open_feature/sdk/provider/provider_metadata.rbs +11 -0
- data/sig/open_feature/sdk/provider/reason.rbs +17 -0
- data/sig/open_feature/sdk/provider/resolution_details.rbs +19 -0
- data/sig/open_feature/sdk/provider.rbs +24 -0
- data/sig/open_feature/sdk/provider_event.rbs +12 -0
- data/sig/open_feature/sdk/provider_initialization_error.rbs +11 -0
- data/sig/open_feature/sdk/provider_state.rbs +13 -0
- data/sig/open_feature/sdk/provider_state_registry.rbs +22 -0
- data/sig/open_feature/sdk/telemetry.rbs +29 -0
- data/sig/open_feature/sdk/thread_local_transaction_context_propagator.rbs +12 -0
- data/sig/open_feature/sdk/tracking_event_details.rbs +10 -0
- data/sig/open_feature/sdk/transaction_context_propagator.rbs +11 -0
- data/sig/open_feature/sdk/version.rbs +5 -0
- data/sig/open_feature/sdk.rbs +22 -0
- metadata +52 -139
- data/docs/plans/2026-03-07-telemetry-utility-design.md +0 -98
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 70a393d81225d8b8b546f985dffee74d8b12451e1b9c18d348e6ac3d6a7781e6
|
|
4
|
+
data.tar.gz: 960f7f7ba3e704965b1dcb1d38c800d162874a9abf423ce0dc09695e8e7b7372
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e166c0c2698e277129734166ec0e0ed33d38329e090fa2760f720d653df93037e599ce83ba14eea803c99bb3be5b7c301e2e522dc99cc47f6299ce41699be451
|
|
7
|
+
data.tar.gz: f74b128a0a376b5f934940226d5a96906b21500373afbce98d52267580a69fab59cc5b0b043f90546bfbf7ed3393ae5033d510e80c50f5abc57a77f10d5a93c7
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.0.
|
|
1
|
+
4.0.2
|
data/.simplecov
CHANGED
data/.tool-versions
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby 4.0.
|
|
1
|
+
ruby 4.0.2
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.5](https://github.com/open-feature/ruby-sdk/compare/v0.6.4...v0.6.5) (2026-03-18)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* 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))
|
|
9
|
+
|
|
3
10
|
## [0.6.4](https://github.com/open-feature/ruby-sdk/compare/v0.6.3...v0.6.4) (2026-03-07)
|
|
4
11
|
|
|
5
12
|
|
data/CLAUDE.md
CHANGED
|
@@ -8,11 +8,13 @@ This is the official OpenFeature SDK for Ruby — an implementation of the [Open
|
|
|
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.
|
|
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
|
-
|
|
9
|
-
gem "
|
|
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", "~> 0.22.0"
|
|
16
|
+
gem "simplecov-cobertura", "~> 3.0"
|
|
17
|
+
gem "steep", "~> 1.9"
|
|
18
|
+
gem "timecop", "~> 0.9.10"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
group :test do
|
|
22
|
+
gem "cucumber", "~> 10.0"
|
|
23
|
+
gem "logger"
|
|
24
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
openfeature-sdk (0.6.
|
|
4
|
+
openfeature-sdk (0.6.5)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
+
activesupport (8.1.2)
|
|
10
|
+
base64
|
|
11
|
+
bigdecimal
|
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
13
|
+
connection_pool (>= 2.2.5)
|
|
14
|
+
drb
|
|
15
|
+
i18n (>= 1.6, < 2)
|
|
16
|
+
json
|
|
17
|
+
logger (>= 1.4.2)
|
|
18
|
+
minitest (>= 5.1)
|
|
19
|
+
securerandom (>= 0.3)
|
|
20
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
21
|
+
uri (>= 0.13.1)
|
|
9
22
|
ast (2.4.3)
|
|
10
23
|
base64 (0.3.0)
|
|
11
24
|
bigdecimal (4.0.1)
|
|
12
25
|
builder (3.3.0)
|
|
26
|
+
concurrent-ruby (1.3.6)
|
|
27
|
+
connection_pool (3.0.2)
|
|
28
|
+
csv (3.3.5)
|
|
13
29
|
cucumber (10.2.0)
|
|
14
30
|
base64 (~> 0.2)
|
|
15
31
|
builder (~> 3.2)
|
|
@@ -41,8 +57,12 @@ GEM
|
|
|
41
57
|
reline (>= 0.3.8)
|
|
42
58
|
diff-lcs (1.6.2)
|
|
43
59
|
docile (1.4.1)
|
|
60
|
+
drb (2.2.3)
|
|
44
61
|
erb (6.0.2)
|
|
45
62
|
ffi (1.17.3)
|
|
63
|
+
fileutils (1.8.0)
|
|
64
|
+
i18n (1.14.8)
|
|
65
|
+
concurrent-ruby (~> 1.0)
|
|
46
66
|
io-console (0.8.2)
|
|
47
67
|
irb (1.17.0)
|
|
48
68
|
pp (>= 0.6.0)
|
|
@@ -52,11 +72,19 @@ GEM
|
|
|
52
72
|
json (2.18.1)
|
|
53
73
|
language_server-protocol (3.17.0.5)
|
|
54
74
|
lint_roller (1.1.0)
|
|
75
|
+
listen (3.10.0)
|
|
76
|
+
logger
|
|
77
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
78
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
|
55
79
|
logger (1.7.0)
|
|
56
80
|
markly (0.15.2)
|
|
57
81
|
memoist3 (1.0.0)
|
|
58
82
|
mini_mime (1.1.5)
|
|
83
|
+
minitest (6.0.2)
|
|
84
|
+
drb (~> 2.0)
|
|
85
|
+
prism (~> 1.5)
|
|
59
86
|
multi_test (1.1.0)
|
|
87
|
+
mutex_m (0.3.0)
|
|
60
88
|
parallel (1.27.0)
|
|
61
89
|
parser (3.3.10.2)
|
|
62
90
|
ast (~> 2.4.1)
|
|
@@ -71,6 +99,12 @@ GEM
|
|
|
71
99
|
racc (1.8.1)
|
|
72
100
|
rainbow (3.1.1)
|
|
73
101
|
rake (13.3.1)
|
|
102
|
+
rb-fsevent (0.11.2)
|
|
103
|
+
rb-inotify (0.11.1)
|
|
104
|
+
ffi (~> 1.0)
|
|
105
|
+
rbs (3.10.3)
|
|
106
|
+
logger
|
|
107
|
+
tsort
|
|
74
108
|
rdoc (7.2.0)
|
|
75
109
|
erb
|
|
76
110
|
psych (>= 4.0.0)
|
|
@@ -79,19 +113,19 @@ GEM
|
|
|
79
113
|
reline (0.6.3)
|
|
80
114
|
io-console (~> 0.5)
|
|
81
115
|
rexml (3.4.4)
|
|
82
|
-
rspec (3.
|
|
83
|
-
rspec-core (~> 3.
|
|
84
|
-
rspec-expectations (~> 3.
|
|
85
|
-
rspec-mocks (~> 3.
|
|
86
|
-
rspec-core (3.
|
|
87
|
-
rspec-support (~> 3.
|
|
88
|
-
rspec-expectations (3.
|
|
116
|
+
rspec (3.13.2)
|
|
117
|
+
rspec-core (~> 3.13.0)
|
|
118
|
+
rspec-expectations (~> 3.13.0)
|
|
119
|
+
rspec-mocks (~> 3.13.0)
|
|
120
|
+
rspec-core (3.13.6)
|
|
121
|
+
rspec-support (~> 3.13.0)
|
|
122
|
+
rspec-expectations (3.13.5)
|
|
89
123
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
90
|
-
rspec-support (~> 3.
|
|
91
|
-
rspec-mocks (3.
|
|
124
|
+
rspec-support (~> 3.13.0)
|
|
125
|
+
rspec-mocks (3.13.8)
|
|
92
126
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
93
|
-
rspec-support (~> 3.
|
|
94
|
-
rspec-support (3.
|
|
127
|
+
rspec-support (~> 3.13.0)
|
|
128
|
+
rspec-support (3.13.7)
|
|
95
129
|
rubocop (1.84.2)
|
|
96
130
|
json (~> 2.3)
|
|
97
131
|
language_server-protocol (~> 3.17.0.2)
|
|
@@ -111,6 +145,7 @@ GEM
|
|
|
111
145
|
rubocop (>= 1.75.0, < 2.0)
|
|
112
146
|
rubocop-ast (>= 1.47.1, < 2.0)
|
|
113
147
|
ruby-progressbar (1.13.0)
|
|
148
|
+
securerandom (0.4.1)
|
|
114
149
|
simplecov (0.22.0)
|
|
115
150
|
docile (~> 1.1)
|
|
116
151
|
simplecov-html (~> 0.11)
|
|
@@ -132,15 +167,38 @@ GEM
|
|
|
132
167
|
standard-performance (1.9.0)
|
|
133
168
|
lint_roller (~> 1.1)
|
|
134
169
|
rubocop-performance (~> 1.26.0)
|
|
170
|
+
steep (1.10.0)
|
|
171
|
+
activesupport (>= 5.1)
|
|
172
|
+
concurrent-ruby (>= 1.1.10)
|
|
173
|
+
csv (>= 3.0.9)
|
|
174
|
+
fileutils (>= 1.1.0)
|
|
175
|
+
json (>= 2.1.0)
|
|
176
|
+
language_server-protocol (>= 3.17.0.4, < 4.0)
|
|
177
|
+
listen (~> 3.0)
|
|
178
|
+
logger (>= 1.3.0)
|
|
179
|
+
mutex_m (>= 0.3.0)
|
|
180
|
+
parser (>= 3.1)
|
|
181
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
182
|
+
rbs (~> 3.9)
|
|
183
|
+
securerandom (>= 0.1)
|
|
184
|
+
strscan (>= 1.0.0)
|
|
185
|
+
terminal-table (>= 2, < 5)
|
|
186
|
+
uri (>= 0.12.0)
|
|
135
187
|
stringio (3.2.0)
|
|
188
|
+
strscan (3.1.7)
|
|
136
189
|
sys-uname (1.5.0)
|
|
137
190
|
ffi (~> 1.1)
|
|
138
191
|
memoist3 (~> 1.0.0)
|
|
192
|
+
terminal-table (4.0.0)
|
|
193
|
+
unicode-display_width (>= 1.1.1, < 4)
|
|
139
194
|
timecop (0.9.10)
|
|
140
195
|
tsort (0.2.0)
|
|
196
|
+
tzinfo (2.0.6)
|
|
197
|
+
concurrent-ruby (~> 1.0)
|
|
141
198
|
unicode-display_width (3.2.0)
|
|
142
199
|
unicode-emoji (~> 4.1)
|
|
143
200
|
unicode-emoji (4.2.0)
|
|
201
|
+
uri (1.1.1)
|
|
144
202
|
|
|
145
203
|
PLATFORMS
|
|
146
204
|
arm64-darwin-21
|
|
@@ -162,11 +220,12 @@ DEPENDENCIES
|
|
|
162
220
|
markly
|
|
163
221
|
openfeature-sdk!
|
|
164
222
|
rake (~> 13.0)
|
|
165
|
-
rspec (~> 3.
|
|
223
|
+
rspec (~> 3.13.0)
|
|
166
224
|
simplecov (~> 0.22.0)
|
|
167
225
|
simplecov-cobertura (~> 3.0)
|
|
168
226
|
standard
|
|
169
227
|
standard-performance
|
|
228
|
+
steep (~> 1.9)
|
|
170
229
|
timecop (~> 0.9.10)
|
|
171
230
|
|
|
172
231
|
BUNDLED WITH
|
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.
|
|
21
|
-
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.6.
|
|
20
|
+
<a href="https://github.com/open-feature/ruby-sdk/releases/tag/v0.6.5">
|
|
21
|
+
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v0.6.5&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:
|
|
@@ -115,6 +126,7 @@ object = client.fetch_object_value(flag_key: 'object_value', default_value: { na
|
|
|
115
126
|
|
|
116
127
|
[Providers](https://openfeature.dev/docs/reference/concepts/provider) are an abstraction between a flag management system and the OpenFeature SDK.
|
|
117
128
|
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.
|
|
129
|
+
|
|
118
130
|
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
131
|
|
|
120
132
|
Once you've added a provider as a dependency, it can be registered with OpenFeature like this:
|
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,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)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example: OpenFeature integration with Ruby on Rails
|
|
4
|
+
#
|
|
5
|
+
# This file demonstrates how you might integrate OpenFeature into a Rails app.
|
|
6
|
+
# It is not runnable standalone — it shows patterns for use in a Rails context.
|
|
7
|
+
|
|
8
|
+
# config/initializers/openfeature.rb
|
|
9
|
+
#
|
|
10
|
+
# OpenFeature::SDK.configure do |config|
|
|
11
|
+
# config.set_provider(YourProvider.new)
|
|
12
|
+
#
|
|
13
|
+
# # Set global context with server-level info
|
|
14
|
+
# config.evaluation_context = OpenFeature::SDK::EvaluationContext.new(
|
|
15
|
+
# "environment" => Rails.env,
|
|
16
|
+
# "service" => "my-rails-app"
|
|
17
|
+
# )
|
|
18
|
+
#
|
|
19
|
+
# # Use thread-local transaction context for per-request data
|
|
20
|
+
# config.set_transaction_context_propagator(
|
|
21
|
+
# OpenFeature::SDK::ThreadLocalTransactionContextPropagator.new
|
|
22
|
+
# )
|
|
23
|
+
# end
|
|
24
|
+
|
|
25
|
+
# app/middleware/openfeature_context_middleware.rb
|
|
26
|
+
#
|
|
27
|
+
# class OpenFeatureContextMiddleware
|
|
28
|
+
# def initialize(app)
|
|
29
|
+
# @app = app
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# def call(env)
|
|
33
|
+
# request = ActionDispatch::Request.new(env)
|
|
34
|
+
# OpenFeature::SDK.set_transaction_context(
|
|
35
|
+
# OpenFeature::SDK::EvaluationContext.new(
|
|
36
|
+
# targeting_key: request.session[:user_id]&.to_s,
|
|
37
|
+
# "ip" => request.remote_ip,
|
|
38
|
+
# "user_agent" => request.user_agent
|
|
39
|
+
# )
|
|
40
|
+
# )
|
|
41
|
+
# @app.call(env)
|
|
42
|
+
# ensure
|
|
43
|
+
# # Clear context to prevent leakage in threaded servers (e.g. Puma)
|
|
44
|
+
# OpenFeature::SDK.set_transaction_context(nil)
|
|
45
|
+
# end
|
|
46
|
+
# end
|
|
47
|
+
|
|
48
|
+
# app/controllers/application_controller.rb
|
|
49
|
+
#
|
|
50
|
+
# class ApplicationController < ActionController::Base
|
|
51
|
+
# private
|
|
52
|
+
#
|
|
53
|
+
# def feature_client
|
|
54
|
+
# @feature_client ||= OpenFeature::SDK.build_client(domain: "web")
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
# def feature_enabled?(flag_key)
|
|
58
|
+
# feature_client.fetch_boolean_value(flag_key: flag_key, default_value: false)
|
|
59
|
+
# end
|
|
60
|
+
# end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/open_feature/sdk/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "openfeature-sdk"
|
|
7
|
+
spec.version = OpenFeature::SDK::VERSION
|
|
8
|
+
spec.authors = ["OpenFeature Authors"]
|
|
9
|
+
spec.email = ["cncf-openfeature-contributors@lists.cncf.io"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "OpenFeature SDK for Ruby"
|
|
12
|
+
spec.description = "Ruby SDK for the OpenFeature specification, an open standard for feature flag management"
|
|
13
|
+
spec.homepage = "https://github.com/open-feature/ruby-sdk"
|
|
14
|
+
spec.license = "Apache-2.0"
|
|
15
|
+
spec.required_ruby_version = ">= 3.4"
|
|
16
|
+
|
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
18
|
+
spec.metadata["source_code_uri"] = "https://github.com/open-feature/ruby-sdk"
|
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/open-feature/ruby-sdk/blob/main/CHANGELOG.md"
|
|
20
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/open-feature/ruby-sdk/issues"
|
|
21
|
+
spec.metadata["documentation_uri"] = "https://github.com/open-feature/ruby-sdk#readme"
|
|
22
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
23
|
+
|
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
26
|
+
spec.files = Dir.chdir(__dir__) do
|
|
27
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
28
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
spec.bindir = "exe"
|
|
32
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
33
|
+
spec.require_paths = ["lib"]
|
|
34
|
+
end
|