Skip to content

Upgrade prep: make the Rails 7.2 upgrade safe to start #880

Description

@suttondemlong

Why

Before any version moves, five pieces of prep are independently useful and remove ways the later steps could fail quietly. None of them changes a version or any user-visible behaviour.

Scope

  1. Pin active_model_serializers to 0.9.8. The constraint is ~> 0.9, which also permits 0.10.x. AMS 0.10 is a rewrite with no embed: / embed_in_root: — options used in 22 places across 10 serializers. A stray bundle update would silently change the JSON shape of every endpoint and break both the Ember and native clients. (Confirmed: a plain bundle lock --update pulls 0.9.8 -> 0.10.16.)
  2. Replace Rails.application.secrets. Deprecated in 7.1, removed in 7.2, and the only deprecation the app emits. config/secrets.yml only read three values, all already env-backed, so this deletes an indirection rather than migrating to credentials.
  3. Make the backend lint jobs reproducible. erb-lint installs the gem unpinned outside the bundle, runs with --autocorrect (fixes in place, exits 0 — so it gates nothing), and is the only job not passing working-directory: backend to ruby/setup-ruby, so it resolves the root .ruby-version while every other job uses backend/. Also gives brakeman the needs: changes guard the other three jobs have.
  4. Raise on deprecation warnings in test. Turns each later upgrade step into a pass/fail signal instead of stderr noise.
  5. Drop rails_12factor. A no-op since Rails 5; production.rb already sets both behaviours explicitly. No release since 2016.

Two traps found while doing this

  • The test: block of secrets.yml was load-bearing: it pinned tomorrow_io_key to a value baked into the WeatherRetriever VCR cassette URI, and smtp_email_from to a value asserted in two mailer specs. Deleting the file naively turns both to nil and breaks CI.
  • Raising on deprecations needs a prerequisite: when DEVISE_SECRET_KEY is blank, Devise::SecretKeyFinder reads Rails.application.secrets from inside the gem. CI sets no such variable and has no .env, so this already fires on every CI run and would abort the boot. Fixed by having the Devise initializer fall back to secret_key_base directly, which is where Devise's own chain ends anyway.

Acceptance criteria

  • bundle exec rspec green
  • bundle exec standardrb exits 0
  • bundle exec erblint --lint-all exits 0 without --autocorrect
  • No deprecation warnings emitted during a test run
  • Brakeman finding count unchanged from master (currently 4 weak-confidence, 0 errors)

Blocks

Everything else in the sequence: #881, #882, #883, #884, #885, #886, #887, #888.


Part of the Ruby + Rails upgrade sequence. Ruby 3.2 reached end of life on 2026-04-01 and the backend is on Rails 7.1; the goal is Ruby 3.4.10 and Rails 8.1, in steps that each keep CI green and are independently deployable.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions