跳转到内容

升级核心包

适用范围:已按 快速开始 创建的独立业务应用,核心通过 modu-sources.json 中的线上私有源安装。以下命令在业务应用根目录 my-app/ 执行,适用于本地开发环境。

更新直接使用线上 Go/npm 包,无需克隆核心仓库,也无需下载新开发包覆盖业务项目。

如果上次更新中断并留下 .modu-update/,先按「失败恢复 B」恢复,不开始新一轮更新。

终端窗口
pnpm server:go list -m github.com/igwen6w/modu/server
pnpm --dir web list @modu/web --depth 0
gh release list --repo igwen6w/modu

记录当前配套版本。向维护者确认目标版本的 Go module、npm 包均已发布,并阅读对应 Release 的变更和迁移说明。

以下示例将已发布的 0.12.0 更新到 0.13.0;目标版本必须是更高的、已发布的精确版本,不带 v 前缀:

终端窗口
MODU_OLD_VERSION='0.12.0'
MODU_TARGET_VERSION='0.13.0'
gh release view "v${MODU_TARGET_VERSION}" --repo igwen6w/modu

如果目标 Release、Go module 或 npm 包任一尚未发布,不执行后续更新。

  1. 在前后端运行终端分别按 Ctrl+C;使用 dev:all 时在该终端按一次。
  2. 停止其他连接此开发库的 worker 和定时任务。
  3. 保存业务源码。已使用 Git 的项目先提交当前修改,再创建自己的更新分支。
  4. 保持数据库可用:
终端窗口
docker compose up -d --wait

更新期间不在同一应用目录启动其他安装、构建或开发进程。

以下数据库命令使用默认 Compose 的服务名 postgres、用户 gorave、数据库 modu_example。修改过配置的应用,先替换为 server/.env 对应的实际值。

终端窗口
umask 077
MODU_BACKUP_DIR="$(cd .. && pwd)/modu-backup-$(date +%Y%m%d-%H%M%S)"
mkdir -m 700 "$MODU_BACKUP_DIR"
printf '%s\n' "$MODU_BACKUP_DIR"
printf '%s\n' "$MODU_OLD_VERSION" > "$MODU_BACKUP_DIR/core-version.txt"
tar --exclude='./node_modules' --exclude='./web/node_modules' \
--exclude='./web/dist' --exclude='./web/src/.umi*' \
--exclude='./server/bin' --exclude='./server/tmp' --exclude='./.git' \
-czf "$MODU_BACKUP_DIR/application.tar.gz" .
docker compose exec -T postgres pg_dump -U gorave -d modu_example \
--format=custom > "$MODU_BACKUP_DIR/database.dump"
docker compose exec -T postgres pg_restore --list \
< "$MODU_BACKUP_DIR/database.dump" > "$MODU_BACKUP_DIR/database-contents.txt"

每条命令成功后再继续。记录打印出的备份目录;新终端中需要重新设置 MODU_BACKUP_DIR。应用备份包含业务源码、依赖文件、.env、密钥和 server/storage/。配置在应用目录之外的上传文件或其他业务存储须另外备份。

pg_restore --list 只检查备份目录可读,不代表完整恢复演练;重要数据先在独立数据库验证恢复。

使用有包读取权限、包含 read:packages 的 GitHub Classic PAT。0.7.2 及之后的模板都提供 core:login,在当前终端执行,出现提示后粘贴 token 并回车:

终端窗口
pnpm core:login

CI 或无法交互的终端改用环境变量方式:

终端窗口
printf '粘贴 GitHub Classic Token(输入隐藏): '
read -rs MODU_NPM_TOKEN
printf '\n'
export MODU_NPM_TOKEN
终端窗口
pnpm core:upgrade --version "$MODU_TARGET_VERSION"

命令沿用已保存的私有源配置,自动完成 Go/npm 配套版本更新、依赖安装、catalog 生成与校验、类型检查、扩展检查和前后端构建。

它不会更新业务源码、覆盖 .env、重新生成密钥,也不会执行数据库迁移或种子。安装失败时先按本文「失败恢复」处理,不继续迁移或启动。

若升级已成功,只因全新检出、清理 web/node_modules 或安装中断而需要重建前端依赖,执行 pnpm core:deps。该入口按 modu-sources.json 加载凭据,按 web/pnpm-lock.yaml frozen 安装,不更新锁文件、不执行 catalog 或生产构建;不要用普通 pnpm --dir web install 代替。

终端窗口
pnpm server:go list -m github.com/igwen6w/modu/server
pnpm --dir web list @modu/web --depth 0

确认两者均为目标版本。检查以下变更:

  • server/go.mod、server/go.sum。
  • web/package.json、web/pnpm-lock.yaml。
  • web/src/extensions/catalog.json。
  • modu-sources.json、web/.npmrc。

按发行说明适配自己的业务代码,并运行业务项目的测试;测试数据库与当前开发库隔离。从 0.12.x 升级到 0.13.0 时,还须先完成下文「数据交换授权回调迁移」及所有扩展的 CoreAPI 适配。若修改了代码,重新执行:

终端窗口
pnpm --dir web typecheck
pnpm --dir web extension:check
pnpm build
pnpm --dir web extension:verify-build

core:upgrade 只更新配套依赖、检查和构建,不执行数据升级;app:setup 仍仅用于首次初始化。确认应用、worker、定时任务全部停止,数据库与文件备份可恢复,server/.env 仍指向本次备份的开发库,先预检:

终端窗口
pnpm --silent app:upgrade --plan --json > upgrade-plan.json

阅读计划、database_fingerprint、baseline 策略、冲突、scope/excluded 和待办;--plan 不写数据库。确认无误后执行:

终端窗口
pnpm --silent app:upgrade --force --json > upgrade-result.json

应用数据升级依次获取升级锁、重新预检、执行待执行迁移、执行经分类审查的 baseline、同步默认菜单并做最终校验。所有环境均不生成 demo 数据、不创建账号、不生成密钥、不更新依赖、不自动授权;--force 仅表示确认操作前提已完成。升级已有应用时不运行 app:setup、server:setup、全量 db:seed、migrate:fresh 或 migrate:reset,保留原有 APP_KEY 和 JWT_SECRET。

app:upgrade 自 0.7.3 起的模板提供;更早的旧应用先按「模板工具的更新」迁移工具后再接入。任一步失败时按输出修复具体对象后重新 --plan / --force,已记录的迁移不重跑。

终端一:

终端窗口
pnpm server:dev

终端二进入同一 my-app/ 目录:

终端窗口
pnpm dev

使用已有账号登录,检查已有业务数据、权限、主要页面和本次修改涉及的功能;验证上传文件等业务资源仍可读取。具有新版入口的应用也可以使用 pnpm dev:all 启动。

升级会使已登录用户的旧 JWT 失效,所有用户需要重新登录一次;数据库中的账号、权限和认证修订原样保留,不要为此重置 JWT_SECRET 或重跑全量种子。

在业务仓库提交依赖声明、锁文件、catalog 和必要的业务适配,记录目标核心版本与迁移结果。不提交 .env、token 或备份数据。

清除当前终端中的 token:

终端窗口
unset MODU_NPM_TOKEN

保留更新前的应用和数据库备份,直到本次验证完成。

重大升级:从 0.11.0 及更早版本进入统一授权

Section titled “重大升级:从 0.11.0 及更早版本进入统一授权”

0.12.0 起核心使用统一授权模型,旧授权 schema 不支持就地转换,也没有自动导入。app:upgrade 的 --plan 与正式执行都会做只读授权 schema 检查,检测到旧 schema 或缺失授权表时直接拒绝,不运行迁移或菜单维护。升级到 0.12.0 及之后的版本(含 0.13.0)须按以下边界操作:

  1. 备份并保留旧库及审计、撤权记录,旧库不动。
  2. 在独立的新数据库安装 0.13.0,完成首次初始化。
  3. 在新库显式安装授权,指定维护者用户 ID:
终端窗口
pnpm server:go run ./cmd/modu authorization install --maintainers 1
  1. 逐项重新配置角色、能力、范围与条件等授权,并完成业务验收。
  2. 验收通过后再切换业务,业务数据搬迁需单独审阅,不能通过修改 schema 标志绕过拒绝。

数据交换授权回调迁移(0.13.0)

Section titled “数据交换授权回调迁移(0.13.0)”

0.13.0 将扩展 CoreAPI 提升至 0.17.0,数据交换扩展的授权回调须同步迁移;此变更没有新增数据库迁移,也不自动补发授权。要点:

  1. Authorize 签名新增 sdk.DataTransferAuthorizationContext 参数:Authorize(ctx, actor, call sdk.DataTransferAuthorizationContext, selection, ids);从 call.Operation 选择实际导入/导出能力,从 call.Phase 区分元数据、模板、上传、预检、提交、执行等阶段。
  2. 事务改用 RequireRequest:回调内用 call.RequireRequest(...) 做真实资源或候选事实判断,Write 中用 tx.RequireRequest(...) 校验当前记录与写后事实。
  3. 移除回调内的 AuthorizedTx / AuthorizedUserTx / HasPermLive / DataTransferVisibleOwnerIDs 等旧调用,否则会等待宿主自己持有的授权门。Validate 只做纯业务校验,涉及权限、引用和可变归属的检查移到 Write。
  4. 完成所有适配后,再把应用扩展 Manifest 的精确 CoreAPI 更新为 0.17.0,重新生成前端 catalog 并构建、验收;仍精确声明旧版本(如 0.16.0)的扩展不能加载到新宿主。

可编译的公开 SDK 示例见核心仓库 starter/server/examples/datatransfer/items.go;完整提交边界见核心仓库 docs/UPGRADING.md 与数据交换协议文档。

  • 0.7.3 要求手工把 web/package.json 的 antd 升到 6.6.4、@ant-design/icons 升到 6.3.4:当时的 core:upgrade 只更新核心声明,不更新宿主 peer 依赖。改完后重新安装并完成登录、表格、弹窗、文件、主题与语言回归。
  • 0.7.1 的 Python 工具须先迁移到 Node ESM:下载并校验 modu-0.7.2-upgrade.tar.gz,按核心仓库维护者说明执行包内 tooling-upgrade.mjs 迁移工具(应用侧对应 pnpm core:tooling-upgrade),再继续后续升级。
  • app:upgrade 自 0.7.3 提供;0.7.2 及更早版本先升级到包含该 API 的核心版本后再接入应用数据升级。

从更早版本升级时逐版本推进,不跨级执行;每个版本先阅读对应 Release 的变更与迁移说明,并保留每步备份。关键节点:

  • 0.7.x → 0.8.0:系统标识改由 /api/v1/branding 与参数配置入口管理;无新增数据库迁移。
  • 0.8 → 0.9.x:AI Agent 与动态结果卡片能力落地,相关启用开关默认关闭。
  • 0.9.x → 0.10:上传与业务附件组件更新。
  • 0.10 → 0.11:RBAC 重构,新增 build-maintenance 等维护命令。
  • 0.11 → 0.12:统一授权的破坏性变更,按上文「重大升级」在独立新库重新安装授权。
  • 0.12 → 0.13:CoreAPI 提升至 0.17.0,数据交换授权回调迁移。

普通失败时,工具会自动恢复依赖文件、源配置和 catalog,但 node_modules、.umi 和构建输出可能已经改变。若恢复后的应用仍使用在线源,重新提供原 registry 对应的凭据后执行:

终端窗口
pnpm core:deps
pnpm build

上述命令严格按已恢复的旧锁文件重装并构建,不重复核心升级流程。若旧应用尚未提供 core:deps,仍可执行 pnpm core:install --version "$MODU_OLD_VERSION"。确认实际 Go/npm 版本后再启动。业务源码适配不在自动恢复范围内;如已修改,恢复对应业务提交或使用应用备份后再安装旧版本。

如果应用目录存在 .modu-update/,执行应用自带的恢复命令,再重装旧版本:

终端窗口
node scripts/online.mjs restore
pnpm core:deps

不要直接删除 .modu-update/;其中保存了更新前的文件。这里调用的是应用自带的 Node 工具,无需编写脚本。

C. 已执行迁移,需要恢复旧环境

Section titled “C. 已执行迁移,需要恢复旧环境”

先停止前后端和所有 worker。恢复旧代码与旧数据库必须配套;仅降级 Go/npm 包不会撤销数据库迁移。

以下命令仍在原 my-app/ 目录执行,使用原 Compose 的 PostgreSQL。设置第 3 步保存的 MODU_BACKUP_DIR;新恢复数据库名会自动生成:

终端窗口
MODU_RESTORE_DB="modu_restore_$(date +%Y%m%d%H%M%S)"
docker compose exec -T postgres createdb -U gorave "$MODU_RESTORE_DB"
docker compose exec -T postgres pg_restore -U gorave \
--dbname="$MODU_RESTORE_DB" --no-owner --exit-on-error \
< "$MODU_BACKUP_DIR/database.dump"
printf '%s\n' "$MODU_RESTORE_DB"

恢复到新数据库,保留发生问题的数据库供排查。然后将旧应用备份解压到一个新的兄弟目录:

终端窗口
mkdir -m 700 ../my-app-restored
tar -xzf "$MODU_BACKUP_DIR/application.tar.gz" -C ../my-app-restored
cd ../my-app-restored
  1. 编辑恢复目录的 server/.env,将 DB_DATABASE 改为刚打印的新数据库名;主机和端口指向仍在运行的原 PostgreSQL。
  2. 保留备份中的应用密钥;恢复应用目录之外的业务文件备份。
  3. 重新配置 npm 读取凭据,执行 pnpm core:install,安装备份中记录的旧版本。
  4. 分别执行 pnpm server:dev 和 pnpm dev,验证旧环境和数据。

恢复目录使用原 Compose 已启动的数据库;不要在恢复目录运行 app:setup 或 dev:all 创建另一套同端口数据库。此恢复会回到备份时间点,备份之后新增的数据需要另行核对处理。

仍使用随附 packages/ 的应用,下载目标版本的 modu-<版本>-upgrade.tar.gz 和配套校验资产,校验后遵循包内 UPGRADE.md 更新核心产物及配套依赖。执行同样的备份、检查、业务回归和应用数据升级,不用开发包覆盖已有业务。首次切换线上源时,先按快速开始配置认证,再用当前配套版本执行带源参数的 core:install。

core:upgrade 更新的是 Go/npm 核心,不会自动给旧应用添加新版模板命令。工具或模板更新须按维护者的独立迁移说明进行,不使用新开发包覆盖整个业务项目。

0.7.2 起的模板工具为 Node 24 原生 ESM,不再依赖 Python。仍在使用 0.7.1 Python 工具的应用,下载并校验 modu-0.7.2-upgrade.tar.gz,解压到应用之外,按包内说明执行 tooling-upgrade.mjs 迁移;迁移前会创建受限快照,迁移后按输出审查并提交 package.json、Node 脚本和代次文件。迁移器核对固定历史指纹,不接触业务源码、环境配置、token、数据库或核心依赖,也不运行 setup、seed 或 migration。

统一授权改造没有提供旧源码项目或生产授权库的自动转换工具。旧架构应用须按对应发行说明单独适配;本页流程用于已经独立消费核心包的应用。