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" PASS: "123quant-speed" TARGET_DIR: "/home/quant-speed/data/dev/ESP32_GDEY042T81_server" REPO_URL: "https://gitea.tangledup-ai.com/Tangledup-ai/ESP32_GDEY042T81_server.git" run: | # 创建一个 shell 脚本,包含所有需要在服务器上执行的逻辑 # 这样可以避免在 expect 中处理复杂的条件判断和转义 cat > remote_script.sh <<'EOS' #!/bin/bash # 获取密码 PASSWORD="$1" TARGET_DIR="$2" RUN_USER="$3" REPO_URL="$4" # 1. 确保目录存在 (脚本已通过 sudo 运行) if [ ! -d "$TARGET_DIR" ]; then mkdir -p "$TARGET_DIR" fi # 2. 修正权限,确保用户拥有目录 chown -R "$RUN_USER:$RUN_USER" "$TARGET_DIR" # 3. 进入目录 cd "$TARGET_DIR" # 4. 执行 Git 操作 (以用户身份执行,避免 .git 权限问题) # 使用 sudo -u 切换到普通用户执行 git echo "Deploying code as $RUN_USER..." FRESH_CLONE=0 if [ ! -d ".git" ]; then echo "Not a git repository. Cloning from $REPO_URL..." # Handle non-empty dir if necessary if [ "$(ls -A)" ]; then echo "Directory not empty. initializing git..." sudo -u "$RUN_USER" git init sudo -u "$RUN_USER" git remote add origin "$REPO_URL" sudo -u "$RUN_USER" git fetch origin sudo -u "$RUN_USER" git checkout -b main --track origin/main || sudo -u "$RUN_USER" git reset --hard origin/main else sudo -u "$RUN_USER" git clone "$REPO_URL" . fi FRESH_CLONE=1 fi if [ "$FRESH_CLONE" -eq 0 ]; then OLD_HEAD=$(sudo -u "$RUN_USER" git rev-parse HEAD 2>/dev/null || echo "") echo "Pulling latest code..." if ! sudo -u "$RUN_USER" git pull origin main; then echo "Git pull failed" exit 1 fi NEW_HEAD=$(sudo -u "$RUN_USER" git rev-parse HEAD) if [ "$OLD_HEAD" == "$NEW_HEAD" ]; then echo "No changes detected, skipping deploy" exit 0 fi else OLD_HEAD="" NEW_HEAD=$(sudo -u "$RUN_USER" git rev-parse HEAD) fi # 5. 执行 Docker 操作 (以 root 身份执行) # 检查构建文件变动 FORCE_REBUILD=0 if [ "$FRESH_CLONE" -eq 1 ]; then FORCE_REBUILD=1 fi if [ "$FORCE_REBUILD" -eq 1 ] || sudo -u "$RUN_USER" git diff --name-only $OLD_HEAD $NEW_HEAD | grep -E 'Dockerfile|requirements.txt'; then echo "Build files changed or fresh clone, rebuilding..." docker compose down --rmi local docker rmi epaper_server:latest || true docker compose up -d --build else echo "Only code changed, restarting container..." docker compose down docker compose up -d fi EOS # 创建 expect 脚本,负责上传到 /tmp 并 sudo 执行 cat > deploy_script.exp <