From 3b46a6cf0a1298fe21133b46b11136bb81b4fc89 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Tue, 26 May 2026 11:31:33 +0200 Subject: [PATCH 1/2] Bumps 2026-05-26 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update gems via `bundle update`: rack 3.1.19 → 3.2.6, rake 13.2.1 → 13.4.2, rspec 3.13.0 → 3.13.2, rspec-core/-mocks/-support, simplecov-html, timecop 0.9.10 → 0.9.11, diff-lcs 1.5.1 → 1.6.2. - Bump Ruby to 3.4.9 (security: zlib CVE-2026-27820). - Bump Node.js to 24.16.0 in `.tool-versions`. Verified locally: `bundle exec rspec` (428 examples, 0 failures) and `bundle exec rubocop` (no offenses). --- .ruby-version | 2 +- .tool-versions | 4 ++-- CHANGELOG.md | 4 ++++ Gemfile.lock | 18 +++++++++--------- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.ruby-version b/.ruby-version index 1cf8253..7bcbb38 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.4.6 +3.4.9 diff --git a/.tool-versions b/.tool-versions index cc2bdd4..52b8227 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -ruby 3.4.6 -nodejs 24.14.1 +ruby 3.4.9 +nodejs 24.16.0 yarn 1.22.22 diff --git a/CHANGELOG.md b/CHANGELOG.md index d7865e2..b0c5c70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## master +- Bump dependencies (rack 3.1.19 → 3.2.6, rake, rspec-\*, timecop, simplecov-html, diff-lcs) +- Bump Ruby to 3.4.9 (zlib CVE-2026-27820) +- Bump Node.js to 24.16.0 in `.tool-versions` + ## 9.0.0 **BREAKING CHANGES:** diff --git a/Gemfile.lock b/Gemfile.lock index fbf9523..11962b1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -19,7 +19,7 @@ GEM debug (1.11.1) irb (~> 1.10) reline (>= 0.3.8) - diff-lcs (1.5.1) + diff-lcs (1.6.2) docile (1.4.1) erb (6.0.4) hashdiff (1.2.1) @@ -45,9 +45,9 @@ GEM stringio public_suffix (7.0.5) racc (1.8.1) - rack (3.1.19) + rack (3.2.6) rainbow (3.1.1) - rake (13.2.1) + rake (13.4.2) rdoc (7.2.0) erb psych (>= 4.0.0) @@ -56,19 +56,19 @@ GEM reline (0.6.3) io-console (~> 0.5) rexml (3.4.4) - rspec (3.13.0) + 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-support (3.13.1) + rspec-support (3.13.7) rubocop (1.86.2) json (~> 2.3) language_server-protocol (~> 3.17.0.2) @@ -98,10 +98,10 @@ GEM 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) stringio (3.2.0) - timecop (0.9.10) + timecop (0.9.11) tsort (0.2.0) unicode-display_width (3.2.0) unicode-emoji (~> 4.1) From 2c4e88e593b3bbbd3230b816119a9f374f91d040 Mon Sep 17 00:00:00 2001 From: Bartosz Date: Tue, 26 May 2026 11:42:31 +0200 Subject: [PATCH 2/2] Repair yarn format:check and align rubocop with prettier-ruby `@prettier/plugin-ruby` 4.x spawns a Ruby server that requires `syntax_tree`, which was never added to the Gemfile, so `yarn format:check` has been failing with `LoadError: cannot load such file -- syntax_tree`. - Add `syntax_tree` to the dev group of the Gemfile. - Run `yarn prettier --write .` against the 11 spec files that had drifted. - Disable two rubocop cops that conflict with prettier-ruby's output so CI stays green: - `Layout/SpaceInsideHashLiteralBraces` (prettier breaks empty hashes onto two lines, which rubocop reads as space inside empty braces) - `Style/EmptyMethod` (prettier expands `def foo; end` to `def foo\nend`) Verified: `bundle exec rubocop`, `yarn format:check`, `bundle exec rspec` (428 examples, 0 failures) all pass. --- .rubocop.yml | 10 ++++++++ CHANGELOG.md | 1 + Gemfile | 1 + Gemfile.lock | 4 +++ castle-rb.gemspec | 2 +- .../rails/support/home_controller.rb | 25 ++++++++----------- spec/lib/castle/api/filter_spec.rb | 9 +------ spec/lib/castle/api/log_spec.rb | 11 +++----- spec/lib/castle/api/risk_spec.rb | 12 +++------ spec/lib/castle/client_spec.rb | 3 ++- spec/lib/castle/core/process_webhook_spec.rb | 18 ++++++++----- spec/lib/castle/core/send_request_spec.rb | 8 ++---- spec/lib/castle/logger_spec.rb | 3 ++- spec/lib/castle/webhooks/verify_spec.rb | 18 ++++++++----- spec/spec_helper.rb | 4 +-- 15 files changed, 68 insertions(+), 61 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 0a0acb0..1769177 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -29,6 +29,11 @@ Layout/LineLength: Layout/MultilineMethodCallIndentation: EnforcedStyle: indented_relative_to_receiver +# Hash brace spacing is handled by prettier-ruby (@prettier/plugin-ruby), which +# breaks empty hashes onto two lines and would otherwise conflict with rubocop. +Layout/SpaceInsideHashLiteralBraces: + Enabled: false + Lint/AmbiguousBlockAssociation: AllowedMethods: [change] @@ -96,6 +101,11 @@ Style/Documentation: Style/DoubleNegation: Enabled: false +# prettier-ruby always expands empty methods to `def foo\nend`. Disable +# rubocop's preference for `def foo; end` so the two stay aligned. +Style/EmptyMethod: + Enabled: false + Style/FormatStringToken: Enabled: false diff --git a/CHANGELOG.md b/CHANGELOG.md index b0c5c70..fe7a9c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Bump dependencies (rack 3.1.19 → 3.2.6, rake, rspec-\*, timecop, simplecov-html, diff-lcs) - Bump Ruby to 3.4.9 (zlib CVE-2026-27820) - Bump Node.js to 24.16.0 in `.tool-versions` +- Repair `yarn format:check`: add `syntax_tree` to the dev group (required by `@prettier/plugin-ruby` 4.x), reformat 11 spec files, and disable rubocop cops that conflict with prettier-ruby (`Layout/SpaceInsideHashLiteralBraces`, `Style/EmptyMethod`) ## 9.0.0 diff --git a/Gemfile b/Gemfile index 9c0b5c4..3a3f17e 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ group :development do gem 'rubocop-performance', require: false gem 'rubocop-rake', require: false gem 'rubocop-rspec', require: false + gem 'syntax_tree', require: false end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 11962b1..4125259 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -38,6 +38,7 @@ GEM racc pp (0.6.3) prettyprint + prettier_print (1.2.1) prettyprint (0.2.0) prism (1.9.0) psych (5.3.1) @@ -101,6 +102,8 @@ GEM simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) stringio (3.2.0) + syntax_tree (6.3.0) + prettier_print (>= 1.2.0) timecop (0.9.11) tsort (0.2.0) unicode-display_width (3.2.0) @@ -125,6 +128,7 @@ DEPENDENCIES rubocop-rake rubocop-rspec simplecov + syntax_tree timecop webmock diff --git a/castle-rb.gemspec b/castle-rb.gemspec index 77ed276..fad325b 100644 --- a/castle-rb.gemspec +++ b/castle-rb.gemspec @@ -28,7 +28,7 @@ Gem::Specification.new do |s| 'rubygems_mfa_required' => 'true' } - s.files = Dir['{lib}/**/*'] + ['README.md', 'LICENSE', 'CHANGELOG.md'] + s.files = Dir['{lib}/**/*'] + %w[README.md LICENSE CHANGELOG.md] s.require_paths = ['lib'] s.required_ruby_version = '>= 3.2' diff --git a/spec/integration/rails/support/home_controller.rb b/spec/integration/rails/support/home_controller.rb index 06013a4..a7827a7 100644 --- a/spec/integration/rails/support/home_controller.rb +++ b/spec/integration/rails/support/home_controller.rb @@ -4,12 +4,7 @@ class HomeController < ActionController::Base # prepare context and call risk via the client def index1 request_context = ::Castle::Context::Prepare.call(request) - payload = { - event: '$login', - status: '$succeeded', - user: { id: '123' }, - properties: { key: 'value' } - } + payload = { event: '$login', status: '$succeeded', user: { id: '123' }, properties: { key: 'value' } } client = ::Castle::Client.new(context: request_context) client.risk(payload) @@ -18,10 +13,11 @@ def index1 # prepare payload via Payload::Prepare and call risk via the client def index2 - payload = ::Castle::Payload::Prepare.call( - { event: '$login', status: '$succeeded', user: { id: '123' }, properties: { key: 'value' } }, - request - ) + payload = + ::Castle::Payload::Prepare.call( + { event: '$login', status: '$succeeded', user: { id: '123' }, properties: { key: 'value' } }, + request + ) client = ::Castle::Client.new client.risk(payload) @@ -30,10 +26,11 @@ def index2 # prepare payload via Payload::Prepare and call Castle::API::Risk directly def index3 - payload = ::Castle::Payload::Prepare.call( - { event: '$login', status: '$succeeded', user: { id: '123' }, properties: { key: 'value' } }, - request - ) + payload = + ::Castle::Payload::Prepare.call( + { event: '$login', status: '$succeeded', user: { id: '123' }, properties: { key: 'value' } }, + request + ) Castle::API::Risk.call(payload) diff --git a/spec/lib/castle/api/filter_spec.rb b/spec/lib/castle/api/filter_spec.rb index 31c2ed3..cc4acc1 100644 --- a/spec/lib/castle/api/filter_spec.rb +++ b/spec/lib/castle/api/filter_spec.rb @@ -2,14 +2,7 @@ RSpec.describe Castle::API::Filter do describe '.call' do - let(:options) do - { - type: '$login', - status: '$attempted', - request_token: 'token', - params: { email: 'foo@bar.com' } - } - end + let(:options) { { type: '$login', status: '$attempted', request_token: 'token', params: { email: 'foo@bar.com' } } } context 'when the request fails and the failover strategy is not :throw' do before do diff --git a/spec/lib/castle/api/log_spec.rb b/spec/lib/castle/api/log_spec.rb index aabee8d..4060deb 100644 --- a/spec/lib/castle/api/log_spec.rb +++ b/spec/lib/castle/api/log_spec.rb @@ -3,12 +3,7 @@ RSpec.describe Castle::API::Log do describe '.call' do let(:options) do - { - type: '$profile_update', - status: '$succeeded', - user: { id: 'u-42' }, - context: { ip: '1.2.3.4' } - } + { type: '$profile_update', status: '$succeeded', user: { id: 'u-42' }, context: { ip: '1.2.3.4' } } end context 'when the request succeeds' do @@ -16,7 +11,9 @@ stub_request(:post, 'https://api.castle.io/v1/log').to_return( status: 201, body: '{}', - headers: { 'Content-Type' => 'application/json' } + headers: { + 'Content-Type' => 'application/json' + } ) end diff --git a/spec/lib/castle/api/risk_spec.rb b/spec/lib/castle/api/risk_spec.rb index 967c981..1b00802 100644 --- a/spec/lib/castle/api/risk_spec.rb +++ b/spec/lib/castle/api/risk_spec.rb @@ -3,13 +3,7 @@ RSpec.describe Castle::API::Risk do describe '.call' do let(:options) do - { - type: '$login', - status: '$succeeded', - request_token: 'token', - user: { id: 'u-42' }, - context: { ip: '1.2.3.4' } - } + { type: '$login', status: '$succeeded', request_token: 'token', user: { id: 'u-42' }, context: { ip: '1.2.3.4' } } end context 'when the request succeeds' do @@ -17,7 +11,9 @@ stub_request(:post, 'https://api.castle.io/v1/risk').to_return( status: 201, body: { policy: { action: 'allow' } }.to_json, - headers: { 'Content-Type' => 'application/json' } + headers: { + 'Content-Type' => 'application/json' + } ) end diff --git a/spec/lib/castle/client_spec.rb b/spec/lib/castle/client_spec.rb index adc8c99..a100981 100644 --- a/spec/lib/castle/client_spec.rb +++ b/spec/lib/castle/client_spec.rb @@ -44,7 +44,8 @@ stub_request(:any, /api.castle.io/).with(basic_auth: ['', 'secret']).to_return( status: response_code, body: response_body, - headers: {} + headers: { + } ) end diff --git a/spec/lib/castle/core/process_webhook_spec.rb b/spec/lib/castle/core/process_webhook_spec.rb index f2002fe..a5d2577 100644 --- a/spec/lib/castle/core/process_webhook_spec.rb +++ b/spec/lib/castle/core/process_webhook_spec.rb @@ -17,13 +17,19 @@ device_token: 'token', user_id: '', trigger: '$login.succeeded', - context: {}, - location: {}, - user_agent: {} + context: { + }, + location: { + }, + user_agent: { + } }, - user_traits: {}, - properties: {}, - policy: {} + user_traits: { + }, + properties: { + }, + policy: { + } }.to_json end diff --git a/spec/lib/castle/core/send_request_spec.rb b/spec/lib/castle/core/send_request_spec.rb index 1ff17b0..ed4cb08 100644 --- a/spec/lib/castle/core/send_request_spec.rb +++ b/spec/lib/castle/core/send_request_spec.rb @@ -57,12 +57,8 @@ context 'when post' do let(:time) { Time.now.utc.iso8601(3) } - let(:command) do - Castle::Commands::Risk.build(event: '$login.succeeded', user: { id: '1' }, name: "\xC4") - end - let(:expected_body) do - { event: '$login.succeeded', user: { id: '1' }, name: '�', context: {}, sent_at: time } - end + let(:command) { Castle::Commands::Risk.build(event: '$login.succeeded', user: { id: '1' }, name: "\xC4") } + let(:expected_body) { { event: '$login.succeeded', user: { id: '1' }, name: '�', context: {}, sent_at: time } } before { allow(Castle::Utils::GetTimestamp).to receive(:call).and_return(time) } diff --git a/spec/lib/castle/logger_spec.rb b/spec/lib/castle/logger_spec.rb index 31ab416..4975088 100644 --- a/spec/lib/castle/logger_spec.rb +++ b/spec/lib/castle/logger_spec.rb @@ -3,7 +3,8 @@ # tmp logger for testing class TmpLogger # @param _message [String] - def info(_message); end + def info(_message) + end end RSpec.describe Castle::Logger do diff --git a/spec/lib/castle/webhooks/verify_spec.rb b/spec/lib/castle/webhooks/verify_spec.rb index 53abf24..d6a9337 100644 --- a/spec/lib/castle/webhooks/verify_spec.rb +++ b/spec/lib/castle/webhooks/verify_spec.rb @@ -19,13 +19,19 @@ device_token: 'token', user_id: user_id, trigger: '$login.succeeded', - context: {}, - location: {}, - user_agent: {} + context: { + }, + location: { + }, + user_agent: { + } }, - user_traits: {}, - properties: {}, - policy: {} + user_traits: { + }, + properties: { + }, + policy: { + } }.to_json end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a11bea0..21866b5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true require 'simplecov' -SimpleCov.start do - add_filter '/spec/' -end +SimpleCov.start { add_filter '/spec/' } require 'rubygems' require 'bundler/setup'