Use when upgrading a Rails application from one version to another, assessing upgrade readiness, planning a multi-hop upgrade path, or investigating breaking changes, deprecation warnings, gem compatibility issues, or config.load_defaults transitions between any Rails versions from 5.2 through the latest release.
76
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
This skill provides a systematic workflow for upgrading Rails applications, covering versions 5.2 through the latest release. It fetches live configuration diffs from railsdiff.org via the GitHub API, performs direct codebase detection using Grep, Glob, and Read tools, and compiles structured upgrade reports — all without requiring external skill dependencies.
Announce at start: "I'm using the rails-upgrade skill to guide this upgrade."
Last verified against rails/rails on 2026-08-13.
| Series | Latest patch | Status |
|---|---|---|
| 8.1.x | 8.1.3.1 | Current stable |
| 8.0.x | 8.0.5.1 | Maintained (bug + security) |
| 7.2.x | 7.2.3.2 | Security fixes only |
| 8.2 | 8.2.0.alpha (main) | In development — see the 8.1 → 8.2 sections in the references |
Anything older than 7.2 is unsupported upstream and receives no security patches.
Always resolve the exact target patch, never just the minor. Check
https://rubygems.org/api/v1/versions/rails.json (or gem list rails --remote --all)
and target the newest patch in the target series. Upgrading to 8.1.0 when 8.1.3.1
exists leaves known CVEs unpatched.
| Rails | Minimum Ruby | Recommended Ruby |
|---|---|---|
| 5.2 | 2.2.2 | 2.5+ |
| 6.0–6.1 | 2.5.0 | 2.7+ |
| 7.0–7.1 | 2.7.0 | 3.1+ |
| 7.2 | 3.1.0 | 3.3+ |
| 8.0–8.1 | 3.2.0 | 3.3+ |
| 8.2 (unreleased) | 3.3.1 | 3.4+ |
Rails 8.2 raises the Ruby floor to 3.3.1. Apps on Ruby 3.2 must bump Ruby before they can move past 8.1. Upgrade Ruby first, on the current Rails version, so the two changes are debugged separately.
Gemfile and Gemfile.lock to find the current Rails gem versionconfig/application.rb to find the current config.load_defaults value.ruby-version or Gemfile for the Ruby version — verify against the compatibility table aboveHARD GATE: Applies to every app that uses Active Storage with the vips variant processor.
CVE-2026-66066 (critical) — arbitrary file read and possible RCE via crafted image uploads.
Fixed in 8.1.3.1, 8.0.5.1, 7.2.3.2.An app is affected when both are true:
config.active_storage.variant_processor is :vips — this is the default from
load_defaults 7.0 onward and no later default changed itChecks to run before the upgrade:
variant_processor in config/ — absence means the :vips default appliesvips --version. Rails raises at boot on libvips < 8.13
after the fix, because older libvips cannot block unfuzzed operations at all.
Upgrading libvips is a prerequisite, not a follow-up.ruby-vips in Gemfile.lock — needs >= 2.2.1 for the in-process
Vips.block_untrusted(true) pathvariable_content_types and plan
a fallback before deploying.secret_key_base, the master key, and every credential reachable from
the app process. Upgrading closes the hole; it does not un-leak a secret.Source: GHSA-xr9x-r78c-5hrm
HARD GATE: Run the test suite before ANY upgrade work.
If tests fail: STOP. Report failures. Do NOT proceed until baseline is green.
A failing baseline makes post-upgrade failures ambiguous.spec/ (RSpec) or test/ (Minitest)bundle exec rspec or bundle exec rails testFetch the live config diff from railsdiff.org via its GitHub data source:
URL: https://api.github.com/repos/railsdiff/rails-new-output/compare/v{CURRENT}...v{TARGET}Example: https://api.github.com/repos/railsdiff/rails-new-output/compare/v7.2.0...v8.0.0
Use WebFetch with this prompt: "List every file that changed between these versions. For each file: its name, status (added/modified/removed), and a 1-2 sentence summary of what changed."
Categorize results into:
config/, config/environments/, config/initializers/)Dockerfile, bin/, Gemfile template)Fallback if API fetch fails: Note it, proceed using references/detection-patterns.md and references/breaking-changes.md static data only.
For multi-step upgrades: Fetch the diff only for the current hop being executed.
references/detection-patterns.mdreferences/gem-compatibility.md — check Gemfile.lock for gems with known issuesskills/rails-guides/references/upgrading_ruby_on_rails.md for the relevant "Upgrading from X to Y" sectionHARD GATE: Verify config.load_defaults status before proceeding.
If new_framework_defaults_*.rb exists with uncommitted changes from a PREVIOUS upgrade: STOP.
Those must be resolved before starting a new upgrade.config/application.rb — confirm the config.load_defaults valueconfig/initializers/new_framework_defaults_*.rbreferences/load-defaults-guide.md for the relevant version transitionCompile all findings into a structured report BEFORE making any changes:
## Rails Upgrade Report: {CURRENT} → {TARGET}
### Environment
- Current Rails: {version}
- Target Rails: {version}
- Ruby: {version} (compatible: yes/no)
- Test baseline: {N} tests, all passing
### Configuration Changes (from railsdiff.org)
{Categorized list from Step 2, or "Could not fetch — using static reference" if API failed}
### Code Changes Required
#### Must Fix Before Version Bump
{Findings from Step 3 with file:line references}
#### Must Fix After Version Bump (Deprecations Becoming Errors)
{Findings}
#### Deprecation Warnings to Address
{Findings}
### Gem Updates Required
| Gem | Current | Required | Notes |
|-----|---------|----------|-------|
{From Step 3 gem check}
### load_defaults Transition Plan
{From Step 4}
### Recommended Approach
- Direct upgrade (changes are minimal) OR
- Dual-boot with next_rails (changes are substantial — see references/dual-boot-guide.md)
### Estimated Effort
{Based on number and severity of findings}HARD GATE: Present the upgrade report to the user and get explicit approval.
Do NOT modify any files until the user approves the report.Execution sequence after approval:
git checkout -b rails-{TARGET}-upgradebundle update rails (fix conflicts as they arise)bin/rails app:update (review each change, do not auto-accept)config.load_defaults per the transition plan from Step 4When jumping more than one minor version (e.g., 6.1 → 8.0):
config.load_defaults is updated before moving onreferences/breaking-changes.mdUse dual-boot (next_rails gem) when:
Skip dual-boot when:
Rails 8.2 is 8.2.0.alpha on main and has not been released. Do not upgrade a
production app to it. The 8.1 → 8.2 material in the references exists for two reasons:
When a user asks about 8.2, say it is unreleased, then use the references to list what to
clear while still on 8.1. Re-verify against main before relying on any of it — unreleased
content changes, and at least one 8.1 feature (alphabetical schema.rb columns) was already
reverted on main.
To refresh the 8.2 picture:
./scripts/fetch-changelogs.sh main ./changelogsSee references/dual-boot-guide.md for setup.
| File | Contents |
|---|---|
references/breaking-changes.md | Breaking changes by version pair (5.2 → 8.2), HIGH/MEDIUM/LOW tables |
references/deprecation-timeline.md | When deprecations were introduced, warned, and removed (through 9.0 targets) |
references/gem-compatibility.md | ~50 popular gems with required versions per Rails release |
references/load-defaults-guide.md | Every load_defaults setting 5.2 → 8.2, risk tiers, transition guidance |
references/detection-patterns.md | Grep/Glob patterns for code-level detection, organized by version pair |
references/dual-boot-guide.md | next_rails dual-boot setup, NextRails.next? patterns, CI config |
references/troubleshooting.md | Common upgrade errors and their solutions |
scripts/fetch-changelogs.sh | Fetches component CHANGELOGs from GitHub for any version or main |
Also cross-references:
skills/rails-guides/references/upgrading_ruby_on_rails.md — Official Rails upgrading guide (3,000+ lines)Based on work by:
Both used under MIT license. Original sources:
99fac3d
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.