diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 4be6714..7f149d0 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -96,43 +96,33 @@ jobs: chmod 600 ~/.ssh/id_ed25519 printf '%s\n' "$SFTP_KNOWN_HOSTS" > ~/.ssh/known_hosts chmod 644 ~/.ssh/known_hosts - # Hetzner Webhosting accounts are SFTP-only — they accept SSH for file - # transfer but refuse remote command exec ("exec request failed on - # channel 0"). rsync over SSH needs to spawn a remote rsync binary, - # so it cannot work here. Use lftp's mirror instead, which speaks - # SFTP end-to-end with the same key + known_hosts pinning. - if ! command -v lftp >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then + # Ensure rsync + openssh are present even on a minimal runner image. + if ! command -v rsync >/dev/null 2>&1 || ! command -v ssh >/dev/null 2>&1; then if command -v sudo >/dev/null 2>&1; then SUDO=sudo; else SUDO=; fi $SUDO apt-get update -qq - $SUDO apt-get install -y --no-install-recommends lftp openssh-client + $SUDO apt-get install -y --no-install-recommends rsync openssh-client fi - - name: Deploy via lftp (mirror over SFTP) + - name: Deploy via rsync env: SFTP_USER: ${{ secrets.SFTP_USER }} SFTP_HOST: ${{ secrets.SFTP_HOST }} SFTP_PATH: ${{ secrets.SFTP_PATH }} run: | - # Fail loudly if any secret is missing — otherwise mirror --delete + # Fail loudly if any secret is missing — otherwise rsync --delete # could be directed at the SSH user's home root. : "${SFTP_USER:?SFTP_USER secret must be set}" : "${SFTP_HOST:?SFTP_HOST secret must be set}" : "${SFTP_PATH:?SFTP_PATH secret must be set}" - # `-u USER,` (with trailing comma = empty password) tells lftp not - # to prompt for a password; auth happens via the key passed to ssh - # by sftp:connect-program. Heredoc body is unindented so lftp's - # parser doesn't mistake leading whitespace for a continuation. - # `debug 3` prints the ssh command lftp invokes — useful if this - # ever breaks again. - lftp <