mcpField
R
rails-upgrade

rails-upgrade

github.com/robzolkos开发5447 次安装40 周前更新
代码仓库

关于 rails-upgrade

rails-upgrade 是用于评估 Rails 应用升级的 skill,检查版本差异、官方升级指南、配置变化和 JavaScript 依赖。它强调先识别本地修改,再制定选择性合并计划,避免直接覆盖定制文件。

主要功能

  1. 01核验 Rails 应用与当前版本
  2. 02比较最新版本及升级类型
  3. 03汇总升级指南和文件差异
  4. 04检查 Rails 相关 JavaScript 依赖
  5. 05按本地修改制定选择性合并

适用场景

  1. 01评估 Rails 版本升级复杂度
  2. 02查找升级所需的配置与迁移
  3. 03在升级时保留项目定制内容

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/robzolkos/skill-rails-upgrade --skill rails-upgrade

安装后在 Claude Code 中输入/rails-upgrade确认已加载。

附带文件README.md

详细介绍

Rails 升级分析器

分析当前的 Rails 应用,并提供全面的升级评估,同时选择性合并文件。

步骤 1:验证 Rails 应用

检查当前目录是否为 Rails 应用,确认以下文件是否存在:

  • Gemfile(必须存在且包含“rails”)
  • config/application.rb(Rails 应用配置)
  • config/environment.rb(Rails 环境)

如果缺少其中任何文件,或这些文件表明当前目录并非 Rails 应用,请停止并告知用户:这似乎不是 Rails 应用。

步骤 2:获取当前 Rails 版本

按以下顺序提取当前 Rails 版本:

  1. 首先,检查 Gemfile.lock 中精确的已安装版本(查找 rails (x.y.z))
  2. 如果未找到,则检查 Gemfile 中的版本约束

报告当前的精确版本(例如,7.1.3)。

步骤 3:查找最新 Rails 版本

使用 GitHub CLI 获取最新的 Rails 版本:

gh api repos/rails/rails/releases/latest --jq '.tag_name'

这会返回最新的稳定版本标签(例如,v8.0.1)。比较版本时去掉“v”前缀。

同时检查近期标签,了解版本发布情况:

gh api repos/rails/rails/tags --jq '.[0:10] | .[].name'

步骤 4:确定升级类型

比较当前版本和最新版本,并对升级进行分类:

  • 补丁升级:主版本号和次版本号相同,补丁版本号不同(例如,7.1.3 → 7.1.5)
  • 次版本升级:主版本号相同,次版本号不同(例如,7.1.3 → 7.2.0)
  • 主版本升级:主版本号不同(例如,7.1.3 → 8.0.0)

步骤 5:获取升级指南

使用 WebFetch 获取官方 Rails 升级指南:

URL:https://guides.rubyonrails.org/upgrading_ruby_on_rails.html

查找与版本升级相关的章节。该指南按目标版本组织,包含以下类型的章节:

  • “从 Rails X.Y 升级到 Rails X.Z”
  • 破坏性变更
  • 弃用警告
  • 配置变更
  • 必需的迁移

提取并总结与用户特定升级路径相关的章节。

步骤 6:获取 Rails 差异

使用 WebFetch 从 railsdiff.org 获取版本间的差异:

URL:https://railsdiff.org/{current_version}/{target_version}

例如:https://railsdiff.org/7.1.3/8.0.0

其中展示了:

  • 默认配置文件的变更
  • 需要添加的新文件
  • 已修改的初始化文件
  • 已更新的依赖项
  • bin/ 脚本的变更

总结主要文件变更。

步骤 7:检查 JavaScript 依赖项

Rails 应用通常包含需要随 Rails 一起更新的 JavaScript 包。检查并报告这些依赖项。

7.1:识别 JS 包管理器

检查应用使用的包管理器:

# Check for package.json (npm/yarn)
ls package.json 2>/dev/null

# Check for importmap (Rails 7+)
ls config/importmap.rb 2>/dev/null
7.2:检查与 Rails 相关的 JS 包

如果存在 package.json,请检查以下与 Rails 相关的包:

# Extract current versions of Rails-related packages
cat package.json | grep -E '"@hotwired/|"@rails/|"stimulus"|"turbo-rails"' || echo "No Rails JS packages found"

要检查的主要包:

包用途版本对应关系
@hotwired/turbo-railsTurbo Drive/Frames/Streams应与 Rails 的版本时期相匹配
@hotwired/stimulusStimulus JS 框架通常在不同 Rails 版本间保持稳定
@rails/actioncableWebSocket 支持应与 Rails 版本相匹配
@rails/activestorage直接上传应与 Rails 版本相匹配
@rails/actiontext富文本编辑应与 Rails 版本相匹配
@rails/request.jsRails UJS 的替代方案应与 Rails 的版本时期相匹配
7.3:检查更新

对于 npm/yarn 项目,检查是否有可用更新:

# Using npm
npm outdated @hotwired/turbo-rails @hotwired/stimulus @rails/actioncable @rails/activestorage 2>/dev/null

# Or check latest versions directly
npm view @hotwired/turbo-rails version 2>/dev/null
npm view @rails/actioncable version 2>/dev/null
7.4:检查 Importmap Pins(如适用)

如果应用使用 importmap-rails,请检查 config/importmap.rb 中固定的版本:

cat config/importmap.rb | grep -E 'pin.*turbo|pin.*stimulus|pin.*@rails' || echo "No importmap pins found"

要更新 importmap 固定项:

bin/importmap pin @hotwired/turbo-rails
bin/importmap pin @hotwired/stimulus
7.5:JS 依赖项摘要

在升级摘要中加入:

### JavaScript Dependencies

**Package Manager**: [npm/yarn/importmap/none]

| Package | Current | Latest | Action |
|---------|---------|--------|--------|
| @hotwired/turbo-rails | 8.0.4 | 8.0.12 | Update recommended |
| @rails/actioncable | 7.1.0 | 8.0.0 | Update with Rails |
| ... | ... | ... | ... |

**Recommended JS Updates:**
- Run `npm update @hotwired/turbo-rails` (or yarn equivalent)
- Run `npm update @rails/actioncable @rails/activestorage` to match Rails version

步骤 8:生成升级摘要

提供全面的摘要,包含步骤 1-7 的所有发现:

版本信息
  • 当前版本:X.Y.Z
  • 最新版本:A.B.C
  • 升级类型:[补丁/次版本/主版本]
升级复杂度评估

根据以下因素,将升级评定为小型、中型或大型:

因素小型中型大型
版本跨度仅补丁版本次要版本主要版本
破坏性变更无少量,且有详尽文档许多,影响重大
配置变更极少适中大量
弃用项无待处理项有一些需要处理许多,需要重构
依赖项兼容需要更新一些需要更新主要依赖项
需要处理的关键变更

列出用户需要处理的最重要变更:

  1. 配置文件更新
  2. 需要更新的弃用方法/功能
  3. 新增的必需依赖项
  4. 需要的数据库迁移
  5. 破坏性 API 变更
建议的升级步骤
  1. 更新测试套件并确保测试通过
  2. 检查当前版本中的弃用警告
  3. 使用新的 Rails 版本更新 Gemfile
  4. 运行 bundle update rails
  5. 更新 JavaScript 依赖项(参见 JS Dependencies 部分)
  6. 不要直接运行 rails app:update——请使用下文的选择性合并流程
  7. 运行数据库迁移
  8. 运行测试套件
  9. 检查并更新弃用代码
资源

第 9 步:选择性更新文件(替代 rails app:update)

**重要:**不要运行 rails app:update,因为它会覆盖文件而不考虑本地自定义内容。请改为遵循以下选择性合并流程:

9.1:检测本地自定义内容

开始升级前,先找出包含本地自定义内容的文件:

# Check for uncommitted changes
git status

# List config files that differ from a fresh Rails app
# These are the files we need to be careful with
git diff HEAD --name-only -- config/ bin/ public/

在以下类别中,列出相关文件:

  • 自定义配置文件:包含项目特定设置的文件(i18n、mailer 等)
  • 已修改的 bin 脚本:包含自定义行为的脚本(例如使用 foreman 的 bin/dev)
  • 标准文件:未经过自定义的文件
9.2:分析 railsdiff 中的必要变更

根据第 6 步中 railsdiff 的输出,对每个发生变更的文件进行分类:

类别操作示例
新文件直接创建config/initializers/new_framework_defaults_X_Y.rb
本地未修改可安全覆盖public/404.html(如果未自定义)
本地已自定义需要手动合并config/application.rb、bin/dev
仅注释变更通常跳过配置文件中的少量注释更新
9.3:制定升级计划

向用户提供清晰的升级计划:

## Upgrade Plan: Rails X.Y.Z → A.B.C

### New Files (will be created):
- config/initializers/new_framework_defaults_A_B.rb
- bin/ci (new CI script)

### Safe to Update (no local customizations):
- public/400.html
- public/404.html
- public/500.html

### Needs Manual Merge (local customizations detected):
- config/application.rb
  └─ Local: i18n configuration
  └─ Rails: [describe new Rails changes if any]

- config/environments/development.rb
  └─ Local: letter_opener mailer config
  └─ Rails: [describe new Rails changes]

- bin/dev
  └─ Local: foreman + Procfile.dev setup
  └─ Rails: changed to simple ruby script

### Skip (comment-only or irrelevant changes):
- config/puma.rb (only comment changes)
9.4:执行升级计划

用户确认计划后:

对于新文件:

直接使用 railsdiff 中的内容创建,或从全新的 Rails 应用中提取:

# Generate a temporary fresh Rails app to extract new files
cd /tmp && rails new rails_template --skip-git --skip-bundle
# Then copy needed files

也可以使用 Rails 生成器创建特定文件:

bin/rails app:update:configs  # Only updates config files, still interactive
对于可安全更新的文件:

覆盖这些文件,因为它们没有本地自定义内容。

对于需要手动合并的文件:

对于每个需要合并的文件,向用户展示:

  1. 当前本地版本(用户的自定义内容)
  2. 新的 Rails 默认版本(来自 railsdiff)
  3. 建议的合并版本,该版本:
    • 保留所有本地自定义内容
    • 仅添加必要的新 Rails 功能
    • 移除已弃用的设置

config/application.rb 的合并示例:

# KEEP local customizations:
config.i18n.available_locales = [:de, :en]
config.i18n.default_locale = :de
config.i18n.fallbacks = [:en]

# ADD new Rails 8.1 settings if needed:
# (usually none required - new defaults come via new_framework_defaults file)
9.5:处理 Active Storage 迁移

更新文件后,运行任何新的迁移:

bin/rails db:migrate

检查是否添加了新的迁移:

ls -la db/migrate/ | tail -10
9.6:验证升级

完成合并后:

  1. 启动 Rails 服务并检查错误:

    bin/dev  # or bin/rails server
    
  2. 检查 Rails 控制台:

    bin/rails console
    
  3. 运行测试套件:

    bin/rails test
    
  4. 检查日志中的弃用警告


步骤 10:完成框架默认设置

确认应用正常运行后:

  1. 检查 config/initializers/new_framework_defaults_X_Y.rb
  2. 逐一启用每项新默认设置,并在每次启用后进行测试
  3. 启用并测试所有默认设置后,更新 config/application.rb:
    config.load_defaults X.Y  # Update to new version
    
  4. 删除 new_framework_defaults_X_Y.rb 文件

错误处理

  • 如果 gh CLI 未通过身份验证,请指示用户运行 gh auth login
  • 如果 railsdiff.org 没有确切版本,请尝试使用 major.minor.0 版本
  • 如果应用已经是最新版本,请祝贺用户,并告知即将发布的版本
  • 如果本地自定义内容会丢失,务必先停止,并在继续之前向用户展示哪些内容会被覆盖

关键原则

  1. 未经检查,绝不覆盖——始终先检查本地自定义内容
  2. 尊重用户意图——本地自定义内容都有其存在的理由
  3. 尽量减少改动——只添加新 Rails 版本所必需的内容
  4. 保持透明——准确告知用户将进行哪些更改
  5. 可逆性——如有需要,用户应能通过 git checkout 恢复

评论

支持 Markdown