关于 spree-upgrade
spree-upgrade 是面向 Spree 应用维护者的升级指南,覆盖依赖更新、数据库迁移和版本数据回填。它介绍 CLI 与原生 Rails 命令、回填计划和重试方式,并指出需手动处理的升级事项。
主要功能
- 01说明升级的依赖、迁移与回填阶段
- 02使用 CLI 或 Rails 命令执行升级
- 03预览回填步骤并指定版本范围
- 04单独重试失败的回填步骤
- 05说明生产部署与手动检查事项
适用场景
- 01规划 Spree 版本升级步骤
- 02部署时运行版本数据回填
- 03失败后重试指定回填任务
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ spree/ agent-skills --skill spree-upgrade安装后在 Claude Code 中输入/spree-upgrade确认已加载。
详细介绍
升级 Spree
每次 Spree 升级都分为相同的三个阶段:
- 升级 gems — 对
spree*gems 执行bundle update。 - 迁移架构 — 从 gems 复制新的迁移文件(
spree:install:migrations),然后运行db:migrate。 - 回填数据 —
rake spree:upgrade会运行spree_core中升级清单列出的特定版本数据任务。
然后是第四个手动阶段:查看对应升级路径的升级指南(行为变更、配置迁移、需要编辑的代码)。可通过 rake 运行的部分永远无法涵盖所有内容。
从 5.x 升级到 6.0? 这是一次有前置条件的重大破坏性升级(必须先使用 5.6、Rails 8.1、替换 Gemfile、将角色作为数据处理)。开始之前请阅读 spree-upgrade-5-to-6 skill。
选择适用方式
| 项目 | 运行方式 |
|---|---|
create-spree-app(Docker + @spree/cli,Rails 应用位于 server/ — 较旧项目位于 backend/) | spree upgrade |
| 在仓库根目录使用 Spree gems 的经典 Rails 应用(没有 Docker/CLI) | 使用下方的原生命令 |
| 生产环境(任一方式) | 使用部署流水线 + bundle exec rake spree:upgrade |
CLI(create-spree-app)
spree upgrade --plan # list the backfill steps a run would execute; runs nothing
spree upgrade # bundle update spree* → install migrations + db:migrate → rake spree:upgrade
spree upgrade 会在运行 bundle update 和迁移之前提示确认(回答 No 可跳过其中一项)。使用 --yes 可跳过提示,适用于非交互式场景。rake 数据回填始终会运行。
它需要已弹出配置的开发栈。新建项目会运行预构建的 ghcr.io/spree/spree 镜像,且不绑定源代码目录,因此在其中运行 bundle update 无法修改你的 server/Gemfile.lock,复制的迁移文件也不会放入 server/db/migrate/。请先运行 spree eject(切换到从源代码构建的 compose),然后再升级。
如果在 monorepo 边缘项目中运行(.env 中设置了 SPREE_PATH),CLI 会拒绝运行 — 请在 monorepo 根目录使用 pnpm server:* 脚本。
原生方式(经典 Rails 应用,或没有 CLI)
bundle update spree spree_core spree_api spree_emails # + spree_dashboard and any spree_* extensions you use
bin/rails spree:install:migrations db:migrate
DRY_RUN=1 bundle exec rake spree:upgrade # plan
bundle exec rake spree:upgrade # run the backfills
CLI 标志与 rake 任务的环境变量一一对应:--plan → DRY_RUN=1,--step <id> → STEP=<id>,--to <x.y> → TO=<x.y>。
rake spree:upgrade 的工作方式
- 清单位于 gem 中的
spree_core/lib/spree/upgrades/<from>_to_<to>/manifest.yml(点号会变为下划线:5_6_to_6_0)。每个清单都按顺序列出步骤:id、name、task(rake 任务)、notes,以及可选的optional: true(如果任务未定义则跳过,例如你没有安装对应的 provider gem)。 - 正常运行会按从旧到新的顺序,遍历 每个
to小于或等于已安装次版本的清单。如果应用漏掉了两版之前的数据回填,运行时会自动补上。 - 每个步骤都必须是幂等的 — 在已升级的应用上重新运行整个任务应安全地不执行任何操作。因此它可以安全地作为发布阶段命令运行。
- 清单只包含数据回填。
bundle update、迁移、cron/周期性任务和代码更改都不会包含在内。
列出已安装 gem 中提供的内容:
spree exec sh -c 'ls "$(bundle info spree_core --path)/lib/spree/upgrades/"'
# classic: ls "$(bundle info spree_core --path)/lib/spree/upgrades/"
先制定计划
spree upgrade --plan # or: DRY_RUN=1 bundle exec rake spree:upgrade
按顺序打印实际运行会执行的每个步骤(id、rake 任务、备注)— 计划模式使用与实际运行相同的清单选择逻辑(每个 to 小于或等于已安装次版本的清单;如果指定了 --to,则为每个 to 小于或等于该版本的清单)。不会执行任何操作,也会跳过 bundle 和 migrate 前置步骤。
计划会从已安装的 gem 中读取清单,因此请先升级 gems — 5.6 bundle 不包含 5.6 → 6.0 的清单。
重试单个步骤
部分失败后,修复原因并仅重新运行该步骤(跳过 bundle + migrate):
spree upgrade --step migrate_returns # or: STEP=migrate_returns bundle exec rake spree:upgrade
步骤 id 来自计划输出。如果两个清单中存在相同的 id,任务会中止并要求使用 TO= 消除歧义。有些任务会使用自己的环境变量参数(BATCH_SIZE、SKIP_INVALID_ROWS=true,……)— 这些参数记录在每个步骤的 notes 中;请以相同方式传入(spree rake spree:upgrade STEP=… BATCH_SIZE=200,或 spree exec env BATCH_SIZE=200 bin/rake …)。
你也可以直接调用底层任务 — spree rake <task> / bundle exec rake <task> — 这对于不在任何清单中的任务很方便。
限定版本上限
spree upgrade --to 5.6
符合条件的清单是指 to ≤ 上限的清单。当你要先升级到中间版本,再继续升级到下一版本时,这很有用(5.x 应用必须先升级到 5.6,才能升级到 6.0)。
它不会做什么
- 扩展升级。
spree upgrade会升级每个已安装的spree*gem(它会在容器中通过bundle list --name-only列出这些 gem),但每个扩展自己的迁移、安装生成器和破坏性变更都需要你自行处理——请查阅其 CHANGELOG。扩展必须有与目标 Spree 版本兼容的发行版,否则bundle update将无法解析依赖。 - 定期任务/配置。 新增的定时任务(Solid Queue
config/recurring.yml,或你的 Sidekiq/cron 配置)、迁移的设置项和新增的环境变量会列在升级指南中,而非清单中。 - 你的代码。 引用已重命名或移除 API 的装饰器、订阅者、工作流钩子、仪表板插件和店面代码都必须手动审查。此插件中的
/spree:audit-upgrade命令会执行只读的就绪情况检查。 - SDK。 前端软件包(
@spree/sdk、@spree/admin-sdk、@spree/dashboard)需要通过你自己的软件包管理器升级——CLI 会在“Next steps”面板中打印apps/storefront的@spree/sdk版本,以作提醒。
在生产环境中
不要在生产环境中运行 spree upgrade——它是开发用 CLI。你的部署流程已经会执行 bundle install 和 db:migrate(starter 的 Docker entrypoint 会在启动时运行 bin/rails db:prepare)。将回填任务作为另一条命令添加:
bundle exec rake spree:upgrade
将其配置为发布阶段命令(Heroku)、部署前命令(Render)、init 容器/Job(Kubernetes)或部署后钩子(Kamal、Capistrano)。由于每个步骤都是幂等的,在每次部署时运行都安全且开销很低,数据迁移完成后尤其如此。
顺序很重要:迁移 → 回填 → 启动新代码。有些步骤是迁移的安全保障,有些则必须在后续迁移之前运行(相关说明中会注明)。对于跨越多个版本的大幅升级,请在维护窗口中或针对已恢复的副本运行回填任务,以测量耗时——多个任务支持 BATCH_SIZE。
检查清单
- 备份数据库。
- 阅读对应升级路径的升级指南:
node_modules/@spree/docs/dist/developer/upgrades/<from>-to-<to>.md或 https://spreecommerce.org/docs/developer/upgrades。 - 升级 gems(和扩展),运行迁移。
- 运行
spree upgrade --plan→ 阅读每个步骤的说明。 - 运行回填任务;使用
--step重新运行失败的步骤。 - 按照指南完成手动操作;运行测试套件;升级 SDK。
- 在发布阶段通过
bundle exec rake spree:upgrade进行部署。
注意事项
- **
--plan没有输出(或只显示旧清单)**表示 gems 尚未升级——计划取自已安装的spree_core。 - 容器中的
bundle update失败 → 你正在使用预构建镜像;请先运行spree eject,否则说明 bundle 不同步(spree bundle install)。 - 某个步骤有意中止。 多个 6.0 任务会拒绝继续处理无法忠实转换的数据(例如
migrate_users_to_customers、migrate_returns),并打印有问题的 ID 以及用于覆盖此行为的环境变量。请阅读提示信息;不要盲目重试。 - 绝不要跳过版本。 清单假定使用其
from版本的架构。跨越多个次版本升级没有问题(升级路径会补齐中间版本);但不能跳过必需的过渡版本(例如,升级到 6.0 前必须先升级到 5.6)。
延伸阅读
node_modules/@spree/docs/dist/developer/upgrades/— 各升级路径的升级指南node_modules/@spree/docs/dist/developer/cli/quickstart.md—spree upgrade参考- https://spreecommerce.org/docs/developer/upgrades
- 相关技能:spree-upgrade-5-to-6、spree-cli、spree-deployment、spree-extensions