• v0.7.2 2433cd22a5

    zijunchiang released this 2026-09-17 01:49:53 +08:00 | 13 commits to main since this release

    OpenDance Studio -- Web 管理服务端 v0.7.2

    ⚠️ 请务必升级到本版:v0.7.0 / v0.7.1 的产物启动不起来(详见第一条)。
    本版同时修正 /health 在正式部署下报错版本号的问题。

    本版不含契约变更(仍为 rest-api 0.5.0 / websocket-keypoints 0.2.0 / data-models 0.7.0 /
    skeleton-topology 0.2.0 / model-formats 0.5.0 / database 0.4.0)与接口行为变更。

    一、【致命】CatalogModule 漏 import ScenesModule:产物「装得上、起不来」

    CatalogService 因为 catalog/export 要下发 scenes[] 而注入了 ScenesService,
    但 CatalogModule 的 imports 里只列了 SongsModule / MotionsModule / ModelsModule。
    Nest 的 DI 是按模块解析的,于是:

    UnknownDependenciesException: Nest can't resolve dependencies of the CatalogService
    (SongRepository, MotionRepository, CharacterModelRepository, SongsService, MotionsService,
     ModelsService, ?, AppConfig). Please make sure that the argument ScenesService at index [6]
     is available in the CatalogModule module.
    

    node dist/main.js 在 bootstrap 阶段就退出,服务完全起不来。

    为什么之前三层检查全绿却没发现:

    检查 为什么没抓到
    nest build / tsc --noEmit 模块 import 缺失是运行时 DI 问题,类型系统看不出来
    258 项单元测试 直接 new 服务或测纯函数,从不编译 AppModule
    打包脚本的产物完整性校验 只校验文件清单与压缩包结构,不启动服务

    修复:CatalogModule.imports 补上 ScenesModule。

    新增防线(同时挂进 npm run verify 与打包脚本):

    • scripts/check-bootstrap.mjs:以正式部署方式(ExecStart=node dist/main.js、
      不带任何 npm 环境变量、不需要数据库)拉起真实产物,断言
      ①日志里没有依赖解析类错误②启动日志里的应用版本等于 package.json
      ③启动确实推进到数据库连接阶段。
      已做反向验证:把 ScenesModule 删除后该检查立刻失败。

    二、/health 的 version 在正式部署下永远是 0.1.0

    原实现:process.env.npm_package_version ?? '0.1.0'。

    该变量只在通过 npm 脚本启动时才存在,而本项目的正式部署方式是原生服务
    (systemd / OpenRC / initd,ExecStart=node dist/main.js)—— npm 不参与,
    于是它恒为 undefined,/health 就回退到硬编码的 0.1.0。
    这与「管理端左下角展示 vX.Y.Z,且必须与 GET /health 的 version 一致」
    (文档 §11.2 第 4 条)直接冲突。

    修复:

    • 新增 src/config/app-version.ts 作为版本号的运行时唯一解析点,按优先级尝试
      APP_VERSION 环境变量 → 运行入口旁的 package.json → 工作目录的
      package.json → npm_package_version,每一步都做包名校验
      (必须是 opendance-web-server,避免读到上层仓库的 package.json);
      全都拿不到时返回显式的 0.0.0,绝不伪装成某个具体版本;
    • /health 改为 version: resolveAppVersion();
    • main.ts 启动首行也打印 应用版本 vX.Y.Z,即使数据库连不上、进程退出,
      日志里也一定能看到本次运行的版本号。

    新增防线:

    • scripts/check-version.mjs(并入 npm run contracts:check)校验
      web-server/package.json = admin/package.json = project.yaml,并用正则
      禁止 health.controller.ts 再出现硬编码版本回退;管理端已构建时还会断言
      产物 JS 内确实含 vX.Y.Z;
    • test/app-version.spec.ts 12 项,其中一项显式模拟无 npm 环境变量的原生部署。

    校验(全部通过)

    检查 结果
    npm run contracts:check 契约六项版本一致 + 35 条路由一致 + 版本一致性一致
    npx tsc --noEmit 通过
    npx vitest run 19 文件 / 258 项全通过
    nest build 通过
    启动冒烟 npm run bootstrap:check 通过(见上)
    对发布产物解压后的实测 解压 tarball → npm ci --omit=dev(与 install.sh 同一步骤)→ env -u npm_package_version node dist/main.js:打印 应用版本 v0.7.2,全部模块 dependencies initialized,随后因本机没有 MySQL 而止于 ECONNREFUSED(预期)

    opendance-web-v0.7.2.tar.gz sha256: f04ecc85d17517ec00754238616eb1237cdb2fe17440af6dce731827c0922b26

    部署与部署后自检

    curl -fLO https://gitea.kasugano.cn/zijunchiang/opendance-web/releases/download/v0.7.2/opendance-web-v0.7.2.tar.gz
    curl -fLO https://gitea.kasugano.cn/zijunchiang/opendance-web/releases/download/v0.7.2/SHA256SUMS
    sha256sum -c SHA256SUMS
    tar -xzf opendance-web-v0.7.2.tar.gz && cd opendance-web-v0.7.2
    bash deploy/install.sh
    
    # 部署后必须做到「可核对」:
    curl -s http://<服务器地址>:3000/health | grep -o '"version":"[^"]*"'   # 必须输出 0.7.2
    

    管理端页面左下角显示的版本号必须与上面这条完全一致(都来自
    web-server/package.json)。

    数据库端到端验收(歌曲 CRUD → 动作上传 → 预处理 → 模型上传 → 审核 → 场景 → 目录导出)
    可在部署完成后执行:API_BASE=http://<服务器地址>:3000 node web-server/test/smoke.mjs

    说明:<服务器地址> 是你们自己部署的服务端地址(部署方决定),不是被脱敏的域名;
    本文档只对 Gitea 域名这类「部署必需且非隐私」的信息直接写出真实值
    (gitea.kasugano.cn / 属主 zijunchiang)。

    Downloads