From 2de0d3a3c90d2675f8197fe090500cad4618cf73 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Mon, 25 May 2026 11:07:25 +0200 Subject: [PATCH 1/6] Release 0.6.0: Rails 8.1 + Devise 5 + Ruby 3.3/3.4/4.0 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What & why ---------- Modernizes the supported stack and removes the Rails 8.2 deprecation path: - Add support for Rails 8.1 (new `gemfiles/rails_8.1.gemfile`, CI matrix rows) - Add support for Devise 5 — gemspec widened to `< 6.0`; pinned to `~> 5.0` in the Rails 8.1 gemfile so CI actually exercises it. No source changes needed: the integration uses no APIs removed in Devise 5. - Add Ruby 3.3, 3.4, and 4.0 to the CI matrix; coverage upload moved to the newest Ruby × Rails row. - Replace deprecated `ActiveSupport::Configurable` with plain Ruby attribute accessors. Same public API, no Rails coupling, no Rails 8.2 deprecation warning. Also fixes `Logger.new("/dev/null")` → `Logger.new(File::NULL)`. - Drop the `appraisal` development dependency in favor of hand-maintained `gemfiles/*.gemfile`. CI was already invoking them directly via `BUNDLE_GEMFILE`, so this is purely a tooling cleanup. - Refresh dev `Gemfile` / `Gemfile.lock` against the new stack (railties ~> 8.1, devise ~> 5.0, sqlite3 ~> 2.1, Bundler 2.7.2). - Fix `bin/console` (was `require "castle/devise"` — broken path). - Drop "currently in beta" disclaimer from the README. - Fix two pre-existing standardrb 1.54 violations (ternary parens). Test plan --------- - `bundle exec rake` — 107 examples, 0 failures, 99.0% coverage - `bundle exec standardrb` — clean - `bin/console` — no deprecation warnings, prints version 0.6.0 - CI matrix verifies all 16 Ruby × Rails combinations on push. --- .github/workflows/specs.yml | 4 + Appraisals | 23 -- CHANGELOG.md | 12 +- Gemfile | 7 +- Gemfile.lock | 265 +++++++++--------- README.md | 4 - bin/console | 2 +- castle_devise.gemspec | 4 +- gemfiles/rails_6.0.gemfile | 2 - gemfiles/rails_6.1.gemfile | 2 - gemfiles/rails_7.0.gemfile | 2 - gemfiles/rails_7.1.gemfile | 2 - gemfiles/rails_7.2.gemfile | 2 - gemfiles/rails_8.0.gemfile | 2 - gemfiles/rails_8.1.gemfile | 5 +- lib/castle_devise/configuration.rb | 46 +-- lib/castle_devise/version.rb | 2 +- .../integration/profile_update_spec.rb | 4 +- 18 files changed, 190 insertions(+), 200 deletions(-) delete mode 100644 Appraisals diff --git a/.github/workflows/specs.yml b/.github/workflows/specs.yml index d818479..d2db36e 100644 --- a/.github/workflows/specs.yml +++ b/.github/workflows/specs.yml @@ -35,11 +35,15 @@ jobs: rails: "8.0" - ruby: "3.4" rails: "8.0" + - ruby: "4.0" + rails: "8.0" # Rails 8.1 - ruby: "3.3" rails: "8.1" - ruby: "3.4" rails: "8.1" + - ruby: "4.0" + rails: "8.1" steps: - uses: actions/checkout@v4 - name: Set up Ruby ${{ matrix.ruby }} diff --git a/Appraisals b/Appraisals deleted file mode 100644 index 1fe4f57..0000000 --- a/Appraisals +++ /dev/null @@ -1,23 +0,0 @@ -appraise "rails-6.0" do - gem "railties", "~> 6.0" -end - -appraise "rails-6.1" do - gem "railties", "~> 6.1" -end - -appraise "rails-7.0" do - gem "railties", "~> 7.0" -end - -appraise "rails-7.1" do - gem "railties", "~> 7.1" -end - -appraise "rails-7.2" do - gem "railties", "~> 7.2" -end - -appraise "rails-8.0" do - gem "railties", "~> 8.0" -end diff --git a/CHANGELOG.md b/CHANGELOG.md index ee6dbaa..d43d03d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ## [Unreleased][main] +## [0.6.0] - 2026-05-25 +- Add support for Rails 8.1 +- Add support for Devise 5 +- Add Ruby 3.3, 3.4, and 4.0 to the CI matrix +- Bump minimum required Ruby version to 3.2 +- Replace deprecated `ActiveSupport::Configurable` with plain Ruby attribute accessors (drops the Rails 8.2 deprecation warning) +- Drop `appraisal` development dependency in favor of hand-maintained `gemfiles/*.gemfile` +- Bump development Gemfile to Rails 8.1, Devise 5, sqlite3 ~> 2.1, Bundler 2.7.x + ## [0.5.0] - 2025-06-17 - Throw a warning instead of an error for the `$login.failed` event when an exception is raised - Security fixes and dependency updates @@ -33,7 +42,8 @@ - Initial release -[main]: https://github.com/castle/castle_devise/compare/v0.5.0...HEAD +[main]: https://github.com/castle/castle_devise/compare/v0.6.0...HEAD +[0.6.0]: https://github.com/castle/castle_devise/compare/v0.5.0...v0.6.0 [0.5.0]: https://github.com/castle/castle_devise/compare/v0.4.3...v0.5.0 [0.4.3]: https://github.com/castle/castle_devise/compare/v0.4.2...v0.4.3 [0.4.2]: https://github.com/castle/castle_devise/compare/v0.4.1...v0.4.2 diff --git a/Gemfile b/Gemfile index 955a72e..b6e4d24 100644 --- a/Gemfile +++ b/Gemfile @@ -8,14 +8,13 @@ gemspec gem "actionmailer" gem "activerecord" gem "byebug" -gem "railties", "~> 7.2" +gem "devise", "~> 5.0" +gem "railties", "~> 8.1" gem "rake" gem "rspec" gem "rspec-rails" gem "simplecov" +gem "sqlite3", "~> 2.1" gem "standard" -gem "sqlite3", "~> 1.7" gem "vcr" gem "webmock" -gem "mutex_m" -gem "logger" diff --git a/Gemfile.lock b/Gemfile.lock index 97c101c..b54e9a8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,121 +1,116 @@ PATH remote: . specs: - castle_devise (0.5.0) + castle_devise (0.6.0) activesupport (>= 6.0) castle-rb (>= 7.2, < 9.0) - devise (>= 4.3.0, < 5.0) + devise (>= 4.3.0, < 6.0) GEM remote: https://rubygems.org/ specs: - actionmailer (7.2.3) - actionpack (= 7.2.3) - actionview (= 7.2.3) - activejob (= 7.2.3) - activesupport (= 7.2.3) + actionmailer (8.1.3) + actionpack (= 8.1.3) + actionview (= 8.1.3) + activejob (= 8.1.3) + activesupport (= 8.1.3) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.2.3) - actionview (= 7.2.3) - activesupport (= 7.2.3) - cgi + actionpack (8.1.3) + actionview (= 8.1.3) + activesupport (= 8.1.3) nokogiri (>= 1.8.5) - racc - rack (>= 2.2.4, < 3.3) + rack (>= 2.2.4) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actionview (7.2.3) - activesupport (= 7.2.3) + actionview (8.1.3) + activesupport (= 8.1.3) builder (~> 3.1) - cgi erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.2.3) - activesupport (= 7.2.3) + activejob (8.1.3) + activesupport (= 8.1.3) globalid (>= 0.3.6) - activemodel (7.2.3) - activesupport (= 7.2.3) - activerecord (7.2.3) - activemodel (= 7.2.3) - activesupport (= 7.2.3) + activemodel (8.1.3) + activesupport (= 8.1.3) + activerecord (8.1.3) + activemodel (= 8.1.3) + activesupport (= 8.1.3) timeout (>= 0.4.0) - activesupport (7.2.3) + activesupport (8.1.3) base64 - benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + json logger (>= 1.4.2) minitest (>= 5.1) securerandom (>= 0.3) tzinfo (~> 2.0, >= 2.0.5) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) - appraisal (2.5.0) - bundler - rake - thor (>= 0.14.0) + uri (>= 0.13.1) + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) ast (2.4.3) base64 (0.3.0) - bcrypt (3.1.20) - benchmark (0.4.1) - bigdecimal (3.2.3) + bcrypt (3.1.22) + bigdecimal (4.1.2) builder (3.3.0) - byebug (12.0.0) + byebug (13.0.0) + reline (>= 0.6.0) castle-rb (8.1.0) - cgi (0.5.0) - concurrent-ruby (1.3.5) - connection_pool (2.5.5) - crack (1.0.0) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) + crack (1.0.1) bigdecimal rexml crass (1.0.6) - date (3.4.1) - devise (4.9.4) + date (3.5.1) + devise (5.0.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 4.1.0) + railties (>= 7.0) responders warden (~> 1.2.3) diff-lcs (1.6.2) docile (1.4.1) drb (2.2.3) - erb (5.0.1) + erb (6.0.4) erubi (1.13.1) - globalid (1.2.1) + globalid (1.3.0) activesupport (>= 6.1) - hashdiff (1.2.0) - i18n (1.14.7) + hashdiff (1.2.1) + i18n (1.14.8) concurrent-ruby (~> 1.0) - io-console (0.8.0) - irb (1.15.2) + io-console (0.8.2) + irb (1.18.0) pp (>= 0.6.0) + prism (>= 1.3.0) rdoc (>= 4.0.0) reline (>= 0.4.2) - json (2.12.2) + json (2.19.5) language_server-protocol (3.17.0.5) lint_roller (1.1.0) logger (1.7.0) - loofah (2.24.1) + loofah (2.25.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) - mail (2.8.1) + mail (2.9.0) + logger mini_mime (>= 0.1.1) net-imap net-pop net-smtp mini_mime (1.1.5) - mini_portile2 (2.8.9) - minitest (5.25.5) - mutex_m (0.3.0) - net-imap (0.5.12) + minitest (6.0.6) + drb (~> 2.0) + prism (~> 1.5) + net-imap (0.6.4) date net-protocol net-pop (0.1.2) @@ -124,45 +119,54 @@ GEM timeout net-smtp (0.5.1) net-protocol - nokogiri (1.18.10-aarch64-linux-gnu) + nokogiri (1.19.3-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-aarch64-linux-musl) + racc (~> 1.4) + nokogiri (1.19.3-arm-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-arm-linux-musl) racc (~> 1.4) - nokogiri (1.18.10-arm64-darwin) + nokogiri (1.19.3-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.10-x86_64-darwin) + nokogiri (1.19.3-x86_64-darwin) + racc (~> 1.4) + nokogiri (1.19.3-x86_64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.3-x86_64-linux-musl) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.27.0) - parser (3.3.8.0) + parallel (1.28.0) + parser (3.3.11.1) ast (~> 2.4.1) racc - pp (0.6.2) + pp (0.6.3) prettyprint prettyprint (0.2.0) - prism (1.4.0) - psych (5.2.6) + prism (1.9.0) + psych (5.3.1) date stringio - public_suffix (6.0.2) + public_suffix (7.0.5) racc (1.8.1) - rack (3.1.19) - rack-session (2.1.1) + rack (3.2.6) + rack-session (2.1.2) base64 (>= 0.1.0) rack (>= 3.0.0) rack-test (2.2.0) rack (>= 1.3) - rackup (2.2.1) + rackup (2.3.1) rack (>= 3) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.2) - loofah (~> 2.21) + rails-html-sanitizer (1.7.0) + loofah (~> 2.25) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (7.2.3) - actionpack (= 7.2.3) - activesupport (= 7.2.3) - cgi + railties (8.1.3) + actionpack (= 8.1.3) + activesupport (= 8.1.3) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -170,39 +174,40 @@ GEM tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.3.0) - rdoc (6.14.0) + rake (13.4.2) + rdoc (7.2.0) erb psych (>= 4.0.0) - regexp_parser (2.10.0) - reline (0.6.1) + tsort + regexp_parser (2.12.0) + reline (0.6.3) io-console (~> 0.5) - responders (3.1.1) - actionpack (>= 5.2) - railties (>= 5.2) - rexml (3.4.1) - rspec (3.13.1) + responders (3.2.0) + actionpack (>= 7.0) + railties (>= 7.0) + rexml (3.4.4) + rspec (3.13.2) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) rspec-mocks (~> 3.13.0) - rspec-core (3.13.4) + rspec-core (3.13.6) rspec-support (~> 3.13.0) rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-mocks (3.13.5) + rspec-mocks (3.13.8) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (8.0.0) + rspec-rails (8.0.4) actionpack (>= 7.2) activesupport (>= 7.2) railties (>= 7.2) - rspec-core (~> 3.13) - rspec-expectations (~> 3.13) - rspec-mocks (~> 3.13) - rspec-support (~> 3.13) - rspec-support (3.13.4) - rubocop (1.75.8) + rspec-core (>= 3.13.0, < 5.0.0) + rspec-expectations (>= 3.13.0, < 5.0.0) + rspec-mocks (>= 3.13.0, < 5.0.0) + rspec-support (>= 3.13.0, < 5.0.0) + rspec-support (3.13.7) + rubocop (1.84.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -210,87 +215,89 @@ GEM parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.44.0, < 2.0) + rubocop-ast (>= 1.49.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.45.1) + rubocop-ast (1.49.1) parser (>= 3.3.7.2) - prism (~> 1.4) - rubocop-performance (1.25.0) + prism (~> 1.7) + rubocop-performance (1.26.1) lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) - rubocop-ast (>= 1.38.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (1.13.0) securerandom (0.4.1) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-html (0.13.1) + simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) - sqlite3 (1.7.3) - mini_portile2 (~> 2.8.0) - sqlite3 (1.7.3-aarch64-linux) - sqlite3 (1.7.3-arm64-darwin) - sqlite3 (1.7.3-x86_64-darwin) - standard (1.50.0) + sqlite3 (2.9.4-aarch64-linux-gnu) + sqlite3 (2.9.4-aarch64-linux-musl) + sqlite3 (2.9.4-arm-linux-gnu) + sqlite3 (2.9.4-arm-linux-musl) + sqlite3 (2.9.4-arm64-darwin) + sqlite3 (2.9.4-x86_64-darwin) + sqlite3 (2.9.4-x86_64-linux-gnu) + sqlite3 (2.9.4-x86_64-linux-musl) + standard (1.54.0) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.0) - rubocop (~> 1.75.5) + rubocop (~> 1.84.0) standard-custom (~> 1.0.0) standard-performance (~> 1.8) standard-custom (1.0.2) lint_roller (~> 1.0) rubocop (~> 1.50) - standard-performance (1.8.0) + standard-performance (1.9.0) lint_roller (~> 1.1) - rubocop-performance (~> 1.25.0) - stringio (3.1.7) - thor (1.3.2) - timeout (0.4.4) + rubocop-performance (~> 1.26.0) + stringio (3.2.0) + thor (1.5.0) + timeout (0.6.1) tsort (0.2.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (3.1.4) - unicode-emoji (~> 4.0, >= 4.0.4) - unicode-emoji (4.0.4) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) + uri (1.1.1) useragent (0.16.11) - vcr (6.3.1) - base64 + vcr (6.4.0) warden (1.2.9) rack (>= 2.0.9) - webmock (3.25.1) + webmock (3.26.2) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - zeitwerk (2.7.3) + zeitwerk (2.8.2) PLATFORMS - aarch64-linux - arm64-darwin-21 - arm64-darwin-24 - x86_64-darwin-18 - x86_64-darwin-19 - x86_64-darwin-20 - x86_64-darwin-22 + aarch64-linux-gnu + aarch64-linux-musl + arm-linux-gnu + arm-linux-musl + arm64-darwin + x86_64-darwin + x86_64-linux-gnu + x86_64-linux-musl DEPENDENCIES actionmailer activerecord - appraisal (~> 2.5.0) byebug castle_devise! - logger - mutex_m - railties (~> 7.2) + devise (~> 5.0) + railties (~> 8.1) rake rspec rspec-rails simplecov - sqlite3 (~> 1.7) + sqlite3 (~> 2.1) standard vcr webmock BUNDLED WITH - 2.6.9 + 2.7.2 diff --git a/README.md b/README.md index 6ca5c1c..361df0d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,5 @@ [![Gem Version](https://badge.fury.io/rb/castle_devise.svg)](https://badge.fury.io/rb/castle_devise) -**Disclaimer:** CastleDevise is currently in beta. There might be some upcoming breaking changes to the gem before we stabilize the API. - ---- - # CastleDevise CastleDevise is a [Devise](https://github.com/heartcombo/devise) plugin that integrates [Castle](https://castle.io). diff --git a/bin/console b/bin/console index d778b90..7d2320f 100755 --- a/bin/console +++ b/bin/console @@ -2,7 +2,7 @@ # frozen_string_literal: true require "bundler/setup" -require "castle/devise" +require "castle_devise" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. diff --git a/castle_devise.gemspec b/castle_devise.gemspec index c653007..bc0f041 100644 --- a/castle_devise.gemspec +++ b/castle_devise.gemspec @@ -29,7 +29,5 @@ Gem::Specification.new do |spec| spec.add_dependency "activesupport", ">= 6.0" spec.add_dependency "castle-rb", ">= 7.2", "< 9.0" - spec.add_dependency "devise", ">= 4.3.0", "< 5.0" - - spec.add_development_dependency "appraisal", "~> 2.5.0" + spec.add_dependency "devise", ">= 4.3.0", "< 6.0" end diff --git a/gemfiles/rails_6.0.gemfile b/gemfiles/rails_6.0.gemfile index 02475ce..fecc541 100644 --- a/gemfiles/rails_6.0.gemfile +++ b/gemfiles/rails_6.0.gemfile @@ -1,5 +1,3 @@ -# This file was generated by Appraisal - source "https://rubygems.org" gem "actionmailer" diff --git a/gemfiles/rails_6.1.gemfile b/gemfiles/rails_6.1.gemfile index aa24e9a..b3c29d7 100644 --- a/gemfiles/rails_6.1.gemfile +++ b/gemfiles/rails_6.1.gemfile @@ -1,5 +1,3 @@ -# This file was generated by Appraisal - source "https://rubygems.org" gem "actionmailer" diff --git a/gemfiles/rails_7.0.gemfile b/gemfiles/rails_7.0.gemfile index 5255342..8a9d966 100644 --- a/gemfiles/rails_7.0.gemfile +++ b/gemfiles/rails_7.0.gemfile @@ -1,5 +1,3 @@ -# This file was generated by Appraisal - source "https://rubygems.org" gem "actionmailer" diff --git a/gemfiles/rails_7.1.gemfile b/gemfiles/rails_7.1.gemfile index 49f6e0c..a0b3173 100644 --- a/gemfiles/rails_7.1.gemfile +++ b/gemfiles/rails_7.1.gemfile @@ -1,5 +1,3 @@ -# This file was generated by Appraisal - source "https://rubygems.org" gem "actionmailer" diff --git a/gemfiles/rails_7.2.gemfile b/gemfiles/rails_7.2.gemfile index 953124a..4a56e56 100644 --- a/gemfiles/rails_7.2.gemfile +++ b/gemfiles/rails_7.2.gemfile @@ -1,5 +1,3 @@ -# This file was generated by Appraisal - source "https://rubygems.org" gem "actionmailer" diff --git a/gemfiles/rails_8.0.gemfile b/gemfiles/rails_8.0.gemfile index 2e6436b..6250e65 100644 --- a/gemfiles/rails_8.0.gemfile +++ b/gemfiles/rails_8.0.gemfile @@ -1,5 +1,3 @@ -# This file was generated by Appraisal - source "https://rubygems.org" gem "actionmailer" diff --git a/gemfiles/rails_8.1.gemfile b/gemfiles/rails_8.1.gemfile index 49c6310..9413c8e 100644 --- a/gemfiles/rails_8.1.gemfile +++ b/gemfiles/rails_8.1.gemfile @@ -1,10 +1,9 @@ -# This file was generated by Appraisal - source "https://rubygems.org" gem "actionmailer" gem "activerecord" gem "byebug" +gem "devise", "~> 5.0" gem "railties", "~> 8.1.0" gem "rake" gem "rspec" @@ -14,7 +13,5 @@ gem "standard" gem "sqlite3" gem "vcr" gem "webmock" -gem "mutex_m" -gem "logger" gemspec path: "../" diff --git a/lib/castle_devise/configuration.rb b/lib/castle_devise/configuration.rb index 98fdf25..2545b81 100644 --- a/lib/castle_devise/configuration.rb +++ b/lib/castle_devise/configuration.rb @@ -1,20 +1,20 @@ # frozen_string_literal: true -require "active_support/configurable" require "logger" module CastleDevise - # Configuration object using {ActiveSupport::Configurable} + # Plain Ruby configuration object for CastleDevise. + # + # Previously this used +ActiveSupport::Configurable+, which is deprecated + # and slated for removal in Rails 8.2. class Configuration - include ActiveSupport::Configurable - # @!attribute api_secret # @return [String] Your API secret - config_accessor(:api_secret) + attr_accessor :api_secret # @!attribute app_id # @return [String] Your Castle App ID - config_accessor(:app_id) + attr_accessor :app_id # @!attribute monitoring_mode # When CastleDevise is in monitoring mode, it sends requests to Castle @@ -25,27 +25,41 @@ class Configuration # from logging in/registering. # # @return [true, false] whether to act on deny requests or not - config_accessor(:monitoring_mode) { false } - - # @!attribute logger - # @return [Logger] A Logger instance. You might want to use Rails.logger here. - config_accessor(:logger) { Logger.new("/dev/null") } + attr_accessor :monitoring_mode # @!attribute before_request_hooks # @return [Array] Array of procs that will get called before a request to the Castle API - config_accessor(:before_request_hooks) { [] } + attr_accessor :before_request_hooks # @!attribute after_request_hooks # @return [Array] Array of procs that will get called after a request to the Castle API - config_accessor(:after_request_hooks) { [] } + attr_accessor :after_request_hooks + + attr_writer :logger, :castle_sdk_facade_class, :castle_client + + def initialize + @monitoring_mode = false + @before_request_hooks = [] + @after_request_hooks = [] + end + + # @!attribute logger + # @return [Logger] A Logger instance. You might want to use Rails.logger here. + def logger + @logger ||= Logger.new(File::NULL) + end # @!attribute castle_sdk_facade_class # @return [Class] Castle API implementation - config_accessor(:castle_sdk_facade_class) { ::CastleDevise::SdkFacade } + def castle_sdk_facade_class + @castle_sdk_facade_class ||= ::CastleDevise::SdkFacade + end # @!attribute castle_client - # @return [Class] Castle SDK client - config_accessor(:castle_client) { ::Castle::Client.new } + # @return [Castle::Client] Castle SDK client + def castle_client + @castle_client ||= ::Castle::Client.new + end # Adds a new before_request hook # @param blk [Proc] diff --git a/lib/castle_devise/version.rb b/lib/castle_devise/version.rb index adea5aa..4aaa8c5 100644 --- a/lib/castle_devise/version.rb +++ b/lib/castle_devise/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module CastleDevise - VERSION = "0.5.0" + VERSION = "0.6.0" end diff --git a/spec/castle_devise/integration/profile_update_spec.rb b/spec/castle_devise/integration/profile_update_spec.rb index 7e930ac..6f3b9be 100644 --- a/spec/castle_devise/integration/profile_update_spec.rb +++ b/spec/castle_devise/integration/profile_update_spec.rb @@ -129,7 +129,7 @@ call_risk_count = 0 allow(facade).to receive(:risk) do call_risk_count += 1 - call_risk_count >= 2 ? raise(Castle::InvalidParametersError) : login_castle_risk_response + (call_risk_count >= 2) ? raise(Castle::InvalidParametersError) : login_castle_risk_response end allow(CastleDevise.logger).to receive(:warn) @@ -151,7 +151,7 @@ call_risk_count = 0 allow(facade).to receive(:risk) do call_risk_count += 1 - call_risk_count >= 2 ? raise(Castle::Error) : login_castle_risk_response + (call_risk_count >= 2) ? raise(Castle::Error) : login_castle_risk_response end allow(CastleDevise.logger).to receive(:error) From a692ff8fa8b21df60f8dc94519165f973698a2a4 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Mon, 25 May 2026 14:39:47 +0200 Subject: [PATCH 2/6] chore: clean up vestigial dummy app files - Remove `spec/dummy_app/.ruby-version` (stale 2.6.5 from 2019; the actual Ruby comes from CI / asdf today). - Remove `spec/dummy_app/config/spring.rb` (Spring was removed from the Rails default stack in 7.0; the file is loaded by nothing). - Remove `spec/dummy_app/app/javascript/packs/application.js` (Webpacker convention, deprecated since Rails 7; we don't compile assets). - Untrack accidentally-committed `spec/dummy_app/log/development.log` and `spec/dummy_app/tmp/development_secret.txt`. They've been in `.gitignore` for ages but predated the rule. - Bump `config.load_defaults` from a hard-coded `5.2` to `Rails::VERSION::STRING.to_f`, so each appraisal exercises that Rails version's own framework defaults instead of the long-EOL 5.2 ones. --- spec/dummy_app/.ruby-version | 1 - .../dummy_app/app/javascript/packs/application.js | 15 --------------- spec/dummy_app/config/application.rb | 5 +++-- spec/dummy_app/config/spring.rb | 6 ------ spec/dummy_app/log/development.log | 0 spec/dummy_app/tmp/development_secret.txt | 1 - 6 files changed, 3 insertions(+), 25 deletions(-) delete mode 100644 spec/dummy_app/.ruby-version delete mode 100644 spec/dummy_app/app/javascript/packs/application.js delete mode 100644 spec/dummy_app/config/spring.rb delete mode 100644 spec/dummy_app/log/development.log delete mode 100644 spec/dummy_app/tmp/development_secret.txt diff --git a/spec/dummy_app/.ruby-version b/spec/dummy_app/.ruby-version deleted file mode 100644 index 57cf282..0000000 --- a/spec/dummy_app/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -2.6.5 diff --git a/spec/dummy_app/app/javascript/packs/application.js b/spec/dummy_app/app/javascript/packs/application.js deleted file mode 100644 index 67ce467..0000000 --- a/spec/dummy_app/app/javascript/packs/application.js +++ /dev/null @@ -1,15 +0,0 @@ -// This is a manifest file that'll be compiled into application.js, which will include all the files -// listed below. -// -// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, -// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. -// -// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the -// compiled file. JavaScript code in this file should be added after the last require_* statement. -// -// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details -// about supported directives. -// -//= require rails-ujs -//= require activestorage -//= require_tree . diff --git a/spec/dummy_app/config/application.rb b/spec/dummy_app/config/application.rb index 105dd21..0f17b32 100644 --- a/spec/dummy_app/config/application.rb +++ b/spec/dummy_app/config/application.rb @@ -6,8 +6,9 @@ module DummyApp class Application < Rails::Application - # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.2 + # Load defaults for the Rails version we're running against. This keeps the dummy + # app exercising each appraisal gemfile against that Rails version's own defaults. + config.load_defaults Rails::VERSION::STRING.to_f # Settings in config/environments/* take precedence over those specified here. # Application configuration can go into files in config/initializers diff --git a/spec/dummy_app/config/spring.rb b/spec/dummy_app/config/spring.rb deleted file mode 100644 index db5bf13..0000000 --- a/spec/dummy_app/config/spring.rb +++ /dev/null @@ -1,6 +0,0 @@ -Spring.watch( - ".ruby-version", - ".rbenv-vars", - "tmp/restart.txt", - "tmp/caching-dev.txt" -) diff --git a/spec/dummy_app/log/development.log b/spec/dummy_app/log/development.log deleted file mode 100644 index e69de29..0000000 diff --git a/spec/dummy_app/tmp/development_secret.txt b/spec/dummy_app/tmp/development_secret.txt deleted file mode 100644 index 3083eb4..0000000 --- a/spec/dummy_app/tmp/development_secret.txt +++ /dev/null @@ -1 +0,0 @@ -42b8cc9a42dc828fc51c7b3ea484e1618ee282ddb7a52dde03b25636aa53080254fd7ad38f1eba180dc71b59471652be21d491d1c01dbc45584a512e6eba5b00 \ No newline at end of file From bb7365f6e3baa5934aa1399b191200e5452d2814 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Mon, 25 May 2026 14:39:57 +0200 Subject: [PATCH 3/6] ci: modernize lint workflow to use bundled standardrb The old workflow used: - `actions/checkout@v1` (Node 12-based; deprecated by GitHub) - `SennaLabs/action-standardrb@v0.0.3` (third-party, last released 2020) pinning `standardrb 1.1.6` - a `sudo chown` workaround required by the third-party action's container The repo's own `Gemfile.lock` is on `standard 1.54.0`, so CI was lint-checking the code against a ruleset five years older than what we use locally. Replace with the standard pattern: checkout, setup Ruby with `bundler-cache`, then `bundle exec standardrb`. This guarantees CI lints against the same `standard` version that's declared in the dev Gemfile, on supported runners. --- .github/workflows/lint.yml | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4f01d81..edf64dc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,21 +1,18 @@ name: Lint -on: [pull_request] +on: + pull_request: + push: + branches: [main] jobs: standardrb: - name: runner / standardrb + name: standardrb runs-on: ubuntu-latest steps: - - name: Check out code - uses: actions/checkout@v1 - - name: Give permissions - run: | - sudo chown -R root:root $GITHUB_WORKSPACE - - name: standardrb - uses: SennaLabs/action-standardrb@v0.0.3 + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 with: - github_token: ${{ secrets.github_token }} - reporter: github-pr-review # Default is github-pr-check - rubocop_version: 1.1.6 # note: this actually refers to standardb version, not Rubocop - rubocop_flags: --format progress + ruby-version: "3.4" + bundler-cache: true + - run: bundle exec standardrb --format progress From 7fe69fdcf27e86dba6f2c0bd08fbb09188f578d3 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Tue, 26 May 2026 11:06:25 +0200 Subject: [PATCH 4/6] Allow castle-rb 9.x Widens the gemspec dependency from `>= 7.2, < 9.0` to `>= 7.2, < 10.0` so the upcoming castle-rb 9.0 release (and 9.1 once it ships with the Event endpoint) can be used as a runtime dependency. castle_devise uses only the following castle-rb surface: - `Castle::Client.new`, `#risk`, `#filter`, `#log` - `Castle.api_secret=`, `Castle.config.logger=` - `Castle::Context::Prepare` - `Castle::Error`, `Castle::InvalidParametersError`, `Castle::InvalidRequestTokenError` All of these are preserved in castle-rb 9.0 (which removes only the long-legacy Track/Authenticate/Device/Impersonation endpoints). Verified locally: 107 examples, 0 failures, 99.01% coverage when bundling against the in-flight castle-rb 9.0 release branch. --- CHANGELOG.md | 5 +++++ Gemfile.lock | 2 +- castle_devise.gemspec | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d43d03d..1a25010 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ ## [0.6.0] - 2026-05-25 - Add support for Rails 8.1 - Add support for Devise 5 +- Allow `castle-rb` 9.x (constraint widened to `>= 7.2, < 10.0`); verified + against the upcoming 9.0 release — castle_devise uses only the + `#risk` / `#filter` / `#log` Client APIs and the `Castle::Error` / + `InvalidParametersError` / `InvalidRequestTokenError` classes, all of + which remain in 9.0. - Add Ruby 3.3, 3.4, and 4.0 to the CI matrix - Bump minimum required Ruby version to 3.2 - Replace deprecated `ActiveSupport::Configurable` with plain Ruby attribute accessors (drops the Rails 8.2 deprecation warning) diff --git a/Gemfile.lock b/Gemfile.lock index b54e9a8..23c7a2b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,7 +3,7 @@ PATH specs: castle_devise (0.6.0) activesupport (>= 6.0) - castle-rb (>= 7.2, < 9.0) + castle-rb (>= 7.2, < 10.0) devise (>= 4.3.0, < 6.0) GEM diff --git a/castle_devise.gemspec b/castle_devise.gemspec index bc0f041..d010c01 100644 --- a/castle_devise.gemspec +++ b/castle_devise.gemspec @@ -28,6 +28,6 @@ Gem::Specification.new do |spec| spec.require_paths = ["lib"] spec.add_dependency "activesupport", ">= 6.0" - spec.add_dependency "castle-rb", ">= 7.2", "< 9.0" + spec.add_dependency "castle-rb", ">= 7.2", "< 10.0" spec.add_dependency "devise", ">= 4.3.0", "< 6.0" end From 68fade8dcf8a9b297cedefe97c9bddca0e72f275 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Tue, 26 May 2026 11:19:59 +0200 Subject: [PATCH 5/6] chore: point dev Gemfile at castle-ruby develop branch Track castle-rb upstream `develop` in dev/test. The gemspec dependency stays on rubygems (`>= 7.2, < 10.0`) so end users are unaffected. Verified: 107 examples, 0 failures. --- Gemfile | 2 ++ Gemfile.lock | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index b6e4d24..6809524 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,8 @@ gemspec gem "actionmailer" gem "activerecord" +# Dev/test: track castle-rb upstream develop. Gemspec uses rubygems. +gem "castle-rb", github: "castle/castle-ruby", branch: "develop" gem "byebug" gem "devise", "~> 5.0" gem "railties", "~> 8.1" diff --git a/Gemfile.lock b/Gemfile.lock index 23c7a2b..e2f4ff7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,11 @@ +GIT + remote: https://github.com/castle/castle-ruby.git + revision: 9dce01b248cc10c3e1321c417bd9b5a24aabd5bf + branch: develop + specs: + castle-rb (9.0.0) + base64 (~> 0.2) + PATH remote: . specs: @@ -63,7 +71,6 @@ GEM builder (3.3.0) byebug (13.0.0) reline (>= 0.6.0) - castle-rb (8.1.0) concurrent-ruby (1.3.6) connection_pool (3.0.2) crack (1.0.1) @@ -287,6 +294,7 @@ DEPENDENCIES actionmailer activerecord byebug + castle-rb! castle_devise! devise (~> 5.0) railties (~> 8.1) From 839a2b3517dca566b465ab955555462b963e9f35 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Tue, 26 May 2026 11:19:59 +0200 Subject: [PATCH 6/6] chore: add .standard.yml ignoring bundler vendor directories RuboCop's default `Exclude` only covers top-level `vendor/**/*`, so when contributors run gemfile-specific bundles the resulting `gemfiles/vendor/ bundle/` tree leaks into `bundle exec standardrb` output. Ignore both `vendor/**/*` and `gemfiles/vendor/**/*` so local lint mirrors CI. --- .standard.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .standard.yml diff --git a/.standard.yml b/.standard.yml new file mode 100644 index 0000000..50ffdc2 --- /dev/null +++ b/.standard.yml @@ -0,0 +1,3 @@ +ignore: + - "gemfiles/vendor/**/*" + - "vendor/**/*"