Skip to content

Commit 506e999

Browse files
josecolellaclaude
andauthored
feat: add RBS type signatures with Steep type checking (#251)
Signed-off-by: Jose Colella <jose.colella@gusto.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3f339dc commit 506e999

40 files changed

Lines changed: 1030 additions & 1 deletion

.github/workflows/main.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ on:
44
- push
55
- pull_request
66

7+
permissions:
8+
contents: read
9+
710
jobs:
811
rspec:
912
runs-on: ${{ matrix.os }}
@@ -64,6 +67,17 @@ jobs:
6467
- run: bundle install
6568
- name: Cucumber
6669
run: bundle exec cucumber
70+
steep:
71+
runs-on: ubuntu-latest
72+
name: Type Check
73+
steps:
74+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
75+
- uses: ruby/setup-ruby@v1
76+
with:
77+
ruby-version: "3.4.9"
78+
- run: bundle install
79+
- run: bundle exec rbs collection install
80+
- run: bundle exec steep check
6781
security:
6882
runs-on: ubuntu-latest
6983
name: Security Audit
@@ -79,7 +93,7 @@ jobs:
7993
status:
8094
name: CI Status
8195
runs-on: ubuntu-latest
82-
needs: [rspec, standard, cucumber, security]
96+
needs: [rspec, standard, cucumber, security, steep]
8397
if: always()
8498
steps:
8599
- name: Successful CI

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ Gemfile.lock
1717

1818
# Claude plans
1919
docs/plans/
20+
21+
# RBS collection cache
22+
.gem_rbs_collection/

CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ This is the official OpenFeature SDK for Ruby — an implementation of the [Open
88

99
## Commands
1010

11+
- **Install dependencies:** `bundle install`
1112
- **Run all tests:** `bundle exec rspec`
1213
- **Run a single test file:** `bundle exec rspec spec/open_feature/sdk/client_spec.rb`
1314
- **Run a specific test by line:** `bundle exec rspec spec/open_feature/sdk/client_spec.rb:43`
1415
- **Lint:** `bundle exec standardrb`
1516
- **Lint with autofix:** `bundle exec standardrb --fix`
17+
- **Type check:** `bundle exec steep check`
1618
- **Default rake (tests + lint):** `bundle exec rake`
1719

1820
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
4749

4850
- All `.rb` files must have `# frozen_string_literal: true` as the first line.
4951
- 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.
5053
- Always sign git commits using the `-S` flag.
5154
- 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.

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ group :development, :test do
1414
gem "standard-performance"
1515
gem "simplecov", "~> 0.22.0"
1616
gem "simplecov-cobertura", "~> 3.0"
17+
gem "steep", "~> 1.9"
1718
gem "timecop", "~> 0.9.10"
1819
end
1920

Gemfile.lock

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,26 @@ PATH
66
GEM
77
remote: https://rubygems.org/
88
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)
922
ast (2.4.3)
1023
base64 (0.3.0)
1124
bigdecimal (4.0.1)
1225
builder (3.3.0)
26+
concurrent-ruby (1.3.6)
27+
connection_pool (3.0.2)
28+
csv (3.3.5)
1329
cucumber (10.2.0)
1430
base64 (~> 0.2)
1531
builder (~> 3.2)
@@ -41,8 +57,12 @@ GEM
4157
reline (>= 0.3.8)
4258
diff-lcs (1.6.2)
4359
docile (1.4.1)
60+
drb (2.2.3)
4461
erb (6.0.2)
4562
ffi (1.17.3)
63+
fileutils (1.8.0)
64+
i18n (1.14.8)
65+
concurrent-ruby (~> 1.0)
4666
io-console (0.8.2)
4767
irb (1.17.0)
4868
pp (>= 0.6.0)
@@ -52,11 +72,19 @@ GEM
5272
json (2.18.1)
5373
language_server-protocol (3.17.0.5)
5474
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)
5579
logger (1.7.0)
5680
markly (0.15.2)
5781
memoist3 (1.0.0)
5882
mini_mime (1.1.5)
83+
minitest (6.0.2)
84+
drb (~> 2.0)
85+
prism (~> 1.5)
5986
multi_test (1.1.0)
87+
mutex_m (0.3.0)
6088
parallel (1.27.0)
6189
parser (3.3.10.2)
6290
ast (~> 2.4.1)
@@ -71,6 +99,12 @@ GEM
7199
racc (1.8.1)
72100
rainbow (3.1.1)
73101
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
74108
rdoc (7.2.0)
75109
erb
76110
psych (>= 4.0.0)
@@ -111,6 +145,7 @@ GEM
111145
rubocop (>= 1.75.0, < 2.0)
112146
rubocop-ast (>= 1.47.1, < 2.0)
113147
ruby-progressbar (1.13.0)
148+
securerandom (0.4.1)
114149
simplecov (0.22.0)
115150
docile (~> 1.1)
116151
simplecov-html (~> 0.11)
@@ -132,15 +167,38 @@ GEM
132167
standard-performance (1.9.0)
133168
lint_roller (~> 1.1)
134169
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)
135187
stringio (3.2.0)
188+
strscan (3.1.7)
136189
sys-uname (1.5.0)
137190
ffi (~> 1.1)
138191
memoist3 (~> 1.0.0)
192+
terminal-table (4.0.0)
193+
unicode-display_width (>= 1.1.1, < 4)
139194
timecop (0.9.10)
140195
tsort (0.2.0)
196+
tzinfo (2.0.6)
197+
concurrent-ruby (~> 1.0)
141198
unicode-display_width (3.2.0)
142199
unicode-emoji (~> 4.1)
143200
unicode-emoji (4.2.0)
201+
uri (1.1.1)
144202

145203
PLATFORMS
146204
arm64-darwin-21
@@ -167,6 +225,7 @@ DEPENDENCIES
167225
simplecov-cobertura (~> 3.0)
168226
standard
169227
standard-performance
228+
steep (~> 1.9)
170229
timecop (~> 0.9.10)
171230

172231
BUNDLED WITH

Rakefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,11 @@ task :cucumber do
1919
sh "bundle exec cucumber"
2020
end
2121

22+
begin
23+
require "steep/rake_task"
24+
Steep::RakeTask.new
25+
rescue LoadError
26+
# Steep not available
27+
end
28+
2229
task default: %i[spec standard]

Steepfile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 commit comments

Comments
 (0)