Skip to content

Dependency Upgrade Roadmap: Rails 7.1 EOL + Outdated Dependencies #89

Description

@AgentKush

Summary

Project Daedalus is running several end-of-life or significantly outdated dependencies that should be upgraded for security, performance, and long-term maintainability. Rails 7.1 reached end-of-life in October 2025 and is no longer receiving security patches. This issue documents every outdated dependency, what needs to change, and a recommended upgrade path.


Current State vs Latest Versions

Dependency Current Latest Severity
Ruby 3.4.8 4.0.2 ⚠️ Major version jump
Rails ~> 7.1 8.1.3 🔴 EOL — no security patches
google-cloud-firestore ~> 2.8 3.1.1 ⚠️ Major version jump
tailwindcss-rails ~> 2.0 4.x (Tailwind v4) ⚠️ Major rewrite
puma ~> 6.0 6.6.1 (safe) / 7.2.0 ✅ Patch safe
propshaft unpinned 1.3.1 ✅ Likely fine
sqlite3 ~> 1.4 2.x+ ⚠️ May need bump

Recommended Upgrade Path

The safest approach is incremental. Do NOT jump straight to Rails 8.1 — each step has config changes and deprecation removals that need to be handled individually.

Phase 1: Rails 7.1 → 7.2 (Smallest, safest step)

Priority: HIGH — gets us off EOL onto a supported version

Config Changes Required:

  • config.cache_classes = trueconfig.enable_reloading = false (production.rb)
  • config.active_record.dump_schema_after_migration = false — can be removed (not using ActiveRecord)
  • config.active_storage.service = :google — review if Active Storage is actually used
  • Run rails app:update to regenerate config files and review diffs
  • Update config.load_defaults from 7.1 to 7.2 in config/application.rb

Gemfile Changes:

gem "rails", "~> 7.2"

Breaking Changes to Watch For:

  • Removed deprecated @rails/ujs (project uses Turbo so this should be fine)
  • Removed deprecated behavior for transaction blocks using return/break/throw (not applicable — no ActiveRecord)
  • Serialization: public signature for serialize method changed (not applicable — Firestore models don't use AR serialize)

What's Safe:

Most 7.1 → 7.2 breaking changes are ActiveRecord-related. Since this project uses Firestore with ActiveModel (not ActiveRecord), the majority of breaking changes don't apply. This is the easiest upgrade step.


Phase 2: Rails 7.2 → 8.0

Key Changes:

  • Requires Ruby 3.2+ (we're on 3.4.8 so this is fine)
  • config.load_defaults8.0
  • Regexp.timeout set to 1s by default — check the search regex in mods_controller.rb (find_mods method uses Regexp.escape so should be fine)
  • Schema sorting changes (not applicable — no ActiveRecord schema)
  • New default authentication generator available (optional)

Gemfile Changes:

gem "rails", "~> 8.0"

What's Safe:

Again, most breaking changes are ActiveRecord-focused. The controller/view layer is largely compatible.


Phase 3: Rails 8.0 → 8.1

Key Changes:

  • Removed support for semicolons as query string separator
  • Removed deprecated bin/rake stats
  • config.load_defaults8.1

What's Safe:

Smallest set of breaking changes. Mostly cleanup of previously deprecated features. This is the least risky step in the entire upgrade path — no database, serialization, or middleware changes to worry about.


Phase 4: Ruby 3.4 → 4.0 (Optional, can be deferred)

Priority: LOW — Ruby 3.4 is still supported

Breaking Changes:

  • *nil no longer calls nil.to_a (returns empty array directly) — unlikely to affect this project
  • Ractor API completely revised (not used in this project)
  • Binary extensions must be rebuilt (handled by bundle install)
  • Set and Pathname are now core classes (no longer need require)

What to Update:

  • .ruby-version4.0.2
  • Gemfileruby "4.0.2"
  • DockerfileFROM ruby:4.0-bookworm
  • Verify all gems are Ruby 4.0 compatible before upgrading

Recommendation:

Wait until Rails 8.x officially supports Ruby 4.0 and all gem dependencies have confirmed compatibility. Ruby 3.4 is still receiving security patches.

Phase 5: google-cloud-firestore 2.x → 3.x

Priority: MEDIUM

Breaking Changes:

  • Default return value of Client#transaction changed — now returns value of yielded block
  • Low-level V1 module classes renamed
  • Client constructor now takes configuration block instead of keyword arguments

What to Check:

  • Firestorable concern — verify Google::Cloud::Firestore.new(credentials: credentials.to_h) still works with v3 API
  • firestore.col("mods").get and firestore.col("tools").get — verify collection query API hasn't changed
  • Test thoroughly — Firestore is the backbone of the entire app

Gemfile Changes:

gem "google-cloud-firestore", "~> 3.1"

Phase 6: tailwindcss-rails 2.x → 4.x (Tailwind CSS v3 → v4)

Priority: LOW — can stay on v3 indefinitely

This is the Riskiest Upgrade

Tailwind CSS v4 is a complete rewrite:

  • JavaScript config (tailwind.config.js) replaced with CSS-based config using @theme
  • @tailwind base/components/utilities directives replaced with @import "tailwindcss"
  • PostCSS removed, replaced with LightningCSS
  • Default values changed: ring width 3px → 1px, ring color blue-500 → currentColor, border-* defaults gray-200 → currentColor
  • Content detection is now automatic

What Would Break:

  • config/tailwind.config.js — entire file needs rewriting to CSS-based @theme format
  • Every ring, border, divide utility — defaults changed, may need explicit values
  • Custom icarus color palette — needs migration to @theme format
  • Custom topo-light/topo-dark background images — need migration to @theme
  • All dark mode classes — should still work but need testing

Recommendation:

Defer this upgrade. Tailwind CSS v3 with tailwindcss-rails v2 is stable and will continue to work. The migration is extensive and touches every view file. Only upgrade when there's a compelling reason (v3 security issue, needed v4 feature, etc.).


Dockerfile Updates

The Dockerfile will need updating alongside the Ruby/Rails upgrades:

# Phase 1-3 (Rails upgrade only):
FROM ruby:3.4-bookworm AS build
# No change needed

# Phase 4 (Ruby 4.0):
FROM ruby:4.0-bookworm AS build

Testing Strategy

Since the app uses Firestore (not a local database), testing upgrades requires:

  1. Local testing with Firestore credentials — essential before deploying any upgrade
  2. Run bundle exec rspec after each phase to catch regressions
  3. Check all pages manually — Home, Mods (index + show), Tools, Info
  4. Verify Firestore reads — mods listing, tools listing, search, author filtering
  5. Verify downloads — Stimulus controller mods#download still triggers correctly
  6. Check asset pipeline — Propshaft compiles CSS/JS/images correctly
  7. Docker build testdocker build . succeeds and container starts

Quick Wins (No Risk)

These can be done right now without any upgrade:

  • Puma: Already on ~> 6.0, latest 6.x is 6.6.1. Just bundle update puma — bug fixes only.
  • Propshaft: Unpinned, so bundle update propshaft gets latest 1.3.1 — safe.
  • Remove unused ActiveRecord config: The production.rb has config.active_record.dump_schema_after_migration = false but the app doesn't use ActiveRecord. Can be removed for clarity.

Summary of Priorities

  1. 🔴 Rails 7.1 → 7.2 — Get off EOL. Mostly config changes. Low risk for this project.
  2. 🟡 Rails 7.2 → 8.0 — Incremental step. Low risk.
  3. 🟡 Rails 8.0 → 8.1 — Small step. Low risk.
  4. 🟡 google-cloud-firestore 2.x → 3.x — Test Firestore concern carefully.
  5. 🟢 Ruby 4.0 — Defer until ecosystem matures.
  6. 🟢 Tailwind v4 — Defer. V3 is fine.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions