#!/usr/bin/env bash
# Build only. Never connects to DM, starts apps, or changes Nginx.
set -euo pipefail
umask 022
TOOLS=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
[ "$#" = 3 ] || { echo '用法: bash build-release.sh 源码仓库绝对路径 完整提交号 版本号'; exit 2; }
REPO=$(cd -- "$1" && pwd)
COMMIT=$2
VERSION=$3
[[ "$VERSION" =~ ^[A-Za-z0-9][A-Za-z0-9._-]{0,70}$ ]] || { echo '版本号只允许字母数字点横线下划线'; exit 2; }
[[ "$COMMIT" =~ ^[a-f0-9]{40}$ ]] || { echo '需要40位完整提交号'; exit 2; }
[ "$(uname -s)" = Linux ] && [ "$(uname -m)" = x86_64 ] || { echo '本工具只支持Linux x86_64'; exit 2; }
[ "$(node -v)" = v20.19.5 ] && [ "$(pnpm -v)" = 10.21.0 ] || { echo '本工具固定Node20.19.5 / pnpm10.21.0'; exit 2; }
[ -z "$(git -C "$REPO" status --porcelain)" ] || { echo '源码仓库有未提交修改，停止'; exit 2; }
git -C "$REPO" cat-file -e "$COMMIT^{commit}"
git -C "$REPO" merge-base --is-ancestor "$COMMIT" origin/standard_wxb || { echo '提交不在已获取的standard_wxb历史内'; exit 2; }
JOB=/data/build/jobs/$VERSION
[ ! -e "$JOB" ] || { echo "版本目录已存在，请换新版本号: $JOB"; exit 2; }
mkdir -p "$JOB/src" "$JOB/logs" "$JOB/extra"
touch "$JOB/.foodsafe-build-workspace"
exec > >(tee "$JOB/logs/build.log") 2>&1
trap 'echo "打包中断，未部署；日志: $JOB/logs/build.log"' ERR
SRC=$JOB/src
# Export committed source only. Local env and untracked files never enter this tree.
git -C "$REPO" archive "$COMMIT" | tar -x -C "$SRC"
export JOB COMMIT VERSION
python3 - <<'PY'
import os,json,pathlib,platform,subprocess
j=pathlib.Path(os.environ['JOB'])
(j/'build-meta.json').write_text(json.dumps({'source_branch':'standard_wxb','source_commit':os.environ['COMMIT'],'version':os.environ['VERSION'],'os':platform.platform(),'arch':platform.machine(),'node':subprocess.check_output(['node','-v'],text=True).strip(),'pnpm':subprocess.check_output(['pnpm','-v'],text=True).strip(),'release_overlay':True},indent=2)+'\n')
# Real env files would affect Vite production output. Refuse tracked env, except examples.
for p in (j/'src').rglob('.env*'):
 if p.is_file() and not any(x in p.name for x in ['example','sample','template']):
  raise SystemExit('源码含实际环境文件，请研发清理并提交后重试：'+str(p.relative_to(j/'src')))
PY
# Exact-match adapter fails closed if future source changes its contract.
python3 "$TOOLS/apply-release-overlay.py" "$SRC"
cp "$TOOLS/locks/package.json" "$TOOLS/locks/package-lock.json" "$JOB/extra/"
(cd "$JOB/extra" && npm ci --ignore-scripts --no-audit --no-fund)
export NODE_ENV=development
(cd "$SRC" && pnpm install --frozen-lockfile --ignore-scripts)
[ ! -e "$SRC/node_modules/qrcode" ] && [ ! -L "$SRC/node_modules/qrcode" ] || { echo '源码已声明qrcode；请研发更新发布工具，避免重复覆盖'; exit 2; }
ln -s "$JOB/extra/node_modules/qrcode" "$SRC/node_modules/qrcode"
for app in web-school web-regulator screen mobile-device; do
  (cd "$SRC/apps/$app" && pnpm run build)
done
(cd "$SRC/services/gateway-service" && pnpm run build)
# Do not accept tsc output from a failed build.
test -s "$SRC/services/gateway-service/dist/services/gateway-service/src/main.js"
python3 "$TOOLS/assemble.py" "$JOB" "$TOOLS/template" /data/releases/food_safety
