agentsclimarketplace

Rails 8 upgrade

Skill davidteren/hotwire-codex-skills/skills/rails-8-upgrade

Unofficial Claude Code skillset inspired by The Rails and Hotwire Codex — 8 skills for building interactive Rails + Hotwire apps (Turbo, Stimulus, Hotwire Native) across web, iOS & Android, each with a runnable checker.

Install
npx -y skills add davidteren/hotwire-codex-skills --skill rails-8-upgrade

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 3 stars3 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Upgrade a Rails 7 app to Rails 8 safely, and catch the subtle test-suite flake it introduces. Use when bumping Rails 7.x to 8.x (or auditing readiness), when planning a Ruby/Rails version bump, or when Rails 8 tests fail intermittently with "undefined method 'login_path'/'root_path'" / pass on serial but flake on parallel runs. Provides a pre-flight audit, a detector + fix for the LazyRouteSet route-test flake, and a 7→8 checklist grounded in a real upgrade.

SKILL.md

3.3 KB, as published. Nobody here has run it

Rails 7 → 8 upgrade

Two things kill time in a 7→8 upgrade: deciding what to bump vs defer, and a flaky route-helper test that Rails 8's LazyRouteSet introduces and that hides behind single green test runs. This skill handles both.

Read references/rails-7-to-8.md for the full checklist and the why.

When to use

  • Bumping rails 7.x → 8.x, or checking whether an app is ready.
  • Tests started flaking after a Rails 8 bump with undefined method 'login_path'/'root_path' in unrelated controllers; serial runs stay green.
  • Reviewing a PR that adds/edits a draw_test_routes-style route helper.

1. Pre-flight audit (read-only)

scripts/upgrade_audit.sh path/to/app

Reports: Ruby/Rails versions (+ flags a Gemfile.lock RUBY VERSION mismatch that makes bundle refuse), config.load_defaults vs Rails major, presence of a new_framework_defaults_*.rb, known-risky gems (notably pagy <6 with custom pagy view helpers — a real porting cost), and whether the test suite uses the flaky route pattern. Changes nothing.

2. The recommended path

  1. Baseline green on current versions first (a bisectable starting point).
  2. Bump rails ~> 8.x and Ruby; leave config.load_defaults where it is (run new library code with old framework behavior — low risk).
  3. bundle update; only hand-pin where a transitive conflict forces it.
  4. Run the suite ≥6× (parallel flakes hide — see below). Boot the server, check a public (200) and a protected (401/redirect) route.
  5. Flip framework defaults separately later, via config/initializers/new_framework_defaults_8_1.rb, one line at a time.

3. The LazyRouteSet route-test flake (the expensive one)

If the suite appends test-only routes via a helper that toggles Rails.application.routes.disable_clear_and_finalize, Rails 8 makes it flaky under parallel runs. Detect it:

scripts/lint_route_test_helper.sh path/to/app

It checks the helper (a) materializes the LazyRouteSet (reload_routes_unless_loaded) before setting the flag, (b) resets the flag in an ensure, (c) doesn't use the finalize! dead-end, and (d) every draw_test_routes caller has a teardown { reload_routes! }. Exits non-zero on risk and prints the fix.

Apply templates/routes_helper.rb.fixed (drop into test/support/) and add the missing teardowns. Then run the suite ≥6× to confirm — a 35%-flake bug passes ~2 of 3 single runs.

Root cause + dead-ends: references/rails-7-to-8.md. Real-world instance: piazza-web/wip/analysis/01.

Why the scripts are heuristic

Plain grep/awk text scans, not Ruby parsers — conservative and dependency-free, meant to gate a PR and point you at the fix, not to be a type checker. They name their ceiling in the output.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.