Skip to content

Upgrade Rails 7.1 → 8.0#358

Draft
JuanVqz wants to merge 9 commits intomainfrom
feature/rails-7.1.6-patch
Draft

Upgrade Rails 7.1 → 8.0#358
JuanVqz wants to merge 9 commits intomainfrom
feature/rails-7.1.6-patch

Conversation

@JuanVqz
Copy link
Copy Markdown
Member

@JuanVqz JuanVqz commented May 5, 2026

Summary

Rails 7.1 → 8.0 upgrade in nine small commits, one concern per commit.

Phase 1 — Rails 7.1 → 7.2

  1. Bump Rails 7.1.5.1 → 7.1.6 - latest 7.1 patch before the version hop.
  2. Switch show_exceptions to symbol value for Rails 7.2 - false:none in config/environments/test.rb.
  3. Drop Rails.application.secrets in favor of credentials/ENV - delete config/secrets.yml and config.read_encrypted_secrets = true in production.
  4. Bump rspec-rails ~> 6.0.3 → ~> 6.1 - prereq for config.fixture_paths.
  5. Rename fixture_path → fixture_paths in rspec config - singular form removed in 7.2.
  6. Bump database_cleaner-active_record 2.1.0 → 2.2.2 - 2.1.x calls the removed connection.schema_migration and crashes on boot under 7.2.
  7. Upgrade Rails 7.1.6 → 7.2.3.1 - flips the Gemfile constraint; both CI checks were green at this point.

Phase 2 — Rails 7.2 → 8.0

  1. Bump jbuilder ~> 2.5 → ~> 2.13 for Rails 8 compat - 2.11.x requires active_support/proxy_object which Rails 8 removed; bumping the floor to 2.13 unblocks the version flip.
  2. Upgrade Rails 7.2.3.1 → 8.0.5 - flips the constraint; collapses the dual-boot if/else now that both sides target 8.0.

Why phased

Each Rails hop is sequential by construction (no version skipping). Doing the 7.2 hop first cleared every 7.2-only deprecation, then the 8.0 hop only had to deal with 8.0-specific concerns. Each fix-before-bump commit is independently revertable and individually testable.

Gemfile.next is a symlink to Gemfile, so both sides of dual-boot share one source of truth. The next? helper and the symlink stay in place for now — keeping build-rails-next in CI as a sanity check during this PR. Cleanup of dual-boot scaffolding is a follow-up.

Detection findings

7.2 patterns

Findings, all addressed:

  • config.action_dispatch.show_exceptions = false (config/environments/test.rb:26)
  • Rails.application.secrets chain (via config/secrets.yml + config.read_encrypted_secrets)
  • config.fixture_path singular (spec/rails_helper.rb:98)
  • Surfaced at runtime, not by static patterns: database_cleaner-active_record 2.1.x calling the removed schema_migration adapter method.

8.0 patterns

Almost everything came back clean: enum kwargs unused, no removed AR config keys, no routes-array drawing, no SCHEMA_CACHE env var, no Benchmark.ms, no rake stats, no Sidekiq / redis_cache_store. Ruby 3.2.3 already meets the 3.2.0 floor.

Sprockets stays — still works at 8.0, just no longer the new-app default. Migration to Propshaft is a separate, optional concern.

Surfaced at runtime, not by static patterns: jbuilder 2.11.x requiring active_support/proxy_object. Bumped to 2.14.1 (~> 2.13 floor).

CI sync

Workflow Ruby Gemfile Rails resolved Verdict
tests.yml (build-rails-current) 3.2.3 Gemfile 8.0.5 OK
tests-next.yml (build-rails-next) 3.2.3 Gemfile.next (symlink) 8.0.5 OK

Both workflows sync'd to upgraded Gemfile.

Test plan

  • bundle exec rspec green at every commit on this branch (204/204)
  • bundle exec rspec green on Rails 8.0.5 (204/204)
  • build-rails-current green on this PR
  • build-rails-next green on this PR
  • Deploy and verify

Follow-ups (not in this PR)

  • Align config.load_defaults to 7.2, then to 8.0 (incremental, one config at a time, separate PR).
  • Cleanup dual-boot scaffolding: drop the next? helper, retire Gemfile.next symlink, retire tests-next.yml.
  • 8.0 → 8.1 hop: address the to_time timezone deprecation surfaced under 8.0 (config.active_support.to_time_preserves_timezone = :zone).

Notes

  • Pre-existing order-dependent flake observed in spec/features/projects_manage_spec.rb:252 (passes on rerun and in isolation). Not introduced by this PR.

JuanVqz added 5 commits May 4, 2026 19:10
Rails 7.2 changes config.action_dispatch.show_exceptions from a
boolean to a symbol. Boolean values stop working at the 7.2 bump.

  - true       -> :all
  - false      -> :none
  - new option -> :rescuable (raise non-rescuable, render rescuable)

The test environment used `false` (raise everything). The 1:1
replacement is :none. Symbol form already works on 7.1, so this is
a direct rewrite with no dual-boot conditional needed.

Ref: https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#config-action-dispatch-show-exceptions
Rails 7.2 removes Rails.application.secrets entirely. Anything that
relied on config/secrets.yml stops working at the bump. Currently the
file only carries secret_key_base, which Rails resolves through this
chain (in order):

  1. Rails.application.credentials.secret_key_base
  2. ENV["SECRET_KEY_BASE"]
  3. tmp/local_secret.txt (dev/test auto-generated)

Production already uses ENV["SECRET_KEY_BASE"] (unchanged). Dev/test
fall through to tmp/local_secret.txt automatically, so deleting
secrets.yml is safe.

Also drops config.read_encrypted_secrets = true from production.rb,
which is a no-op in 7.2 and only ever applied to the legacy
secrets.yml.enc workflow.

Ref: https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#rails-application-secrets-removal
Rails 7.2 deprecates fixture_path (singular) in favor of
fixture_paths (plural array). The new API exists in Rails 7.1+,
but rspec-rails surfaces it via config.fixture_paths only from
6.1.0 onward — 6.0.x still expects fixture_path.

Bumping the floor to 6.1 unblocks the fixture_paths rewrite that
follows in the next commit. 6.1.5 resolves cleanly on both
sides of the dual-boot pair (7.1.6 and 7.2.3) with no other
gem changes pulled in beyond the rspec-rails sub-gems on the
.next side.
Rails 7.2 deprecates the singular fixture_path setter on
ActiveSupport::TestCase. rspec-rails 6.1+ exposes the plural
form, which takes an array of paths and is the long-term API
on both 7.1 and 7.2. Direct rewrite — no NextRails.next? branch
needed, and no behavior change since we still point at a single
spec/fixtures directory.

Ref: https://github.com/rspec/rspec-rails/blob/main/Changelog.md#610--2023-11-21
@JuanVqz JuanVqz changed the title Bump Rails 7.1.5.1 → 7.1.6 Rails 7.1.6 patch + fix-before-bump prep for 7.2 May 5, 2026
JuanVqz added 2 commits May 4, 2026 19:33
database_cleaner-active_record 2.1.x calls AR connection
adapter#schema_migration, which Rails 7.2 removed in favor of an
internal-pool-based API. The 2.1.x suite errors out on boot
under 7.2 with:

  NoMethodError: undefined method `schema_migration' for
  #<ActiveRecord::ConnectionAdapters::PostgreSQLAdapter ...>

2.2.0 reworked the cleanup to use the new connection API. 2.2.2 is
the latest patch and resolves cleanly on both 7.1.6 and 7.2.3.

Doing the bump as its own commit so the Rails version flip in the
next commit is isolated to the Gemfile constraint change.

Ref: https://github.com/DatabaseCleaner/database_cleaner-active_record/blob/main/CHANGELOG.md
Flips the Gemfile constraint from ~> 7.1.0 to ~> 7.2.0 and
collapses the dual-boot if/else into a single line, since both
sides of the dual-boot pair now point at 7.2 anyway.

The next? helper (Gemfile lines 3-5) and the Gemfile.next symlink
stay in place. They will be retired in a follow-up cleanup pass
once 7.2 ships, per the dual-boot teardown checklist — keeping
them now keeps build-rails-next in CI as a sanity check on the
exact same constraints as build-rails-current.

All fix-before-bump items were addressed in earlier commits in
this branch:

  - show_exceptions symbol value
  - Rails.application.secrets removal
  - rspec-rails fixture_paths support
  - database_cleaner-active_record schema_migration compat

Test suite is 204/204 green on 7.2.3.1.
@JuanVqz JuanVqz changed the title Rails 7.1.6 patch + fix-before-bump prep for 7.2 Upgrade Rails 7.1 → 7.2 May 5, 2026
JuanVqz added 2 commits May 4, 2026 20:33
jbuilder 2.11.x calls require "active_support/proxy_object" at
load time. proxy_object was deprecated in Rails 5 and removed in
Rails 8.0, so the require raises LoadError the moment Bundler
runs Bundler.require for the :default group:

  LoadError: cannot load such file -- active_support/proxy_object
    config/application.rb:7:in `<top (required)>'

jbuilder 2.12 dropped the require (jbuilder commit b8e2d8f),
2.13 added explicit Rails 8 support. Bumping the floor to 2.13
resolves cleanly on both 7.2 (current) and 8.0 (next), so this
sits as a prereq before the Rails version flip.

Conservative resolution kept all other gems pinned.

Ref: rails/jbuilder#580
Flips the Gemfile constraint from ~> 7.2.0 to ~> 8.0.0 and
collapses the dual-boot if/else into a single line. Both sides
of the dual-boot pair (Gemfile and Gemfile.next via symlink) now
target 8.0.

Detection against the 8.0 pattern set surfaced no fix-before-bump
items in our codebase: enum is unused, no removed AR config keys,
no routes-array usage, no SCHEMA_CACHE env var, no Benchmark.ms,
Ruby 3.2.3 already meets the 3.2.0 floor.

Sprockets stays — it still works at 8.0 (just no longer the new-
app default). Migration to Propshaft is a separate, optional
concern.

The only prereq surfaced by booting the test suite under 8.0 was
jbuilder still requiring active_support/proxy_object; addressed
in the previous commit.

Test suite is 204/204 green on 8.0.5.

Deferred to the 8.0 → 8.1 hop (per skill rules — future-version
runtime warnings are not fix-before-bump for the current hop):

  - to_time timezone behavior
    (config.active_support.to_time_preserves_timezone = :zone)
@JuanVqz JuanVqz changed the title Upgrade Rails 7.1 → 7.2 Upgrade Rails 7.1 → 8.0 May 5, 2026
@JuanVqz JuanVqz marked this pull request as draft May 5, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant