111 lines
3.7 KiB
YAML
111 lines
3.7 KiB
YAML
name: Deploy to Server
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
- master
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: ubuntu
|
|
steps:
|
|
# 直接使用 expect 脚本处理交互,比 sshpass 更稳定,尤其是在 Alpine 上
|
|
|
|
- name: Install dependencies
|
|
run: |
|
|
if command -v apt-get &> /dev/null; then
|
|
apt-get update
|
|
apt-get install -y expect openssh-client
|
|
elif command -v apk &> /dev/null; then
|
|
apk update
|
|
apk add expect openssh-client bash
|
|
else
|
|
echo "Unknown package manager"
|
|
exit 1
|
|
fi
|
|
|
|
- name: Deploy to server
|
|
env:
|
|
HOST: "6.6.6.66"
|
|
USER: "quant-speed"
|
|
PASS: "123quant-speed"
|
|
TARGET_DIR: "/home/quant-speed/data/dev/ESP32_GDEY042T81_server"
|
|
run: |
|
|
# 创建一个 shell 脚本,包含所有需要在服务器上执行的逻辑
|
|
# 这样可以避免在 expect 中处理复杂的条件判断和转义
|
|
cat > remote_script.sh <<'EOS'
|
|
#!/bin/bash
|
|
|
|
# 获取密码
|
|
PASSWORD="$1"
|
|
|
|
# 记录旧版本号
|
|
OLD_HEAD=$(git rev-parse HEAD 2>/dev/null || echo "")
|
|
|
|
# 尝试直接 git pull
|
|
echo "Pulling latest code..."
|
|
if ! git pull; then
|
|
echo "Git pull permission denied, trying with sudo..."
|
|
echo "$PASSWORD" | sudo -S git pull || { echo "Git pull failed"; exit 1; }
|
|
fi
|
|
|
|
NEW_HEAD=$(git rev-parse HEAD)
|
|
|
|
if [ "$OLD_HEAD" == "$NEW_HEAD" ]; then
|
|
echo "No changes detected, skipping deploy"
|
|
exit 0
|
|
fi
|
|
|
|
# 检查构建文件变动
|
|
if git diff --name-only $OLD_HEAD $NEW_HEAD | grep -E 'Dockerfile|requirements.txt'; then
|
|
echo "Build files changed, rebuilding..."
|
|
echo "$PASSWORD" | sudo -S docker compose down --rmi local
|
|
echo "$PASSWORD" | sudo -S docker rmi epaper_server:latest || true
|
|
echo "$PASSWORD" | sudo -S docker compose up -d --build
|
|
else
|
|
echo "Only code changed, restarting container..."
|
|
echo "$PASSWORD" | sudo -S docker compose down
|
|
echo "$PASSWORD" | sudo -S docker compose up -d
|
|
fi
|
|
EOS
|
|
|
|
# 创建 expect 脚本,只负责上传脚本和执行脚本
|
|
cat > deploy_script.exp <<EOF
|
|
#!/usr/bin/expect -f
|
|
|
|
set timeout 300
|
|
set host "$HOST"
|
|
set user "$USER"
|
|
set password "$PASS"
|
|
set target_dir "$TARGET_DIR"
|
|
|
|
# 1. SSH 连接并创建目录
|
|
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \$user@\$host "mkdir -p \$target_dir"
|
|
expect {
|
|
"yes/no" { send "yes\r"; exp_continue }
|
|
"password:" { send "\$password\r" }
|
|
}
|
|
expect eof
|
|
|
|
# 2. 上传脚本
|
|
spawn scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null remote_script.sh \$user@\$host:\$target_dir/deploy.sh
|
|
expect {
|
|
"password:" { send "\$password\r" }
|
|
}
|
|
expect eof
|
|
|
|
# 3. 执行脚本
|
|
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -t \$user@\$host "cd \$target_dir && chmod +x deploy.sh && bash deploy.sh '\$password'"
|
|
expect {
|
|
"password:" { send "\$password\r" }
|
|
}
|
|
|
|
# 保持交互直到脚本执行完毕
|
|
expect eof
|
|
EOF
|
|
|
|
# 执行 expect 脚本
|
|
chmod +x deploy_script.exp
|
|
./deploy_script.exp
|