From rails-upgrade
Analyzes Rails apps and generates upgrade reports from 2.3 to 8.1 with breaking changes, deprecations, and step-by-step migration guides. Use for upgrades, multi-hop plans, or version queries.
How this skill is triggered — by the user, by Claude, or both
Slash command
/rails-upgrade:rails-upgradeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- **Name:** Rails Upgrade Assistant
CHANGELOG.mddetection-scripts/patterns/rails-40-patterns.ymldetection-scripts/patterns/rails-41-patterns.ymldetection-scripts/patterns/rails-42-patterns.ymldetection-scripts/patterns/rails-50-patterns.ymldetection-scripts/patterns/rails-51-patterns.ymldetection-scripts/patterns/rails-52-patterns.ymldetection-scripts/patterns/rails-60-patterns.ymldetection-scripts/patterns/rails-70-patterns.ymldetection-scripts/patterns/rails-71-patterns.ymldetection-scripts/patterns/rails-72-patterns.ymldetection-scripts/patterns/rails-80-patterns.ymldetection-scripts/patterns/rails-81-patterns.ymlexamples/multi-hop-upgrade.mdexamples/simple-upgrade.mdreferences/breaking-changes-by-version.mdreferences/deprecation-warnings.mdreferences/gem-compatibility.mdreferences/multi-hop-strategy.mdreferences/staying-current.mdnext_rails gem. Covers setup, NextRails.next? code patterns, CI configuration, and post-upgrade cleanup. Must be installed for Step 2 of the upgrade workflow.load_defaults updates with tiered risk assessment (Tier 1: low-risk, Tier 2: needs codebase grep, Tier 3: requires human review). Used as the final step after the Rails version upgrade is complete.This skill follows the proven FastRuby.io upgrade methodology:
next_rails gemKey Resources:
dual-boot skill for dual-boot setup with next_rails (see Dependencies)references/deprecation-warnings.md for managing deprecationsreferences/staying-current.md for maintaining upgrades over timeNextRails.next?When proposing code fixes that must work with both the current and target Rails versions (dual-boot), always use NextRails.next? from the next_rails gem — never use respond_to? or other feature-detection patterns.
DELEGATE to the dual-boot skill for:
next_rails --init, Gemfile.next)NextRails.next? code patterns and examplesDEPENDENCY: Requires the dual-boot skill
Claude should activate this skill when user says:
Upgrade Requests:
Specific Report Requests:
Upgrade Cleanup Requests (delegate to the upgrade-cleanup plugin):
Rails upgrades MUST follow a sequential path. Examples:
For Rails 5.x to 8.x:
5.0.x → 5.1.x → 5.2.x → 6.0.x → 6.1.x → 7.0.x → 7.1.x → 7.2.x → 8.0.x → 8.1.x
You CANNOT skip versions. Examples:
If user requests a multi-hop upgrade (e.g., 5.2 → 8.1):
| From | To | Difficulty | Key Changes | Ruby Required |
|---|---|---|---|---|
| 2.3.x | 3.0.x | Very Hard | XSS protection, routes syntax | 1.8.7 - 1.9.3 |
| 3.0.x | 3.1.x | Medium | Asset pipeline, jQuery | 1.8.7 - 1.9.3 |
| 3.1.x | 3.2.x | Easy | Ruby 1.9.3 support | 1.8.7 - 2.0 |
| 3.2.x | 4.0.x | Hard | Strong Parameters, Turbolinks | 1.9.3+ |
| 4.0.x | 4.1.x | Medium | Spring, secrets.yml | 1.9.3+ |
| 4.1.x | 4.2.x | Medium | ActiveJob, Web Console | 1.9.3+ |
| 4.2.x | 5.0.x | Hard | ActionCable, API mode, ApplicationRecord | 2.2.2+ |
| From | To | Difficulty | Key Changes | Ruby Required |
|---|---|---|---|---|
| 5.0.x | 5.1.x | Easy | Encrypted secrets, yarn default | 2.2.2+ |
| 5.1.x | 5.2.x | Medium | Active Storage, credentials | 2.2.2+ |
| 5.2.x | 6.0.x | Hard | Zeitwerk, Action Mailbox/Text | 2.5.0+ |
| 6.0.x | 6.1.x | Medium | Horizontal sharding, strict loading | 2.5.0+ |
| 6.1.x | 7.0.x | Hard | Hotwire/Turbo, Import Maps | 2.7.0+ |
| 7.0.x | 7.1.x | Medium | Composite keys, async queries | 2.7.0+ |
| 7.1.x | 7.2.x | Medium | Transaction-aware jobs, DevContainers | 3.1.0+ |
| 7.2.x | 8.0.x | Very Hard | Propshaft, Solid gems, Kamal | 3.2.0+ |
| 8.0.x | 8.1.x | Easy | Bundler-audit, max_connections | 3.2.0+ |
SKILL.md - This file (entry point)Legacy Rails:
version-guides/upgrade-3.2-to-4.0.md - Rails 3.2 → 4.0 (Strong Parameters)version-guides/upgrade-4.0-to-4.1.md - Rails 4.0 → 4.1 (Spring, secrets.yml, enums)version-guides/upgrade-4.1-to-4.2.md - Rails 4.1 → 4.2 (ActiveJob, Web Console)version-guides/upgrade-4.2-to-5.0.md - Rails 4.2 → 5.0 (ApplicationRecord)Modern Rails:
version-guides/upgrade-5.0-to-5.1.md - Rails 5.0 → 5.1 (Encrypted secrets)version-guides/upgrade-5.1-to-5.2.md - Rails 5.1 → 5.2 (Active Storage, Credentials)version-guides/upgrade-5.2-to-6.0.md - Rails 5.2 → 6.0 (Zeitwerk)version-guides/upgrade-6.0-to-6.1.md - Rails 6.0 → 6.1 (Horizontal sharding)version-guides/upgrade-6.1-to-7.0.md - Rails 6.1 → 7.0 (Hotwire/Turbo)version-guides/upgrade-7.0-to-7.1.md - Rails 7.0 → 7.1 (Composite keys)version-guides/upgrade-7.1-to-7.2.md - Rails 7.1 → 7.2 (Transaction jobs)version-guides/upgrade-7.2-to-8.0.md - Rails 7.2 → 8.0 (Propshaft)version-guides/upgrade-8.0-to-8.1.md - Rails 8.0 → 8.1 (bundler-audit)workflows/test-suite-verification-workflow.md - MANDATORY FIRST STEP - How to run and verify test suiteworkflows/direct-detection-workflow.md - How to run breaking change detection directlyworkflows/upgrade-report-workflow.md - How to generate upgrade reportsworkflows/gem-compatibility-workflow.md - Load in Step 4.5 - Per-lockfile gem compatibility check against the target Rails version. Documents both the primary (next_rails bundle_report compatibility) and the secondary (railsbump.org API) and the rules for when to escalate.workflows/boot-smoke-test-workflow.md - Load in Step 4.6 - Run a Rails-loading command against Gemfile.next to catch gem-level runtime incompat that the resolver can't see (gems calling removed Rails internals or require-ing removed files).workflows/ci-sync-workflow.md - MANDATORY before opening the upgrade PR - How to verify CI config matches the upgraded Gemfileworkflows/app-update-preview-workflow.md - How to generate app:update previewsupgrade-cleanup companion plugin - User-triggered. Removes dual-boot scaffolding and drops NextRails.next? / NextRails.current? branches. Deprecation triage stays with this skill for the next hop.examples/simple-upgrade.md - Single-hop upgrade exampleexamples/multi-hop-upgrade.md - Multi-hop upgrade examplereferences/deprecation-warnings.md - Finding and fixing deprecationsreferences/staying-current.md - Keeping up with Rails releasesreferences/breaking-changes-by-version.md - Quick lookupreferences/multi-hop-strategy.md - Multi-version planningreferences/testing-checklist.md - Comprehensive testingreferences/gem-compatibility.md - Gem update order and the "no compatible version" playbook (fork / vendor / replace). Load only when Step 4.5's compatibility check produced blockers.detection-scripts/patterns/rails-*.yml - Version-specific patterns for direct detectiontemplates/upgrade-report-template.md - Main upgrade report structuretemplates/app-update-preview-template.md - Configuration previewWhen user requests an upgrade, follow this workflow:
⚠️ THIS STEP IS REQUIRED BEFORE ANY OTHER WORK
1. Read Gemfile.lock to find exact current Rails version (e.g., 3.2.19)
2. Compare against latest patch for that series:
- EOL series (≤ 7.1): use static table in references/multi-hop-strategy.md
- Active series (≥ 7.2): query RubyGems API (see references/multi-hop-strategy.md for commands)
3. If current version < latest patch:
- INFORM user: "Your app is on Rails X.Y.Z but the latest patch is X.Y.W"
- Guide through Gemfile update and bundle update rails
- Run test suite after patch upgrade
- Deploy patch upgrade before proceeding
- Do NOT proceed to next minor/major until on latest patch
4. If current version == latest patch:
- Proceed to Step 1
Why patch first: Patch releases contain security fixes, bug fixes, and additional deprecation warnings. Starting the version hop on the latest patch is safer (the security fixes are already in production) and easier to debug (the new deprecation warnings surface issues that would otherwise show up mid-upgrade).
⚠️ THIS STEP IS REQUIRED BEFORE ANY OTHER WORK
1. Read: workflows/test-suite-verification-workflow.md
2. Detect test framework (RSpec, Minitest, or both)
3. Run test suite with: bundle exec rspec OR bundle exec rails test
4. Capture results: total tests, passing, failing, pending
5. If ANY tests fail:
- STOP the upgrade process
- Report failing tests to user
- Offer to help fix failing tests
- Do NOT proceed until all tests pass
6. If all tests pass:
- Record baseline metrics (test count, coverage if available)
- Proceed to Step 2
DELEGATE to the dual-boot skill for setup and initialization.
That skill handles:
- Checking if Gemfile.next already exists (to avoid duplicate `next?` method)
- Adding next_rails gem and running next_rails --init
- Installing dependencies for both Rails versions
- Configuring the Gemfile with `if next?` conditionals
1. Check if upgrade is single-hop or multi-hop
2. If multi-hop, explain sequential requirement
3. Plan individual hops
Claude runs detection directly using tools - NO script generation needed
1. Read: workflows/direct-detection-workflow.md
2. Read: detection-scripts/patterns/rails-{VERSION}-patterns.yml
3. For each pattern in the patterns file:
- Use Grep tool to search for the pattern
- Collect file paths and line numbers
- Store findings with context
4. Read: version-guides/upgrade-{FROM}-to-{TO}.md for context
5. Compile all findings into structured data
Determines which gems must be bumped before the Rails version change can resolve.
1. Read: workflows/gem-compatibility-workflow.md and follow it. The
workflow documents the primary check (next_rails bundle_report),
the conditions for escalating to the secondary (railsbump API),
and the bucket mapping for both.
2. Pass the resulting three buckets — required bumps, blockers,
already compatible — into Step 5's report so the gem-update
section reflects real per-lockfile data.
3. If any blockers exist, load references/gem-compatibility.md for
the fork/replace/vendor playbook and the gem update order. Skip
otherwise.
Catches the gem-internal incompatibilities that Step 4 (codebase grep) and
Step 4.5 (resolver-level compat check) cannot see.
A gem can declare loose Rails constraints — no upper bound on activerecord /
activesupport — and `bundle_report compatibility` plus `bundle install` will
both call it "compatible." But at runtime, the gem may:
- call a Rails internal that was removed at the target version
(e.g. database_cleaner-active_record 2.1.x calling
AR::ConnectionAdapters#schema_migration, removed in Rails 7.2)
- require a file that was removed at the target version
(e.g. jbuilder 2.11.x doing `require "active_support/proxy_object"`,
removed in Rails 8.0)
These surface only when something boots Rails. Catching them here, before
the report is written, lets them land in fix-before-bump where they belong
instead of mid-implementation.
1. Read: workflows/boot-smoke-test-workflow.md
2. Run a Rails-loading command against Gemfile.next:
BUNDLE_GEMFILE=Gemfile.next bundle exec rspec --dry-run
(or `bin/rails runner "puts Rails.version"`, or `bundle exec rspec` if
the suite is fast enough — anything that triggers
`Bundler.require(*Rails.groups)` and the framework boot.)
3. If boot fails, capture the LoadError / NoMethodError trace, identify
the offending gem (grep the bundle paths for the missing constant or
file), check rubygems for a newer version with target-Rails compat,
and add the bump to the fix-before-bump bucket for Step 5.
4. Re-run the boot smoke test until it succeeds. Then proceed to Step 5.
1. Read: templates/upgrade-report-template.md
2. Read: templates/app-update-preview-template.md
3. Read: workflows/upgrade-report-workflow.md
4. Read: workflows/app-update-preview-workflow.md
Deliverable #1: Comprehensive Upgrade Report
workflows/direct-detection-workflow.md — fix-before-bump (kind: breaking and kind: deprecation) and fix-when-ready (kind: migration and kind: optional) — with OLD vs NEW code examples taken from the user's actual files, custom-code warnings flagged with ⚠️, a step-by-step migration plan, a testing checklist, and a rollback plan.Deliverable #2: app:update Preview
1. Present Comprehensive Upgrade Report first
2. Present app:update Preview Report second
3. Apply fix-before-bump changes (`kind: breaking` and `kind: deprecation`). Most fixes are direct rewrites — the new API typically works on both sides of the dual-boot pair (e.g., `update_attributes` → `update`). Use `NextRails.next?` only when the fix requires target-version-only APIs that don't exist in the current Rails
4. Update Gemfile to target Rails version
5. Run test suite against both versions
6. **Check CI config matches the upgraded Gemfile** — load `workflows/ci-sync-workflow.md`, fix any mismatches before proceeding
7. Deploy and verify
Do not fix load_defaults-triggered runtime deprecation warnings about future Rails versions during this hop. This caveat covers post-bump runtime warnings emitted by Rails X+1 about behavior scheduled to change in X+2 — typically surfaced once load_defaults X.Y flips on in Step 7. Those belong to the next upgrade cycle and are addressed before the next version bump.
This is not a contradiction of fix-before-bump. The kind: deprecation patterns from Step 4's detection are warnings emitted by the current Rails version about APIs that go away at the target version — they stay in fix-before-bump and should be addressed in this hop.
Triaging tomorrow's deprecation warnings now expands the scope of the current hop and risks shipping a half-finished change.
⚠️ THIS STEP HAPPENS AFTER THE UPGRADE IS COMPLETE
1. DELEGATE to the rails-load-defaults skill
2. That skill walks through each config change one at a time, grouped by risk tier
3. Tests are re-run between each change
4. Consolidates into config/application.rb when done
⚠️ DO NOT AUTO-RUN. Mention it; let the user decide.
1. Tell the user the cleanup option exists
2. Delegate to the upgrade-cleanup plugin only when the user explicitly asks
("finish the upgrade", "clean up dual-boot", "drop the NextRails branches")
3. The cleanup plugin removes NextRails.next? / NextRails.current? branches
and retires dual-boot scaffolding. Deprecation triage stays with this
skill for the next hop, not with cleanup.
Sample wording the agent can crib from when prompting the user:
Rails X.Y is in. When you're ready to remove dual-boot scaffolding (drop
NextRails.next?/NextRails.current?branches, retireGemfile.next), ask me to clean up. If you're heading straight to the next hop, keeping dual-boot in place is also fine.
Before starting ANY upgrade:
Note: This step is now automated. Claude will run the test suite and BLOCK the upgrade if any tests fail.
bundle outdatedUser says: "Upgrade my Rails app to 8.1"
Action - Step 0 (MANDATORY: Verify Latest Patch):
Gemfile.lock for exact Rails versionreferences/multi-hop-strategy.md)Action - Step 1 (MANDATORY: Verify Tests Pass):
workflows/test-suite-verification-workflow.mdbundle exec rspec or bundle exec rails testAction - Step 2 (Set Up Dual-Boot):
dual-boot skill for setupAction - Step 3 (Validate Upgrade Path):
Action - Step 4 (Run Detection Directly):
workflows/direct-detection-workflow.mddetection-scripts/patterns/rails-{VERSION}-patterns.ymlAction - Step 4.5 (Check Gem Compatibility):
workflows/gem-compatibility-workflow.md and follow itbundle_report compatibility); escalate to railsbump only when the workflow's conditions triggerreferences/gem-compatibility.md for the fork/replace/vendor playbookAction - Step 5 (Generate Reports):
workflows/upgrade-report-workflow.mdworkflows/app-update-preview-workflow.mdAction - Step 6 (Implement & Upgrade):
kind: breaking and kind: deprecation). Most fixes are direct rewrites — the new API typically works on both sides of the dual-boot pair (e.g., update_attributes → update). Use NextRails.next? only when the fix requires target-version-only APIs that don't exist in the current Railsworkflows/ci-sync-workflow.md) — fix any mismatches before declaring Step 6 completeAction - Step 7 (Align load_defaults - FINAL):
rails-load-defaults skillUser says: "Help me upgrade from Rails 5.2 to 8.1"
Action - Step 0 (MANDATORY: Verify Latest Patch):
Gemfile.lockAction - Step 1 (MANDATORY: Verify Tests Pass):
Action - Step 2 (Set Up Dual-Boot):
dual-boot skill for setup (if not already set up)Action - Step 3 (Plan & Execute):
references/multi-hop-strategy.mdUser says: "What breaking changes affect my app for Rails 8.0?"
This pattern is analysis-only — it intentionally skips Step 2 (Dual-Boot setup) and Step 3 (Validate Upgrade Path) because the user is not yet committing to an upgrade.
Action - Step 0 (MANDATORY: Verify Latest Patch):
Action - Step 1 (MANDATORY: Verify Tests Pass):
Action - Step 4 (Run Detection):
workflows/direct-detection-workflow.mdBefore delivering, verify:
For Direct Detection:
For Comprehensive Upgrade Report:
kind: breaking and kind: deprecation) and fix-when-ready (kind: migration and kind: optional) — with real file:line referencesFor CI Config Check (Step 6, before opening the PR):
For app:update Preview:
NextRails.next? for Dual-Boot Code (NEVER use respond_to? for version branching. DELEGATE to the dual-boot skill for patterns and setup.)workflows/ci-sync-workflow.md to make sure every CI file matches the upgraded Gemfile — stale CI is the most common cause of red builds on upgrade PRs)upgrade-cleanup plugin. Delegate to it only when the user explicitly asks: "finish the upgrade", "clean up dual-boot", "drop the NextRails branches". Cleanup removes NextRails.next? / NextRails.current? branches and retires dual-boot scaffolding. Deprecation triage stays with this skill for the next hop.)A successful upgrade assistance session:
✅ Verified latest patch version (Step 0 - MANDATORY)
✅ Upgraded to latest patch if needed (before any minor/major hop)
✅ Ran test suite (Step 1 - MANDATORY)
✅ Verified all tests pass (blocked if tests failed)
✅ Recorded baseline metrics (test count, coverage)
✅ Set up dual-boot (Step 2 - early, before upgrading)
✅ Validated upgrade path (Step 3 - single-hop vs multi-hop, hops planned)
✅ Ran detection directly (using Grep/Glob/Read tools - no script)
✅ Generated Comprehensive Upgrade Report using actual findings
✅ Generated app:update Preview using actual config files
✅ Used user's actual code from findings (not generic examples)
✅ Flagged all custom code with ⚠️ warnings based on detected issues
✅ Implemented changes and upgraded Rails version
✅ Verified CI config matches the upgraded Gemfile (Ruby, Rails matrix, services — all mismatches fixed before opening the PR)
✅ Aligned load_defaults (after upgrade is complete)
✅ Mentioned cleanup after the upgrade shipped (pointed to the upgrade-cleanup plugin without auto-running it; delegated only when the user explicitly asked)
✅ Provided clear next steps
✅ Offered to help implement changes
See CHANGELOG.md for version history and current version.
npx claudepluginhub ombulabs/claude-skills --plugin upgrade-cleanupAnalyzes Rails app structure and dependencies to produce targeted upgrade guidance, diff summaries, and checklist for version jumps.
Applies end-to-end Ruby/Rails upgrades: bumps versions, updates gems, fixes deprecations/code, Rails config, iterates RSpec/RuboCop green, verifies, commits. Use /fix or 'next' from plan.
Guides framework and language migrations: version upgrades, breaking changes, dependency audits, codemods, rollbacks. For React 19, Next.js App Router, Python 3.12, Node 22, etc.