- 为 trialrun 环境契约补充 ATTENDANCE_ENABLED=true - 部署脚本先 build init 再 run,避免新迁移和 seed 被旧镜像跳过
195 行
6.1 KiB
Bash
可执行文件
195 行
6.1 KiB
Bash
可执行文件
#!/usr/bin/env bash
|
|
# ============================================================
|
|
# hyb-oa - 同机部署脚本(本地执行)
|
|
# ============================================================
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
DEPLOY_SERVER="${DEPLOY_SERVER:-deploy@118.89.77.218}"
|
|
REMOTE_DIR="${REMOTE_DIR:-/opt/hyb-oa-trialrun}"
|
|
REMOTE_ENV_FILE="${REMOTE_ENV_FILE:-${REMOTE_DIR}/deploy/trialrun/.env}"
|
|
ENABLE_WORKER="${ENABLE_WORKER:-0}"
|
|
ENABLE_MINIO="${ENABLE_MINIO:-0}"
|
|
SYNC_ENV="${SYNC_ENV:-0}"
|
|
COMPOSE_FILE="deploy/trialrun/docker-compose.yml"
|
|
LOCAL_ENV_FILE="deploy/trialrun/.env"
|
|
ENV_CONTRACT_SCRIPT="deploy/trialrun/validate-env-contract.js"
|
|
RUNTIME_SMOKE_SCRIPT="server/src/scripts/smoke-trialrun-runtime.js"
|
|
EXTERNAL_DEPS_SMOKE_SCRIPT="server/src/scripts/smoke-external-deps.js"
|
|
|
|
need_cmd() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
echo "[ERROR] 缺少命令: $1" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
need_cmd rsync
|
|
need_cmd ssh
|
|
need_cmd node
|
|
|
|
if [[ ! -f "${ROOT_DIR}/${COMPOSE_FILE}" ]]; then
|
|
echo "[ERROR] 缺少 ${COMPOSE_FILE}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "${ROOT_DIR}/${ENV_CONTRACT_SCRIPT}" ]]; then
|
|
echo "[ERROR] 缺少 ${ENV_CONTRACT_SCRIPT}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "${ROOT_DIR}/${RUNTIME_SMOKE_SCRIPT}" ]]; then
|
|
echo "[ERROR] 缺少 ${RUNTIME_SMOKE_SCRIPT}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "${ROOT_DIR}/${EXTERNAL_DEPS_SMOKE_SCRIPT}" ]]; then
|
|
echo "[ERROR] 缺少 ${EXTERNAL_DEPS_SMOKE_SCRIPT}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${SYNC_ENV}" == "1" && ! -f "${ROOT_DIR}/${LOCAL_ENV_FILE}" ]]; then
|
|
echo "[ERROR] SYNC_ENV=1 但本地不存在 ${LOCAL_ENV_FILE}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo ">>> 0. 校验部署环境契约"
|
|
node "${ROOT_DIR}/${ENV_CONTRACT_SCRIPT}"
|
|
|
|
echo ">>> 1. 创建远端目录"
|
|
ssh "${DEPLOY_SERVER}" "mkdir -p '${REMOTE_DIR}'"
|
|
|
|
echo ">>> 2. 同步 OA 仓库到服务器"
|
|
rsync -az --delete \
|
|
--exclude '.git' \
|
|
--exclude '.github' \
|
|
--exclude '.agent' \
|
|
--exclude '.agents' \
|
|
--exclude '.codex' \
|
|
--exclude '.claude' \
|
|
--exclude 'node_modules' \
|
|
--exclude 'client/node_modules' \
|
|
--exclude 'server/node_modules' \
|
|
--exclude 'client/test-results' \
|
|
--exclude 'client/playwright-report' \
|
|
--exclude 'server/generated' \
|
|
--exclude 'deploy/trialrun/data' \
|
|
--exclude 'deploy/trialrun/.env' \
|
|
--exclude 'coverage' \
|
|
--exclude 'dist' \
|
|
--exclude '*.log' \
|
|
"${ROOT_DIR}/" "${DEPLOY_SERVER}:${REMOTE_DIR}/"
|
|
|
|
if [[ "${SYNC_ENV}" == "1" ]]; then
|
|
echo ">>> 3. 同步部署环境变量"
|
|
ssh "${DEPLOY_SERVER}" "mkdir -p '$(dirname "${REMOTE_ENV_FILE}")'"
|
|
rsync -az "${ROOT_DIR}/${LOCAL_ENV_FILE}" "${DEPLOY_SERVER}:${REMOTE_ENV_FILE}"
|
|
else
|
|
echo ">>> 3. 跳过 .env 同步(默认安全模式)"
|
|
echo " 如果你确认本地 deploy/trialrun/.env 可直接上服务器,可用:SYNC_ENV=1 bash deploy/trialrun/deploy.sh"
|
|
fi
|
|
|
|
echo ">>> 4. 在服务器执行部署与 smoke"
|
|
ssh "${DEPLOY_SERVER}" \
|
|
"REMOTE_DIR='${REMOTE_DIR}' REMOTE_ENV_FILE='${REMOTE_ENV_FILE}' COMPOSE_FILE='${COMPOSE_FILE}' ENABLE_WORKER='${ENABLE_WORKER}' ENABLE_MINIO='${ENABLE_MINIO}' bash -s" <<'REMOTE'
|
|
set -euo pipefail
|
|
cd "$REMOTE_DIR"
|
|
mkdir -p deploy/trialrun/data/postgres deploy/trialrun/data/storage deploy/trialrun/data/minio
|
|
|
|
if [[ ! -f "$REMOTE_ENV_FILE" ]]; then
|
|
echo "[ERROR] 远端缺少 $REMOTE_ENV_FILE,请先手工创建或使用 SYNC_ENV=1" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if docker compose version >/dev/null 2>&1; then
|
|
compose_cmd=(docker compose -f "$COMPOSE_FILE" --env-file "$REMOTE_ENV_FILE")
|
|
elif command -v docker-compose >/dev/null 2>&1; then
|
|
compose_cmd=(docker-compose -f "$COMPOSE_FILE" --env-file "$REMOTE_ENV_FILE")
|
|
else
|
|
echo "[ERROR] 远端既没有 docker compose,也没有 docker-compose" >&2
|
|
exit 1
|
|
fi
|
|
|
|
profile_args=()
|
|
if [[ "$ENABLE_MINIO" == "1" ]]; then
|
|
profile_args+=(--profile minio)
|
|
fi
|
|
if [[ "$ENABLE_WORKER" == "1" ]]; then
|
|
profile_args+=(--profile worker)
|
|
fi
|
|
|
|
echo ">>> 4.1 校验远端 compose 配置"
|
|
"${compose_cmd[@]}" "${profile_args[@]}" config >/dev/null
|
|
|
|
echo ">>> 4.2 启动基础服务"
|
|
"${compose_cmd[@]}" up -d db
|
|
if [[ "$ENABLE_MINIO" == "1" ]]; then
|
|
"${compose_cmd[@]}" "${profile_args[@]}" up -d minio minio_init
|
|
fi
|
|
"${compose_cmd[@]}" "${profile_args[@]}" up -d --build server
|
|
if [[ "$ENABLE_WORKER" == "1" ]]; then
|
|
"${compose_cmd[@]}" "${profile_args[@]}" up -d worker
|
|
fi
|
|
|
|
echo ">>> 4.3 构建最新 init 镜像"
|
|
"${compose_cmd[@]}" build init
|
|
|
|
echo ">>> 4.4 执行 init"
|
|
"${compose_cmd[@]}" run --rm -T init </dev/null
|
|
|
|
echo ">>> 4.5 等待 /ready"
|
|
ready_ok=0
|
|
for i in $(seq 1 60); do
|
|
if curl -fsS http://127.0.0.1:3000/ready >/dev/null; then
|
|
ready_ok=1
|
|
break
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
if [[ "$ready_ok" != "1" ]]; then
|
|
echo "[ERROR] /ready 在超时时间内未通过" >&2
|
|
"${compose_cmd[@]}" logs --tail=200 server || true
|
|
exit 1
|
|
fi
|
|
|
|
echo ">>> 4.6 执行 external deps smoke"
|
|
if ! "${compose_cmd[@]}" exec -T server node src/scripts/smoke-external-deps.js; then
|
|
echo "[ERROR] external deps smoke 失败,输出最近 server 日志" >&2
|
|
"${compose_cmd[@]}" logs --tail=200 server || true
|
|
exit 1
|
|
fi
|
|
|
|
echo ">>> 4.7 执行 runtime smoke"
|
|
if ! "${compose_cmd[@]}" exec -T server node src/scripts/smoke-trialrun-runtime.js; then
|
|
echo "[ERROR] runtime smoke 失败,输出最近 server 日志" >&2
|
|
"${compose_cmd[@]}" logs --tail=200 server || true
|
|
exit 1
|
|
fi
|
|
|
|
echo ">>> 4.8 当前服务状态"
|
|
"${compose_cmd[@]}" ps
|
|
REMOTE
|
|
|
|
LIVE_SMOKE_READY=1
|
|
for required_key in LIVE_SMOKE_ADMIN_IDENTIFIER LIVE_SMOKE_ADMIN_PASSWORD LIVE_SMOKE_EMPLOYEE_IDENTIFIER LIVE_SMOKE_EMPLOYEE_PASSWORD; do
|
|
if [[ -z "${!required_key:-}" ]]; then
|
|
LIVE_SMOKE_READY=0
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [[ "$LIVE_SMOKE_READY" == "1" ]]; then
|
|
echo ">>> 5. 执行部署后 live smoke"
|
|
bash "${ROOT_DIR}/scripts/qa/run-web-gates.sh" smoke-live
|
|
else
|
|
echo ">>> 5. 跳过部署后 live smoke(未提供完整 LIVE_SMOKE_* 凭据)"
|
|
fi
|
|
|
|
echo ">>> 6. 部署完成"
|
|
echo " 远端目录: ${REMOTE_DIR}"
|
|
echo " 环境文件: ${REMOTE_ENV_FILE}"
|
|
echo " 已自动执行:契约校验 + /ready + external deps smoke + runtime smoke"
|
|
echo " 若本地已配置 LIVE_SMOKE_*,部署后会自动补跑网页 live smoke"
|
|
echo " 请确认 Nginx 已把 OA 域名反代到 127.0.0.1:3000"
|