diff --git a/.github/workflows/docker-build-deploy.yml b/.github/workflows/docker-build-deploy.yml index 06b1b92..444493e 100644 --- a/.github/workflows/docker-build-deploy.yml +++ b/.github/workflows/docker-build-deploy.yml @@ -223,8 +223,31 @@ jobs: - name: Add server to known hosts run: | + set -euo pipefail mkdir -p ~/.ssh - ssh-keyscan -H -p "${SSH_PORT:-22}" "${SSH_HOST}" >> ~/.ssh/known_hosts + touch ~/.ssh/known_hosts + + KEYSCAN_OK=0 + for i in 1 2 3; do + echo "ssh-keyscan attempt ${i}/3: ${SSH_HOST}:${SSH_PORT:-22}" + if ssh-keyscan -T 10 -H -p "${SSH_PORT:-22}" "${SSH_HOST}" >> ~/.ssh/known_hosts 2>/tmp/ssh-keyscan.err; then + KEYSCAN_OK=1 + break + fi + sleep 2 + done + + if [ "$KEYSCAN_OK" -eq 1 ]; then + echo "SSH_COMMON_OPTS=" >> "$GITHUB_ENV" + else + echo "::warning::ssh-keyscan failed. Falling back to non-strict host checking for this run." + if [ -f /tmp/ssh-keyscan.err ]; then + echo "--- ssh-keyscan stderr ---" + cat /tmp/ssh-keyscan.err || true + echo "--------------------------" + fi + echo "SSH_COMMON_OPTS=-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" >> "$GITHUB_ENV" + fi - name: Prepare remote candidate release env: @@ -238,10 +261,10 @@ jobs: echo "镜像标签: $IMAGE_TAG" echo "部署目录: $COMPOSE_DIR/api" - echo "$ALIYUN_CR_PASSWORD" | ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" \ + echo "$ALIYUN_CR_PASSWORD" | ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" \ "docker login $REGISTRY --username=$ALIYUN_CR_USERNAME --password-stdin" - ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " + ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " set -euo pipefail mkdir -p '$COMPOSE_DIR/api' mkdir -p '$COMPOSE_DIR/api/backups' @@ -272,10 +295,10 @@ jobs: fi echo "上传候选 compose 与环境文件..." - scp -P "$SSH_PORT" ./api/docker-compose.yml "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/docker-compose.candidate.yml" - scp -P "$SSH_PORT" "$ENV_SRC" "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/.env.candidate" + scp ${SSH_COMMON_OPTS:-} -P "$SSH_PORT" ./api/docker-compose.yml "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/docker-compose.candidate.yml" + scp ${SSH_COMMON_OPTS:-} -P "$SSH_PORT" "$ENV_SRC" "$SSH_USER@$SSH_HOST:$COMPOSE_DIR/api/.env.candidate" - ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " + ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " set -euo pipefail cd '$COMPOSE_DIR/api' echo '拉取候选镜像: $IMAGE_TAG' @@ -291,7 +314,7 @@ jobs: run: | set -euo pipefail echo "切换线上版本,容器启动时将自动执行 Alembic..." - ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " + ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " set -euo pipefail cd '$COMPOSE_DIR/api' if [ -f '$COMPOSE_FILE' ]; then @@ -325,7 +348,7 @@ jobs: - name: Verify deployment run: | echo "验证部署状态..." - ssh -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " + ssh ${SSH_COMMON_OPTS:-} -p "$SSH_PORT" "$SSH_USER@$SSH_HOST" " set -euo pipefail cd '$COMPOSE_DIR/api' docker compose ps