关于 rails-upgrade
rails-upgrade 是用于指导 Rails 应用升级的技能,覆盖 5.2 及之后的版本。它结合版本与 Ruby 兼容性检查、代码检测和分阶段报告,并要求获批后才修改文件。
主要功能
- 01Rails 与 Ruby 兼容性评估
- 02获取实时配置差异
- 03检测代码升级模式
- 04规划 load_defaults 迁移
- 05经批准后执行升级
适用场景
- 01规划 Rails 版本升级
- 02查找代码与 gem 兼容性问题
- 03准备跨多个版本的升级路径
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ lucianghinda/ superpowers-ruby --skill rails-upgrade安装后在 Claude Code 中输入/rails-upgrade确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/breaking-changes.mddeprecation-timeline.mddetection-patterns.mddual-boot-guide.mdgem-compatibility.mdload-defaults-guide.mdtroubleshooting.mdscripts/fetch-changelogs.sh详细介绍
Rails 升级
概述
此技能提供了系统化的 Rails 应用升级工作流,涵盖从 5.2 到最新版本。它通过 GitHub API 从 railsdiff.org 获取实时配置差异,使用 Grep、Glob 和 Read 工具直接检测代码库,并生成结构化升级报告——无需依赖外部技能。
开始时请声明:“我将使用 rails-upgrade 技能来指导此次升级。”
版本发布概况
最后一次依据 rails/rails 验证:2026-08-13。
| 系列 | 最新补丁版本 | 状态 |
|---|---|---|
| 8.1.x | 8.1.3.1 | 当前稳定版 |
| 8.0.x | 8.0.5.1 | 维护中(错误修复 + 安全更新) |
| 7.2.x | 7.2.3.2 | 仅提供安全修复 |
| 8.2 | 8.2.0.alpha (main) | 开发中——请参阅参考资料中的 8.1 → 8.2 部分 |
低于 7.2 的版本均已不受上游支持,也不会获得安全补丁。
始终确认精确的目标补丁版本,不要只确认次版本。 检查
https://rubygems.org/api/v1/versions/rails.json(或运行 gem list rails --remote --all),
并将目标设为目标系列中最新的补丁版本。如果存在 8.1.3.1,却只升级到 8.1.0,
已知的 CVE 就不会得到修复。
Ruby 版本兼容性
| Rails | 最低 Ruby 版本 | 推荐 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(未发布) | 3.3.1 | 3.4+ |
Rails 8.2 将 Ruby 最低版本提高到 3.3.1。使用 Ruby 3.2 的应用必须先升级 Ruby, 才能升级到高于 8.1 的 Rails 版本。请先在当前 Rails 版本下升级 Ruby, 以便分别排查这两项变更的问题。
工作流
步骤 0:版本评估
- 阅读
Gemfile和Gemfile.lock,确认当前 Rails gem 版本 - 阅读
config/application.rb,确认当前config.load_defaults值 - 检查
.ruby-version或Gemfile中的 Ruby 版本,并对照上方兼容性表进行验证 - 如果用户未指定目标版本,请向用户确认
- 将目标版本确定为精确的补丁版本(参见上方“版本发布概况”)——目标系列中的最新补丁版本
- 如果升级跨度超过一个次版本,请规划逐步升级路径(例如,7.0 → 8.0 需要经过 7.0 → 7.1 → 7.2 → 8.0)
- 输出:版本评估摘要(当前 Rails、当前 Ruby、目标 Rails 补丁版本、所需 Ruby 版本、升级路径)
步骤 0.5:Active Storage / libvips 安全检查
HARD 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.
同时满足以下条件时,应用会受到影响:
config.active_storage.variant_processor为:vips——这是从load_defaults 7.0开始的默认值,之后的默认值也未更改此设置- 应用接受来自不受信任用户的图片上传
升级前需要执行以下检查:
- 在
config/中搜索variant_processor——如果未找到,则表示适用:vips默认值 - 检查已安装的 libvips:
vips --version。修复之后,Rails 在 libvips 低于 8.13 时会在启动阶段报错,因为旧版 libvips 完全无法阻止未经模糊处理的操作。 升级 libvips 是前置要求,不是后续步骤。 - 检查
Gemfile.lock中的ruby-vips——对于进程内的Vips.block_untrusted(true)路径,需要>= 2.2.1 - 警告用户:生成 BMP、ICO 和 PSD 格式的变体现在会报错。如果应用
会提供这些类型的变体,请将它们从
variable_content_types中移除,并在部署前规划备用方案。 - 如果应用运行的是受影响版本,且接受过不受信任的上传,请告知用户轮换
secret_key_base、主密钥,以及应用进程可以访问的所有凭据。升级可以堵住漏洞, 但无法撤回已经泄露的机密。
步骤 1:测试套件验证
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)或test/(Minitest) - 运行:
bundle exec rspec或bundle exec rails test - 记录:测试总数、通过数、失败数、待处理数
- 如果有任何失败:停止,报告失败情况,并提出协助修复
- 如果全部通过:记录为基准,然后继续步骤 2
步骤 2:配置差异(railsdiff.org)
通过 GitHub 数据源从 railsdiff.org 获取实时配置差异:
URL: https://api.github.com/repos/railsdiff/rails-new-output/compare/v{CURRENT}...v{TARGET}
示例:https://api.github.com/repos/railsdiff/rails-new-output/compare/v7.2.0...v8.0.0
使用 WebFetch 并附上以下提示词:“列出这些版本之间所有发生变化的文件。对于每个文件,请提供文件名、状态(新增/修改/删除)以及 1-2 句变更摘要。”
将结果分类为:
- 变更的配置文件(
config/、config/environments/、config/initializers/) - 基础设施文件(
Dockerfile、bin/、Gemfile模板) - 资源管道变更
- 新增文件(目标版本新增)
- 删除的文件
**API 获取失败时的备用方案:**注明此情况,仅使用 references/detection-patterns.md 和 references/breaking-changes.md 中的静态数据继续操作。
**多步升级:**仅获取当前正在执行的跃迁所对应的差异。
步骤 3:代码级检测
- 阅读
references/detection-patterns.md中相关版本的章节 - 对于每种模式,直接使用 Grep 工具在指定路径中搜索该模式
- 收集发现,并附上文件:行号引用和匹配内容
- 阅读
references/gem-compatibility.md— 检查Gemfile.lock中是否包含存在已知问题的 gem - 对照
skills/rails-guides/references/upgrading_ruby_on_rails.md中相关的“从 X 升级到 Y”章节 - 尽可能并行执行搜索(在一条消息中调用多个 Grep)
- 汇总发现:
- 升级前必须修复
- 升级后必须修复
- 需要处理的弃用警告
- 需要更新的 gem
步骤 4:load_defaults 验证
HARD 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— 确认config.load_defaults的值 - 使用 Glob 查找
config/initializers/new_framework_defaults_*.rb - 如果某个文件中存在来自先前升级且未注释的行:停止,先解决这些问题
- 阅读
references/load-defaults-guide.md中相关版本迁移的指南 - 制定 load_defaults 迁移计划:确定哪些设置可以安全启用,哪些需要先修改代码
步骤 5:升级报告
在进行任何更改之前,将所有发现汇总为结构化报告:
## 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}
步骤 6:执行升级
HARD GATE: Present the upgrade report to the user and get explicit approval.
Do NOT modify any files until the user approves the report.
获批后的执行顺序:
- 创建升级分支:
git checkout -b rails-{TARGET}-upgrade - 更新 Gemfile:提升 Rails 版本,并更新已识别的 gem
- 执行
bundle update rails(出现冲突时逐一解决) - 根据步骤 2 的配置差异应用配置变更
- 修复升级前必须解决的代码问题(来自步骤 3)
- 运行测试套件 — 处理失败项
- 运行
bin/rails app:update(逐项审核变更,不要自动接受) - 根据步骤 4 的迁移计划更新
config.load_defaults - 再次运行测试套件
- 尽可能修复剩余的弃用警告
- 报告最终状态和测试结果
多步升级
跨越多个次要版本升级时(例如,6.1 → 7.0 → 7.1 → 7.2 → 8.0):
- 计算所有跃迁:6.1 → 7.0 → 7.1 → 7.2 → 8.0
- 按顺序为每次跃迁执行步骤 0–6
- 当前跃迁的所有测试通过之前,切勿继续下一次跃迁
- 每次跃迁后:确保已更新
config.load_defaults,再继续 - 规划时,参考
references/breaking-changes.md中的难度表
何时使用双重启动
以下情况使用双重启动(next_rails gem):
- 升级难度为高或非常难(7.2 → 8.0、6.1 → 7.0)
- 应用有超过 50k 行代码,或 gem 依赖关系复杂
- 团队需要在升级期间继续发布功能
以下情况跳过双重启动:
- 难度为简单或中等(7.0 → 7.1、8.0 → 8.1)
- 代码库较小(少于 10k 行代码)
- 破坏性变更很少且影响范围有限
升级到 Rails 8.2(尚未发布)
Rails 8.2 在 main 上的版本为 8.2.0.alpha,尚未发布。不要将生产应用升级到此版本。参考资料中的 8.1 → 8.2 内容存在的原因有两个:
- Rails 8.1 的弃用警告会将 8.2 列为移除版本。 若不了解 8.2 对相关功能的处理方式,就无法正确评估 8.1 的弃用项。
- 在 8.1 上做好准备无需额外成本。 每项将在 8.2 中移除的内容,都有适用于 8.1 的修复方案。
用户询问 8.2 时,说明该版本尚未发布,然后使用参考资料列出仍在 8.1 上时需要清理的内容。依赖任何信息前,都要对照 main 重新核实——未发布的内容可能会变化,而且至少有一项 8.1 功能(schema.rb 列按字母顺序排列)已在 main 上撤回。
要更新 8.2 相关信息:
./scripts/fetch-changelogs.sh main ./changelogs
设置方法请参见 references/dual-boot-guide.md。
参考文件
| 文件 | 内容 |
|---|---|
references/breaking-changes.md | 各版本对(5.2 → 8.2)的破坏性变更,按高/中/低风险划分的表格 |
references/deprecation-timeline.md | 弃用项的引入、警告和移除时间(包括目标版本 9.0) |
references/gem-compatibility.md | 约 50 个常用 gem 在各 Rails 版本中所需的版本 |
references/load-defaults-guide.md | 5.2 → 8.2 的所有 load_defaults 设置、风险等级和迁移指导 |
references/detection-patterns.md | 用于代码级检测的 Grep/Glob 模式,按版本对整理 |
references/dual-boot-guide.md | next_rails 双重启动设置、NextRails.next? 模式和 CI 配置 |
references/troubleshooting.md | 常见升级错误及其解决方案 |
scripts/fetch-changelogs.sh | 从 GitHub 获取任意版本或 main 的组件 CHANGELOG |
另请参阅:
skills/rails-guides/references/upgrading_ruby_on_rails.md— Rails 官方升级指南(3,000 多行)
致谢
基于以下项目的工作:
- OmbuLabs.ai / FastRuby.io(MIT)— FastRuby.io 升级方法、检测模式和 gem 兼容性数据
- Mario Alberto Chávez Cárdenas(MIT)— 破坏性变更参考表和弃用时间线格式
两者均依据 MIT 许可证使用。原始来源: