|
| 1 | +#!/usr/bin/env bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +# 用法: |
| 5 | +# ./scripts/build_release.sh v0.1.0 |
| 6 | +# 不传则自动用当前 tag;没 tag 就用 commit 短哈希 |
| 7 | +VERSION="${1:-}" |
| 8 | + |
| 9 | +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" |
| 10 | +FRONTEND_DIR="$ROOT_DIR/frontend" |
| 11 | +BACKEND_DIR="$ROOT_DIR/backend" |
| 12 | + |
| 13 | +OUT_STAGING="$ROOT_DIR/dist_release" |
| 14 | +PKG_NAME="" |
| 15 | +ZIP_NAME="" |
| 16 | + |
| 17 | +# ---- 版本号推断 ---- |
| 18 | +if [[ -z "$VERSION" ]]; then |
| 19 | + if git -C "$ROOT_DIR" describe --tags --exact-match >/dev/null 2>&1; then |
| 20 | + VERSION="$(git -C "$ROOT_DIR" describe --tags --exact-match)" |
| 21 | + else |
| 22 | + VERSION="dev-$(git -C "$ROOT_DIR" rev-parse --short HEAD)" |
| 23 | + fi |
| 24 | +fi |
| 25 | + |
| 26 | +PKG_NAME="DataFlow-WebUI-$VERSION" |
| 27 | +ZIP_NAME="$PKG_NAME.zip" |
| 28 | + |
| 29 | +echo "[build_release] VERSION=$VERSION" |
| 30 | +echo "[build_release] PKG_NAME=$PKG_NAME" |
| 31 | + |
| 32 | +# ---- 依赖检查(尽早失败)---- |
| 33 | +command -v node >/dev/null 2>&1 || { echo "node not found"; exit 1; } |
| 34 | +command -v npm >/dev/null 2>&1 || { echo "npm not found"; exit 1; } |
| 35 | +command -v python >/dev/null 2>&1 || { echo "python not found"; exit 1; } |
| 36 | +command -v zip >/dev/null 2>&1 || { echo "zip not found (ubuntu: apt-get install zip)"; exit 1; } |
| 37 | +command -v rsync >/dev/null 2>&1 || { echo "rsync not found (ubuntu: apt-get install rsync)"; exit 1; } |
| 38 | + |
| 39 | +# ---- 清理 staging ---- |
| 40 | +rm -rf "$OUT_STAGING" |
| 41 | +mkdir -p "$OUT_STAGING/$PKG_NAME" |
| 42 | + |
| 43 | +# ---- 1) 构建前端(你现在 dist 已在 frontend/ 下)---- |
| 44 | +echo "[build_release] Building frontend..." |
| 45 | +pushd "$FRONTEND_DIR" >/dev/null |
| 46 | +# 你仓库里是 yarn.lock;若你更想用 yarn,就把 npm ci 换成 yarn install --frozen-lockfile |
| 47 | +# 这里先用 npm(要求有 package-lock.json);如果你没 lock,建议改用 yarn |
| 48 | +if [[ -f "package-lock.json" ]]; then |
| 49 | + npm ci |
| 50 | + npm run build |
| 51 | +else |
| 52 | + echo "No package-lock.json found, using npm install (consider using yarn with yarn.lock)." |
| 53 | + npm install |
| 54 | + npm run build |
| 55 | +fi |
| 56 | +popd >/dev/null |
| 57 | + |
| 58 | +# dist 必须存在 |
| 59 | +if [[ ! -d "$FRONTEND_DIR/dist" ]]; then |
| 60 | + echo "[build_release] ERROR: frontend/dist not found after build." |
| 61 | + exit 1 |
| 62 | +fi |
| 63 | + |
| 64 | +# ---- 2) 组装发布包:保持你的目录结构 backend/ + frontend/dist ---- |
| 65 | +echo "[build_release] Assembling package..." |
| 66 | + |
| 67 | +# 2.1 后端:复制 backend/(排除 tests、cache、pycache 等) |
| 68 | +rsync -a \ |
| 69 | + --exclude "__pycache__" \ |
| 70 | + --exclude ".venv" \ |
| 71 | + --exclude ".pytest_cache" \ |
| 72 | + --exclude "tests" \ |
| 73 | + --exclude "cache_local" \ |
| 74 | + "$BACKEND_DIR/" \ |
| 75 | + "$OUT_STAGING/$PKG_NAME/backend/" |
| 76 | + |
| 77 | +# 2.2 前端:只复制 dist(不带 node_modules/src 等) |
| 78 | +mkdir -p "$OUT_STAGING/$PKG_NAME/frontend" |
| 79 | +rsync -a --delete \ |
| 80 | + "$FRONTEND_DIR/dist/" \ |
| 81 | + "$OUT_STAGING/$PKG_NAME/frontend/dist/" |
| 82 | + |
| 83 | +# 2.3 顶层文档(可选) |
| 84 | +[[ -f "$ROOT_DIR/README-release-en.md" ]] && cp "$ROOT_DIR/README-release-en.md" "$OUT_STAGING/$PKG_NAME/" |
| 85 | +[[ -f "$ROOT_DIR/README-release-zh.md" ]] && cp "$ROOT_DIR/README-release-zh.md" "$OUT_STAGING/$PKG_NAME/" |
| 86 | +[[ -f "$ROOT_DIR/LICENSE" ]] && cp "$ROOT_DIR/LICENSE" "$OUT_STAGING/$PKG_NAME/" || true |
| 87 | + |
| 88 | +# ---- 3) 一键启动脚本 ---- |
| 89 | +# 关键:从 release 根目录启动,保证 backend 里用 ../frontend/dist 能找到前端资源 |
| 90 | +cat > "$OUT_STAGING/$PKG_NAME/run.sh" <<'EOF' |
| 91 | +#!/usr/bin/env bash |
| 92 | +set -e |
| 93 | +cd "$(dirname "$0")" |
| 94 | +
|
| 95 | +# 后端依赖 |
| 96 | +cd backend |
| 97 | +
|
| 98 | +uvicorn app.main:app --reload --port 8000 --reload-dir app --host=0.0.0.0 |
| 99 | +EOF |
| 100 | +chmod +x "$OUT_STAGING/$PKG_NAME/run.sh" |
| 101 | + |
| 102 | +cat > "$OUT_STAGING/$PKG_NAME/run.bat" <<'EOF' |
| 103 | +@echo off |
| 104 | +setlocal |
| 105 | +cd /d "%~dp0" |
| 106 | +
|
| 107 | +cd backend |
| 108 | +
|
| 109 | +uvicorn app.main:app --reload --port 8000 --reload-dir app --host=0.0.0.0 |
| 110 | +EOF |
| 111 | + |
| 112 | +# ---- 4) 打 zip ---- |
| 113 | +echo "[build_release] Creating zip..." |
| 114 | +pushd "$OUT_STAGING" >/dev/null |
| 115 | +zip -r "$ROOT_DIR/$ZIP_NAME" "$PKG_NAME" |
| 116 | +popd >/dev/null |
| 117 | + |
| 118 | +echo "[build_release] Done: $ROOT_DIR/$ZIP_NAME" |
0 commit comments