Bump oauth2 + faraday to 2.x for Rails 8.0 compatibility - #14
Open
wmaciejak wants to merge 2 commits into
Open
Conversation
Prepares the gem for Rails 8. The blocker was BaseModel#as_json mutating a frozen options Hash (Rails 8 freezes options during Array/Hash#as_json recursion). oauth2 1.4 also pinned faraday < 2, so both had to move together. - oauth2 ~> 2.0, faraday ~> 2.0, + faraday-multipart (:multipart / UploadIO moved out of Faraday core) - Faraday 2 API: dependency -> require, register_middleware class form, connection_build rebuild, FilePart, request :authorization - as_json dups options before mutating (folds in the housecall-web patch) - required_ruby_version >= 3.0; net-http-persistent -> faraday-net_http_persistent (lazy-required only when that adapter is selected) - Fix pre-existing ChangeService#url_for_query arity mismatch - Version-independent specs; suite green on activemodel 8.1.3 / Ruby 3.4 (464/0) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Faraday 2 / oauth2 2 (and required_ruby_version >= 3.0) can't resolve on
Ruby < 3.0, so the 2.5/2.6/2.7 jobs failed at bundle install ("Could not
find compatible versions"). Align the matrix with the supported range
(3.0-3.4) and make ruby-head informational via continue-on-error.
Also drop the `ruby RUBY_VERSION` Gemfile pin, which broke bundle install
on prerelease Rubies (ruby-head: "Your Ruby version is 4.1.0.dev, but your
Gemfile specified 4.1.0"). The Ruby floor now lives in the gemspec.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bump oauth2 & faraday to 2.x — Rails 8.0 readiness
Why
This fork could not run under Rails 8.0. The blocker:
BaseModel#as_jsonmutated its
options[:except]in place, and Rails 8 now freezes the optionsHash passed down through
Array#as_json/Hash#as_jsonrecursion(
rails/rails@5f73931) — so serializing any model nested in a container raisedFrozenError. housecall-web currently patches around this at runtime.Fixing it cleanly also required moving off the old HTTP stack:
oauth2 ~> 1.4transitively pins
faraday < 2, so oauth2 and faraday have to be bumpedtogether (
oauth2 2.0relaxes the constraint tofaraday < 3).What changed
Rails 8 fix (the point of this PR)
BaseModel#as_jsonnow dups the options Hash before mutating it. This foldsin the workaround housecall-web carries as a monkey patch, so that patch can be
removed once this ships.
Dependency bumps
oauth2 ~> 1.4→~> 2.0faraday < 2.0→~> 2.0faraday-multipart ~> 1.0— Faraday 2 extracted the:multipartrequestmiddleware and
UploadIO/FilePartinto this gem.net-http-persistent→faraday-net_http_persistent ~> 2.0— under Faraday 2the
:net_http_persistentadapter lives in this gem, not the raw one (which wasinert). Required lazily in
Quickbooks.http_adapter=so the default:net_httppath pays no load cost.
required_ruby_version >= 3.0(Faraday 2's floor; a Rails 8 host adds>= 3.2via activemodel).activemodelstays unpinned on the upper bound soactivemodel 8.x is allowed.
Faraday 2 API migration
Faraday::Middleware.dependencywas removed → plainrequire 'zlib'/require 'brotli'(brotli now raises an actionable
LoadErrorif the optional gem is absent).register_middlewareno longer accepts thelambda { Klass }thunk form → registerthe class directly.
Connection#buildwas removed → the OAuth2 client's Faraday stack is now injected viaclient.options[:connection_build](which oauth2 2.0 uses to build the connectionlazily) instead of mutating
client.connection.Faraday::UploadIO→Faraday::Multipart::FilePart.Connection#basic_authwas removed →request :authorization, :basic, …(used inAccessToken#disconnect).oauth2 2.0
AccessToken#get/#post(…, raise_errors: false)still suppresses raising onnon-2xx (QBO faults must be wrapped, not raised) —
Client#requesthonors theper-call override.
Incidental fix (pre-existing bug)
ChangeService#url_for_querytook 3 args whilefetch_collectioncalls it with 4(
options) →ArgumentError. Signature aligned with the base method. (This wasfailing before this PR, independent of the bump.)
Tests
BaseModel#as_jsoncoverage (there was none), including regression cases thatexercise the real Rails 8 trigger — a model nested in an Array/Hash serialized
with options, which is what makes ActiveSupport freeze them.
url_for_queryand request-hook specs to assert on decoded queries andstructured
RequestInfoinstead of exact stdout — they were coupled to Faraday's+vs%20encoding and Ruby'sHash#inspectformat (=>vs=>in Ruby 3.4).Testing
bundle exec rspec→ 464 examples, 0 failures on Ruby 3.4.1 withactivemodel/activesupport 8.1.3 (Rails 8's ActiveModel/ActiveSupport).
as_jsonregression was proven end-to-end: the container-recursion path deliversa
frozen=trueoptions Hash intoas_json; the pre-fix code raisesFrozenErroronthat exact path, the fix does not.
Downstream / migration notes
Quickbooks::Model::BaseModel#as_jsonmonkey patch onlyafter the Gemfile points at a ref containing this change (until then it's a redundant
no-op). Also re-verify any direct
OAuth2::Clientconstruction / token refresh(
get_token,refresh!) against the oauth2 2.0 API.Quickbooks.http_adapter = :net_http_persistentnow get the correctFaraday 2 adapter automatically.
Out of scope (follow-up)
BaseModelJSON#to_jsonandTaxRateDetailLine#to_jsonare arity-0 (def to_json), soa
to_json(options)call during serialization wouldArgumentError. Pre-existing andversion-agnostic — not addressed here.