#!/usr/bin/env bash # ============================================================ # OpenDance Studio Windows 客户端 —— **跨端集成验收**(T-WIN-019) # # Windows 发布包里的客户端(包内 pck) × 真实 Web 服务端 # # 为什么需要它:本仓单测打的是**假 HTTP 夹具**,Web 端测试只验自己那一侧。 # 两端各自绿灯 ≠ 契约字段真的对得上(字段名/嵌套/null/单位/范围都可能一侧对一侧错)。 # 契约 0.5.0 新增的 `scenes[]` 与重力/风向参数尤其如此。 # # 本脚本: # 1. 要求一个**已部署好的** Web 服务端(不做部署,与项目边界一致); # 2. 用真实素材播种一份目录(真 VMD → 内部标准;真 PMX → VRM;场景 GLB + 物理参数), # 并写出期望值 JSON(`--skip-seed` 可跳过,复用已有目录); # 3. 用 Godot 加载**发布包里的 pck**(`--main-pack`)跑 # `build/integration/probe-integration.gd`,逐项断言并给出退出码。 # # 用法: # GODOT_BIN=/path/to/godot API_BASE=http://127.0.0.1:3000 \ # bash build/accept-integration.sh dist-release/opendance-windows-v0.2.3.zip # # # 已播种过、只重跑探针: # GODOT_BIN=... API_BASE=... bash build/accept-integration.sh --skip-seed # # 环境变量: # API_BASE Web 服务端基地址(默认 http://127.0.0.1:3000) # OPENDANCE_SAMPLES_DIR 真实素材目录(默认 仓库根/示例文件) # EXPECT_PATH 期望值 JSON 输出路径(默认 $WORK_DIR/catalog-expect.json) # WORK_DIR 解包目录(默认 mktemp -d) # ============================================================ set -uo pipefail PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)" cd "$PROJECT_DIR" TARGET="${1:-}" SKIP_SEED=0 for arg in "$@"; do [ "$arg" = "--skip-seed" ] && SKIP_SEED=1; done API_BASE="${API_BASE:-http://127.0.0.1:3000}" SAMPLES_DIR="${OPENDANCE_SAMPLES_DIR:-$PROJECT_DIR/../示例文件}" WORK_DIR="${WORK_DIR:-$(mktemp -d)}" EXPECT_PATH="${EXPECT_PATH:-$WORK_DIR/catalog-expect.json}" FAILED=0 log() { printf '\033[1;34m[accept-int]\033[0m %s\n' "$*"; } fail() { printf '\033[1;31m[accept-int] ✗ %s\033[0m\n' "$*" >&2; FAILED=1; } if [ -z "$TARGET" ] || [ ! -e "$TARGET" ]; then echo "用法:GODOT_BIN=... API_BASE=... bash build/accept-integration.sh <发布包 zip 或已解压目录> [--skip-seed]" >&2 exit 2 fi # 必须**先**建目录:期望值 JSON 默认就落在 $WORK_DIR 下,播种阶段就要写它 mkdir -p "$WORK_DIR" # ---- 0. 服务端可达性 ---- log "服务端:$API_BASE" HEALTH="$(curl -sf -m 10 "$API_BASE/health" || true)" if [ -z "$HEALTH" ]; then fail "GET $API_BASE/health 不可达 —— 请先部署 Web 服务端(本项目不部署它)" exit 1 fi echo "$HEALTH" | node -e ' let s = ""; process.stdin.on("data", (d) => (s += d)).on("end", () => { const j = JSON.parse(s); console.log(` ✓ 服务端版本 ${j.version}|数据库 ${j.database?.connected ? "已连接" : "未连接"}|scenes.available=${j.scenes?.available}`); });' # ---- 1. 播种目录 ---- if [ "$SKIP_SEED" = "1" ]; then log "跳过播种(--skip-seed);期望值文件:$EXPECT_PATH" else log "播种真实目录(真 VMD / 真 PMX / 场景 GLB + 物理参数)…" if [ ! -d "$SAMPLES_DIR" ]; then fail "找不到素材目录 $SAMPLES_DIR(用 OPENDANCE_SAMPLES_DIR 指定)" exit 1 fi if ! command -v node >/dev/null 2>&1; then fail "播种需要 node(Web 端已依赖 node,本机应已安装)" exit 1 fi API_BASE="$API_BASE" OPENDANCE_SAMPLES_DIR="$SAMPLES_DIR" EXPECT_PATH="$EXPECT_PATH" \ node "$PROJECT_DIR/build/integration/seed-catalog.mjs" || { fail "播种失败"; exit 1; } fi if [ ! -f "$EXPECT_PATH" ]; then fail "缺少期望值文件 $EXPECT_PATH(首次运行不要加 --skip-seed)" exit 1 fi # ---- 2. 取包内 pck ---- if [ -f "$TARGET" ]; then log "解压发布包…" if ! unzip -qq -o "$TARGET" -d "$WORK_DIR" 2>/dev/null; then command -v 7z >/dev/null 2>&1 && 7z x -y -o"$WORK_DIR" "$TARGET" >/dev/null || { fail "解压失败"; exit 1; } fi PACKAGE_DIR="$(find "$WORK_DIR" -maxdepth 1 -mindepth 1 -type d | head -1)" else PACKAGE_DIR="$TARGET" fi PCK="$PACKAGE_DIR/OpenDance.pck" [ -f "$PCK" ] || { fail "找不到包内 pck:$PCK"; exit 1; } log "包内 pck:$PCK($(stat -c%s "$PCK") 字节)" # ---- 3. Godot ---- GODOT_BIN="${GODOT_BIN:-}" if [ -z "$GODOT_BIN" ]; then for candidate in godot godot4 Godot; do command -v "$candidate" >/dev/null 2>&1 && { GODOT_BIN="$candidate"; break; } done fi [ -n "$GODOT_BIN" ] || { fail "未找到 Godot(用 GODOT_BIN=<路径> 指定,需与本项目同版本 4.7.x)"; exit 1; } # ---- 4. 跨端探针 ---- log "跨端集成探针(包内客户端 × $API_BASE)…" PROBE_LOG="$WORK_DIR/probe-integration.log" if timeout 600 "$GODOT_BIN" --headless --main-pack "$PCK" \ --script "$PROJECT_DIR/build/integration/probe-integration.gd" \ -- --api-base "$API_BASE" --expect "$EXPECT_PATH" >"$PROBE_LOG" 2>&1; then PROBE_OK=1 else PROBE_OK=0 fi grep -vE "^Godot Engine|^$" "$PROBE_LOG" | sed 's/^/ /' [ "$PROBE_OK" = 1 ] || fail "跨端集成探针未通过" echo "" if [ "$FAILED" -ne 0 ]; then echo "============================================================" echo " 跨端集成验收失败(工作目录:$WORK_DIR)" echo "============================================================" exit 1 fi echo "============================================================" echo " 跨端集成验收全部通过(工作目录:$WORK_DIR)" echo "============================================================"