Improve WeChat MP replies and ship MindSpace/H5 production updates.
Add WeChat service account routing with sync acks, connectivity tests, and context isolation; document deploy runbooks; and bundle related MindSpace, voice, Plaza, and server gateway changes for production rollout. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Executable
+237
@@ -0,0 +1,237 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 一键把源码同步到开发机测试目录:Memind / memind_adm / Plaza
|
||||
# 适用:更新基于源码的开发机器环境。goose 不在本流程内。
|
||||
|
||||
HOST="${DEPLOY_HOST:-192.168.1.9}"
|
||||
USER="${DEPLOY_USER:-john}"
|
||||
TARGET="${DEPLOY_USER_HOST:-${USER}@${HOST}}"
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
EXCLUDE_FILE="${ROOT_DIR}/scripts/.rsync-exclude-test-host"
|
||||
|
||||
MEMIND_SRC="${MEMIND_SRC:-${ROOT_DIR}}"
|
||||
ADM_SRC="${ADM_SRC:-${ROOT_DIR}/../memind_adm}"
|
||||
PLAZA_SRC="${PLAZA_SRC:-${ROOT_DIR}/../tkmind_go/ui/plaza}"
|
||||
|
||||
MEMIND_DST="${MEMIND_DST:-/Users/john/PycharmProjects/test/test-memind}"
|
||||
ADM_DST="${ADM_DST:-/Users/john/PycharmProjects/test/test-memindadm}"
|
||||
PLAZA_DST="${PLAZA_DST:-/Users/john/PycharmProjects/test/test-memindplaza}"
|
||||
|
||||
RSYNC_OPTS=(
|
||||
-az
|
||||
--delete
|
||||
--exclude-from="${EXCLUDE_FILE}"
|
||||
)
|
||||
|
||||
DRY_RUN=0
|
||||
CHECK_ONLY=0
|
||||
ONLY_MEMIND=0
|
||||
ONLY_ADM=0
|
||||
ONLY_PLAZA=0
|
||||
SKIP_MV=0
|
||||
AUTO_YES=0
|
||||
|
||||
usage() {
|
||||
cat <<USAGE
|
||||
用法: ./scripts/deploy-to-test-host.sh [选项]
|
||||
|
||||
目标目录(支持环境变量覆盖)
|
||||
DEPLOY_HOST, DEPLOY_USER, DEPLOY_USER_HOST
|
||||
MEMIND_SRC, ADM_SRC, PLAZA_SRC
|
||||
MEMIND_DST, ADM_DST, PLAZA_DST
|
||||
MEMIND_STATUS_URL, ADMIN_STATUS_URL, PLAZA_URL
|
||||
|
||||
常用选项
|
||||
--only-memind 仅同步 test-memind
|
||||
--only-adm 仅同步 test-memindadm
|
||||
--only-plaza 仅同步 test-memindplaza
|
||||
--skip-delete 同步时不做 --delete(避免误删未排除文件)
|
||||
--dry-run 预览变更,不实际写入
|
||||
--check-only 只做连通性和目录检查,不做 rsync
|
||||
--yes 非交互,自动确认
|
||||
--help 显示帮助
|
||||
|
||||
示例
|
||||
./scripts/deploy-to-test-host.sh --dry-run
|
||||
./scripts/deploy-to-test-host.sh --only-memind --skip-delete
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--only-memind) ONLY_MEMIND=1 ;;
|
||||
--only-adm) ONLY_ADM=1 ;;
|
||||
--only-plaza) ONLY_PLAZA=1 ;;
|
||||
--skip-delete) SKIP_MV=1 ;;
|
||||
--dry-run) DRY_RUN=1 ;;
|
||||
--check-only) CHECK_ONLY=1 ;;
|
||||
--yes) AUTO_YES=1 ;;
|
||||
--help|-h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "未知参数: $1" >&2
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ "${ONLY_MEMIND}" -eq 1 && ("${ONLY_ADM}" -eq 1 || "${ONLY_PLAZA}" -eq 1) ]] ||
|
||||
[[ "${ONLY_ADM}" -eq 1 && "${ONLY_PLAZA}" -eq 1 ]]; then
|
||||
echo "错误: --only-* 只能选一个" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${SKIP_MV}" -eq 1 ]]; then
|
||||
RSYNC_OPTS=(
|
||||
-az
|
||||
--exclude-from="${EXCLUDE_FILE}"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ ! -f "${EXCLUDE_FILE}" ]]; then
|
||||
echo "错误: 未找到排除规则文件 ${EXCLUDE_FILE}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SSH_OPTS=(-o BatchMode=yes -o ConnectTimeout=12)
|
||||
|
||||
log() { printf '%s\n' "$*"; }
|
||||
err() { printf '%s\n' "$*" >&2; }
|
||||
fail() { err "✗ $*"; exit 1; }
|
||||
ok() { printf '%s\n' "✓ $*"; }
|
||||
|
||||
ssh_to_host() {
|
||||
ssh "${SSH_OPTS[@]}" "${TARGET}" "$*"
|
||||
}
|
||||
|
||||
preflight_local() {
|
||||
local src=$1
|
||||
[[ -d "$src" ]] || fail "本地源目录不存在: $src"
|
||||
[[ -f "$src/.gitignore" ]] || true
|
||||
ok "本地源目录存在: $src"
|
||||
}
|
||||
|
||||
preflight_remote() {
|
||||
local dst=$1
|
||||
local label=$2
|
||||
ssh_to_host "mkdir -p '${dst}'" >/dev/null
|
||||
if ! ssh_to_host "test -w '${dst}'" >/dev/null 2>&1; then
|
||||
fail "远端目标不可写: ${label} -> ${TARGET}:${dst}"
|
||||
fi
|
||||
ok "远端目录可写: ${label} -> ${dst}"
|
||||
}
|
||||
|
||||
ensure_host() {
|
||||
log "检查 SSH: ${TARGET}"
|
||||
ssh_to_host "echo connected" >/dev/null || fail "SSH 连接失败:${TARGET}"
|
||||
ok "SSH 连接成功: ${TARGET}"
|
||||
}
|
||||
|
||||
need_confirm() {
|
||||
local target=$1
|
||||
[[ "${AUTO_YES}" -eq 1 ]] && return 0
|
||||
read -r -p "确认同步 ${target}?[y/N] " input
|
||||
[[ "$input" == "y" || "$input" == "Y" ]]
|
||||
}
|
||||
|
||||
do_sync() {
|
||||
local label=$1
|
||||
local src=$2
|
||||
local dst=$3
|
||||
local flags=("${RSYNC_OPTS[@]}")
|
||||
|
||||
preflight_local "$src"
|
||||
preflight_remote "$dst" "$label"
|
||||
|
||||
if [[ "${DRY_RUN}" -eq 1 ]]; then
|
||||
flags+=(--dry-run --itemize-changes)
|
||||
log "[预览] ${label}: ${src} -> ${TARGET}:${dst}"
|
||||
rsync "${flags[@]}" "${src}/" "${TARGET}:${dst}/" | head -80
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! need_confirm "$label"; then
|
||||
fail "用户取消:${label}"
|
||||
fi
|
||||
|
||||
log "同步中 ${label}: ${src} -> ${TARGET}:${dst}"
|
||||
rsync "${flags[@]}" "${src}/" "${TARGET}:${dst}/"
|
||||
ok "同步完成 ${label}"
|
||||
}
|
||||
|
||||
health_check() {
|
||||
local label=$1
|
||||
local url=$2
|
||||
|
||||
if [[ -z "${url}" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ssh_to_host "command -v curl >/dev/null && curl -fsS '${url}' >/dev/null" >/dev/null 2>&1; then
|
||||
ok "${label} 健康检查通过:${url}"
|
||||
else
|
||||
log "⚠ ${label} 健康检查失败:${url}(仅提示)"
|
||||
fi
|
||||
}
|
||||
|
||||
export MEMIND_STATUS_URL="${MEMIND_STATUS_URL:-http://127.0.0.1:18081/api/status}"
|
||||
export ADMIN_STATUS_URL="${ADMIN_STATUS_URL:-http://127.0.0.1:18082/healthz}"
|
||||
export PLAZA_URL="${PLAZA_URL:-http://127.0.0.1:13001/plaza}"
|
||||
|
||||
ensure_host
|
||||
|
||||
if [[ "${CHECK_ONLY}" -eq 1 ]]; then
|
||||
preflight_remote "${MEMIND_DST}" "Memind"
|
||||
preflight_remote "${ADM_DST}" "memind_adm"
|
||||
preflight_remote "${PLAZA_DST}" "Plaza"
|
||||
ok "检查通过:远端目录可用"
|
||||
health_check "Memind" "${MEMIND_STATUS_URL}"
|
||||
health_check "memind_adm" "${ADMIN_STATUS_URL}"
|
||||
health_check "Plaza" "${PLAZA_URL}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TARGETS=()
|
||||
if [[ "${ONLY_MEMIND}" -eq 1 ]]; then
|
||||
TARGETS+=("memind")
|
||||
elif [[ "${ONLY_ADM}" -eq 1 ]]; then
|
||||
TARGETS+=("adm")
|
||||
elif [[ "${ONLY_PLAZA}" -eq 1 ]]; then
|
||||
TARGETS+=("plaza")
|
||||
else
|
||||
TARGETS+=("memind" "adm" "plaza")
|
||||
fi
|
||||
|
||||
for t in "${TARGETS[@]}"; do
|
||||
case "$t" in
|
||||
memind)
|
||||
do_sync "Memind" "${MEMIND_SRC}" "${MEMIND_DST}"
|
||||
;;
|
||||
adm)
|
||||
do_sync "memind_adm" "${ADM_SRC}" "${ADM_DST}"
|
||||
;;
|
||||
plaza)
|
||||
do_sync "Plaza" "${PLAZA_SRC}" "${PLAZA_DST}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
log "同步完成。建议检查:"
|
||||
log " Memind: ${MEMIND_STATUS_URL}"
|
||||
log " memind_adm: ${ADMIN_STATUS_URL}"
|
||||
log " Plaza: ${PLAZA_URL}"
|
||||
|
||||
echo "\n可在远端执行 restart(不包含 goose)"
|
||||
echo " ssh ${TARGET}"
|
||||
echo " cd ${MEMIND_DST} && pnpm install && pnpm dev:server 或 pm2 reload memind"
|
||||
echo " cd ${ADM_DST} && pnpm install && pnpm start:??"
|
||||
echo " cd ${PLAZA_DST} && pnpm install && pnpm dev:plaza"
|
||||
|
||||
echo ""
|
||||
echo "如果需要,我也可以把 restart 命令固定成你们当前启动脚架构(例如 launchctl/systemd/pm2/nodemon)。"
|
||||
Reference in New Issue
Block a user