| ¶Ô±ÈÐÂÎļþ |
| | |
| | | #!/usr/bin/env bash |
| | | # ============================================================ |
| | | # å®å¤ä¸éæ°æ ââ å端é¨ç½²èæ¬ï¼macOS / Linux çï¼ |
| | | # 对åºä»åºéç WTXC.batï¼åªéç¨äºæ¬åæ¯ï¼ä¸éæ°æï¼ã |
| | | # |
| | | # ./WTXC.sh # æå»º + ä¸ä¼ + è§£åï¼çä»·äº WTXC.batï¼ |
| | | # ./WTXC.sh --dry-run # åªæå»ºåæ¬å°æ£æ¥ï¼ä¸è¿æå¡å¨ãä¸ä¸ä¼ |
| | | # ./WTXC.sh --skip-build # ä¸æå»ºï¼ç´æ¥ä¸ä¼ å½åç®å½å·²æç dist.zip |
| | | # |
| | | # æµç¨ä¸ WTXC.bat å®å
¨ä¸è´ï¼pnpm buildï¼å¸¦ VITE_COMPANY=WTXCï¼â çæ dist.zip |
| | | # â scp ä¸ä¼ å° <è¿ç«¯ç®å½>/.dist.zip.uploading â æ ¡éªå¤§å° â æ¹å |
| | | # â unzip -t æ ¡éª â unzip -o è§£å â å é¤è¿ç«¯ zip |
| | | # |
| | | # é¨ç½²ç®æ ï¼root@42.63.71.140:/home/vue/dist |
| | | # |
| | | # ç¯å¢åéè¦çï¼DEPLOY_PASSWORDãDEPLOY_HOSTãDEPLOY_DIRãDEPLOY_PORT |
| | | # ï¼æ¹å¯ç æä¸´æ¶æå°å«çç®å½æ¶ç¨ï¼é¿å
æå¯ç åè¿å½ä»¤è¡åå²ï¼ |
| | | # |
| | | # 说æï¼WTXC.bat èµ°çæ¯ bin\sshpass.exeï¼Windows ä¸ç¨ï¼ãmacOS 䏿²¡æ sshpass |
| | | # æ¶æ¬èæ¬èªå¨æ¹ç¨ç³»ç»èªå¸¦ç expect éå¯ç ï¼å æ¤æ éé¢å¤å®è£
ï¼è¥å·²è£
|
| | | # sshpassï¼brew install hudochenkov/sshpass/sshpassï¼åä¼å
使ç¨å®ã |
| | | # ============================================================ |
| | | set -euo pipefail |
| | | |
| | | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| | | cd "$SCRIPT_DIR" |
| | | |
| | | # ------------------------------------------------------------------ |
| | | # 1. åæ°ä¸ç®æ é
ç½®ï¼å¯¹åº WTXC.bat é¡¶é¨ç Configuration æ®µï¼ |
| | | # ------------------------------------------------------------------ |
| | | SKIP_BUILD=0 |
| | | DRY_RUN=0 |
| | | |
| | | for arg in "$@"; do |
| | | case "$arg" in |
| | | --skip-build) SKIP_BUILD=1 ;; |
| | | --dry-run) DRY_RUN=1 ;; |
| | | -h | --help) |
| | | # æå°æä»¶å¤´é¨ç注é说æï¼ç¬¬ä¸è¡ shebang ä¹åå° set ä¹åï¼ |
| | | awk 'NR == 1 { next } /^set / { exit } { print }' "${BASH_SOURCE[0]}" |
| | | exit 0 |
| | | ;; |
| | | *) |
| | | echo "[ERROR] æªç¥åæ°ï¼${arg}ï¼å¯ç¨ï¼--skip-build / --dry-run / -hï¼" >&2 |
| | | exit 1 |
| | | ;; |
| | | esac |
| | | done |
| | | |
| | | COMPANY="WTXC" |
| | | EXPECT_BRANCH="dev_å®å¤_ä¸éæ°ææ" |
| | | REMOTE_USER="root" |
| | | REMOTE_HOST="42.63.71.140" |
| | | PORT="22" |
| | | PASSWORD="Nxwtxc123." |
| | | REMOTE_DIR="/home/vue/dist" |
| | | ZIP_FILE="dist.zip" |
| | | |
| | | # å
许ç¨ç¯å¢åéè¦ç |
| | | REMOTE_HOST="${DEPLOY_HOST:-$REMOTE_HOST}" |
| | | REMOTE_DIR="${DEPLOY_DIR:-$REMOTE_DIR}" |
| | | PASSWORD="${DEPLOY_PASSWORD:-$PASSWORD}" |
| | | PORT="${DEPLOY_PORT:-$PORT}" |
| | | |
| | | SSH_OPTS=(-o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ServerAliveInterval=15 -o ServerAliveCountMax=3 -o NumberOfPasswordPrompts=1) |
| | | |
| | | # ------------------------------------------------------------------ |
| | | # 2. åç½®æ£æ¥ï¼åªè½å¨æ¬å®¢æ·åæ¯ä¸æå»ºé¨ç½² |
| | | # å
éåæ»äºä¸éçåç§°/Logo/æ¥å£å°åï¼ç¨å«ç忝æå»ºä¼æå«å®¢æ·çåç«¯ä¼ ä¸æ¥ã |
| | | # ------------------------------------------------------------------ |
| | | CURRENT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')" |
| | | if [ -n "$CURRENT_BRANCH" ] && [ "$CURRENT_BRANCH" != "$EXPECT_BRANCH" ]; then |
| | | if [ "${ALLOW_BRANCH_MISMATCH:-0}" != "1" ]; then |
| | | echo "[ERROR] å½ååæ¯æ¯ ${CURRENT_BRANCH}ï¼ä¸æ¯ä¸é忝 ${EXPECT_BRANCH}ã" >&2 |
| | | echo " æ¬èæ¬ä¼ææå»ºç»æé¨ç½²å°ä¸éç产æå¡å¨ï¼è¯·å
ååä¸é忝ï¼" >&2 |
| | | echo " git checkout ${EXPECT_BRANCH}" >&2 |
| | | echo " ç¡®å®è¦å¨è¯¥åæ¯ä¸é¨ç½²æ¶ï¼å¯å ALLOW_BRANCH_MISMATCH=1 è·³è¿æ¤æ ¡éªã" >&2 |
| | | exit 1 |
| | | fi |
| | | echo "[WARN] 忝䏿¯ ${EXPECT_BRANCH}ï¼å½å ${CURRENT_BRANCH}ï¼ï¼æ ALLOW_BRANCH_MISMATCH=1 ç»§ç»ã" >&2 |
| | | fi |
| | | |
| | | echo |
| | | echo "============================================================" |
| | | echo " Vue Dist Auto Deploy (ä¸éæ°æ / macOS)" |
| | | echo "============================================================" |
| | | echo |
| | | echo "Company : $COMPANY" |
| | | echo "Server : $REMOTE_USER@$REMOTE_HOST:$PORT" |
| | | echo "Remote Dir : $REMOTE_DIR" |
| | | echo "Package : $ZIP_FILE" |
| | | if [ -n "$(git status --porcelain 2>/dev/null || true)" ]; then |
| | | echo "Git : â å·¥ä½åºææªæäº¤æ¹å¨ï¼é¨ç½²çæ¯å·¥ä½åºå
容ï¼ä¸æ¯æäº¤å
容ï¼" |
| | | else |
| | | echo "Git : ${CURRENT_BRANCH} @ $(git rev-parse --short HEAD 2>/dev/null || echo '-')" |
| | | fi |
| | | echo |
| | | |
| | | # ------------------------------------------------------------------ |
| | | # 3. ä¾èµæ£æ¥ï¼å¯¹åº WTXC.bat ç [1/7]~[3/7]ï¼ |
| | | # ------------------------------------------------------------------ |
| | | echo "[1/4] æ£æ¥ pnpm / node ..." |
| | | command -v pnpm >/dev/null 2>&1 || { |
| | | echo "[ERROR] æ¾ä¸å° pnpmï¼è¯·å
npm install -g pnpm" >&2 |
| | | exit 1 |
| | | } |
| | | command -v node >/dev/null 2>&1 || { |
| | | echo "[ERROR] æ¾ä¸å° node" >&2 |
| | | exit 1 |
| | | } |
| | | echo " pnpm $(pnpm --version) / node $(node --version)" |
| | | |
| | | if [ ! -d node_modules ]; then |
| | | echo "[INFO] node_modules ä¸åå¨ï¼æ§è¡ pnpm install ..." |
| | | pnpm install |
| | | else |
| | | echo " node_modules å·²åå¨" |
| | | fi |
| | | |
| | | # ------------------------------------------------------------------ |
| | | # 4. æå»ºï¼å¯¹åº WTXC.bat ç [4/7]ï¼ |
| | | # 注æï¼archiver æä»¶æ¯å¨ closeBundle é弿¥å dist.zipï¼ |
| | | # æä»¥æå»ºå®è¦çå®è½å°ï¼åæ¶å
å ææ§ zipï¼é¿å
ææ§å
彿°å
ä¼ ä¸å»ã |
| | | # é»è®¤æ¯æ¬¡éæ°æå»ºï¼WTXC.bat 乿¯å¦æ¤ï¼ï¼åªææ¾å¼ --skip-build æå¤ç¨æ§å
ã |
| | | # ------------------------------------------------------------------ |
| | | if [ "$SKIP_BUILD" -eq 0 ]; then |
| | | echo |
| | | echo "[2/4] æå»ºä¸ï¼VITE_COMPANY=${COMPANY}ï¼pnpm run buildï¼..." |
| | | rm -f "$ZIP_FILE" |
| | | VITE_COMPANY="$COMPANY" pnpm run build |
| | | for _ in $(seq 1 30); do |
| | | [ -f "$ZIP_FILE" ] && break |
| | | sleep 1 |
| | | done |
| | | else |
| | | echo |
| | | echo "[2/4] è·³è¿æå»ºï¼--skip-buildï¼ï¼å¤ç¨å·²æç ${ZIP_FILE}" |
| | | echo "[WARN] 请确认该å
å°±æ¯ç¨ VITE_COMPANY=${COMPANY} æå»ºçï¼" >&2 |
| | | echo " å
é已忻客æ·çåç§°/Logo/æ¥å£å°åï¼ç¨éå
伿å«å®¢æ·çåç«¯ä¼ å°æ¬æå¡å¨ã" >&2 |
| | | fi |
| | | |
| | | if [ ! -f "$ZIP_FILE" ]; then |
| | | echo "[ERROR] æå»ºç»æä½æ²¡æçæ $ZIP_FILE" >&2 |
| | | exit 1 |
| | | fi |
| | | |
| | | ZIP_BYTES="$(wc -c < "$ZIP_FILE" | tr -d ' ')" |
| | | echo "[OK] æå
宿ï¼${ZIP_FILE}ï¼${ZIP_BYTES} åèï¼" |
| | | |
| | | if [ "$DRY_RUN" -eq 1 ]; then |
| | | echo "[INFO] --dry-runï¼æ¬å°æ£æ¥éè¿ï¼æªè¿æå¡å¨ãæªä¸ä¼ ã" |
| | | exit 0 |
| | | fi |
| | | |
| | | # ------------------------------------------------------------------ |
| | | # 5. è¿ç«¯æä½ï¼å¯¹åº WTXC.bat ç [6/7][7/7]ï¼ |
| | | # ------------------------------------------------------------------ |
| | | EXPECT_HELPER="$(mktemp -t wtxc-sshpass)" |
| | | cleanup() { rm -f "$EXPECT_HELPER"; } |
| | | trap cleanup EXIT |
| | | |
| | | cat > "$EXPECT_HELPER" <<'EXPECT' |
| | | #!/usr/bin/expect -f |
| | | # ç¨æ³: sshpass-helper <password> <command...> |
| | | set timeout 3600 |
| | | set pw [lindex $argv 0] |
| | | set cmd [lrange $argv 1 end] |
| | | eval spawn -noecho $cmd |
| | | expect { |
| | | -re "(?i)are you sure you want to continue connecting" { send "yes\r"; exp_continue } |
| | | -re "(?i)password:" { send "$pw\r"; exp_continue } |
| | | -re "(?i)permission denied" { exit 5 } |
| | | # è¶
æ¶å¿
é¡»æ¾å¼éåºï¼å¦å expect 伿å¨åé¢ç wait ä¸ä¸è¿å |
| | | timeout { puts stderr "SSH è¶
æ¶"; exit 9 } |
| | | eof |
| | | } |
| | | catch wait result |
| | | exit [lindex $result 3] |
| | | EXPECT |
| | | chmod +x "$EXPECT_HELPER" |
| | | |
| | | HAS_SSHPASS=0 |
| | | command -v sshpass >/dev/null 2>&1 && HAS_SSHPASS=1 |
| | | if [ "$HAS_SSHPASS" -eq 0 ] && ! command -v expect >/dev/null 2>&1; then |
| | | echo "[ERROR] æ¢æ²¡æ sshpass 乿²¡æ expectï¼æ æ³å¨èæ¬éèªå¨éå¯ç ã" >&2 |
| | | echo " 坿§è¡ï¼brew install hudochenkov/sshpass/sshpassï¼ææå·¥ scp ä¸ä¼ ã" >&2 |
| | | exit 1 |
| | | fi |
| | | |
| | | # å¨è¿ç«¯æ§è¡å½ä»¤ï¼è¿åå
¶éåºç ï¼stdout ç±è°ç¨æ¹æè·ï¼å¤±è´¥æ¶è¾åºæå° stderrï¼ |
| | | remote_run() { |
| | | local out rc=0 |
| | | if [ "$HAS_SSHPASS" -eq 1 ]; then |
| | | out="$(SSHPASS="$PASSWORD" sshpass -e ssh -p "$PORT" "${SSH_OPTS[@]}" "$REMOTE_USER@$REMOTE_HOST" "$1" 2>&1)" || rc=$? |
| | | else |
| | | out="$("$EXPECT_HELPER" "$PASSWORD" ssh -p "$PORT" "${SSH_OPTS[@]}" "$REMOTE_USER@$REMOTE_HOST" "$1" 2>&1)" || rc=$? |
| | | fi |
| | | if [ "$rc" -ne 0 ]; then |
| | | echo "[ERROR] è¿ç«¯å½ä»¤æ§è¡å¤±è´¥ï¼exit $rcï¼ï¼$1" >&2 |
| | | [ -n "$out" ] && printf '%s\n' "$out" >&2 |
| | | fi |
| | | printf '%s' "$out" |
| | | return "$rc" |
| | | } |
| | | |
| | | # ä¸ä¼ ä¸ä¸ªæä»¶ï¼remote_copy <æ¬å°æä»¶> <è¿ç«¯ç»å¯¹è·¯å¾>ï¼ä¿çè¿åº¦æ¡ï¼ |
| | | remote_copy() { |
| | | if [ "$HAS_SSHPASS" -eq 1 ]; then |
| | | SSHPASS="$PASSWORD" sshpass -e scp -P "$PORT" "${SSH_OPTS[@]}" "$1" "$REMOTE_USER@$REMOTE_HOST:$2" |
| | | else |
| | | "$EXPECT_HELPER" "$PASSWORD" scp -P "$PORT" "${SSH_OPTS[@]}" "$1" "$REMOTE_USER@$REMOTE_HOST:$2" |
| | | fi |
| | | } |
| | | |
| | | echo |
| | | echo "[3/4] è¿æ¥æå¡å¨ ..." |
| | | remote_run "echo SSH_OK" >/dev/null |
| | | echo "[OK] SSH è¿æ¥æå" |
| | | |
| | | remote_run "mkdir -p '$REMOTE_DIR'" >/dev/null |
| | | echo "[OK] è¿ç«¯ç®å½å°±ç»ª" |
| | | |
| | | REMOTE_TMP="$REMOTE_DIR/.dist.zip.uploading" |
| | | echo |
| | | echo "[4/4] ä¸ä¼ å¹¶è§£å ..." |
| | | remote_run "rm -f '$REMOTE_TMP'" >/dev/null |
| | | remote_copy "$ZIP_FILE" "$REMOTE_TMP" |
| | | echo "[OK] ä¸ä¼ 宿" |
| | | |
| | | # è¿ç«¯å½ä»¤çè¾åºé伿··æ expect åæ¾çå¯ç æç¤ºï¼å½ä»¤æ¬èº«ç stdout æ»å¨æåï¼ |
| | | # åæåä¸ä¸ªå段å³ä¸ºæéæ°å¼ï¼stat ç stderr ä¹ä¼èµ°å°è¿éï¼æ
åå䏿¬¡ç©ºå¼å¤æï¼ã |
| | | REMOTE_BYTES="$(remote_run "stat -c %s '$REMOTE_TMP'" | tr -d '\r' | awk 'END { print $NF }')" |
| | | REMOTE_BYTES="$(printf '%s' "$REMOTE_BYTES" | tr -cd '0-9')" |
| | | if [ -z "$REMOTE_BYTES" ] || [ "$REMOTE_BYTES" != "$ZIP_BYTES" ]; then |
| | | echo "[ERROR] è¿ç«¯æä»¶å¤§å°($REMOTE_BYTES)䏿¬å°($ZIP_BYTES)ä¸ä¸è´ï¼å·²ä¸æ¢ï¼è¿ç«¯ä¸´æ¶æä»¶ä¿çå¨ $REMOTE_TMP" >&2 |
| | | exit 1 |
| | | fi |
| | | echo "[OK] 大尿 ¡éªä¸è´ï¼$REMOTE_BYTES åèï¼" |
| | | |
| | | remote_run "mv -f '$REMOTE_TMP' '$REMOTE_DIR/$ZIP_FILE'" >/dev/null |
| | | echo "[OK] å
已就ä½" |
| | | |
| | | remote_run "command -v unzip" >/dev/null || { |
| | | echo "[ERROR] è¿ç«¯æ²¡æ unzipï¼CentOS ç¨ yum install -y unzip / Ubuntu ç¨ apt install -y unzip" >&2 |
| | | exit 1 |
| | | } |
| | | |
| | | remote_run "cd '$REMOTE_DIR' && unzip -tq '$ZIP_FILE'" >/dev/null |
| | | echo "[OK] è¿ç«¯ zip æ ¡éªéè¿" |
| | | |
| | | remote_run "cd '$REMOTE_DIR' && unzip -oq '$ZIP_FILE'" >/dev/null |
| | | echo "[OK] è§£å宿" |
| | | |
| | | remote_run "rm -f '$REMOTE_DIR/$ZIP_FILE'" >/dev/null || echo "[WARN] è¿ç«¯ zip å é¤å¤±è´¥ï¼ä¸å½±å使ç¨ï¼" |
| | | |
| | | echo |
| | | echo "============================================================" |
| | | echo " DEPLOY SUCCESS" |
| | | echo "============================================================" |
| | | echo "Company : $COMPANY" |
| | | echo "Server : $REMOTE_HOST:$PORT" |
| | | echo "Remote Dir : $REMOTE_DIR" |
| | | echo "Package : ${ZIP_FILE}ï¼${ZIP_BYTES} åèï¼" |
| | | echo "æç¤ºï¼å端æ¯éæèµæºï¼æµè§å¨ Ctrl/Cmd+Shift+R 强å·ååéªè¯ã" |
| | | echo |