fix(deploy): bash 3.2 compat, sshpass auth, sync admin dist to public/admin
- Replace bash 4.2+ printf %(...)T with date subshell so script runs on the macOS-default bash 3.2. - Add SSH_PASS_FILE / SSH_PASSWORD support via sshpass for environments where password auth is the only path. - After admin npm build, rsync view/admin/dist/ into public/admin/ (preserving UEditor and favicon) so the project rsync ships the admin to the path nginx actually serves from. - Simplify rsync exclude list to drop view/admin/ wholesale. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,8 +38,30 @@ log() { printf "\033[1;36m[%s]\033[0m %s\n" "$(_ts)" "$*"; }
|
||||
warn() { printf "\033[1;33m[%s] WARN\033[0m %s\n" "$(_ts)" "$*"; }
|
||||
err() { printf "\033[1;31m[%s] ERR\033[0m %s\n" "$(_ts)" "$*" >&2; }
|
||||
|
||||
ssh_run() { ssh -p "$SSH_PORT" "${SSH_USER}@${SSH_HOST}" "$@"; }
|
||||
ssh_pipe() { ssh -p "$SSH_PORT" "${SSH_USER}@${SSH_HOST}" bash -se; }
|
||||
# 认证:优先 SSH_PASS_FILE(sshpass -f),其次 SSH_PASSWORD env,再退回公钥
|
||||
SSH_BASE=(ssh -p "$SSH_PORT" -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR)
|
||||
if [ -n "${SSH_PASS_FILE:-}" ] && [ -f "${SSH_PASS_FILE/#~/$HOME}" ]; then
|
||||
SSH_PASS_FILE="${SSH_PASS_FILE/#~/$HOME}"
|
||||
[ "$(stat -f '%A' "$SSH_PASS_FILE" 2>/dev/null || stat -c '%a' "$SSH_PASS_FILE")" = "600" ] || \
|
||||
warn "SSH_PASS_FILE permission is not 600 (consider: chmod 600 $SSH_PASS_FILE)"
|
||||
command -v sshpass >/dev/null || { err "sshpass not installed (brew install hudochenkov/sshpass/sshpass)"; exit 1; }
|
||||
SSH_AUTH=(sshpass -f "$SSH_PASS_FILE")
|
||||
elif [ -n "${SSH_PASSWORD:-}" ]; then
|
||||
command -v sshpass >/dev/null || { err "sshpass not installed"; exit 1; }
|
||||
SSH_AUTH=(sshpass -e) # reads SSHPASS env
|
||||
export SSHPASS="$SSH_PASSWORD"
|
||||
else
|
||||
SSH_AUTH=()
|
||||
fi
|
||||
|
||||
ssh_run() { "${SSH_AUTH[@]}" "${SSH_BASE[@]}" "${SSH_USER}@${SSH_HOST}" "$@"; }
|
||||
ssh_pipe() { "${SSH_AUTH[@]}" "${SSH_BASE[@]}" "${SSH_USER}@${SSH_HOST}" bash -se; }
|
||||
# rsync 走相同认证
|
||||
if [ -n "${SSH_AUTH+x}" ] && [ "${#SSH_AUTH[@]}" -gt 0 ]; then
|
||||
RSYNC_RSH="${SSH_AUTH[*]} ssh -p $SSH_PORT -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR"
|
||||
else
|
||||
RSYNC_RSH="ssh -p $SSH_PORT"
|
||||
fi
|
||||
|
||||
check_health() {
|
||||
local url code i
|
||||
@@ -156,6 +178,14 @@ else
|
||||
fi
|
||||
[ -d "$PROJECT_ROOT/view/admin/dist" ] || { err "view/admin/dist missing; build failed?"; exit 1; }
|
||||
|
||||
# admin 实际运行目录 = pro_v3.5.1/public/admin/(远端 nginx 指向同名路径)
|
||||
# 把 build 产物同步到 public/admin/,再让项目根 rsync 整体推上去
|
||||
log "Sync admin dist -> public/admin/"
|
||||
mkdir -p "$PROJECT_ROOT/public/admin"
|
||||
rsync -a --delete \
|
||||
--exclude='UEditor/' --exclude='favicon.ico' \
|
||||
"$PROJECT_ROOT/view/admin/dist/" "$PROJECT_ROOT/public/admin/"
|
||||
|
||||
# ---- VERSION ----
|
||||
TS=$(date +%Y%m%d-%H%M%S)
|
||||
SHA=$(git -C "$PROJECT_ROOT/.." rev-parse --short HEAD 2>/dev/null || echo "nogit")
|
||||
@@ -166,7 +196,7 @@ log "Release tag: $TAG"
|
||||
RSYNC_OPTS=(-az --delete --human-readable
|
||||
--exclude-from="$EXCLUDE_FILE"
|
||||
--backup --backup-dir="$REMOTE_BAK/$TAG"
|
||||
-e "ssh -p $SSH_PORT")
|
||||
-e "$RSYNC_RSH")
|
||||
[ "$DRY_RUN" -eq 1 ] && RSYNC_OPTS+=(--dry-run --itemize-changes)
|
||||
|
||||
log "rsync -> ${SSH_USER}@${SSH_HOST}:$REMOTE_ROOT (backup: $REMOTE_BAK/$TAG)"
|
||||
|
||||
Reference in New Issue
Block a user