The step failed silently (exit 1, no message) because stderr was
redirected to /dev/null while sh -e aborts on ssh-keyscan's non-zero
exit. Let the real error (DNS/firewall/etc.) show up in the log.
None of these are sensitive, so use Actions variables (vars) instead of
secrets. DEPLOY_PORT is now its own variable (default 22) rather than
being packed into DEPLOY_HOST. Only DEPLOY_SSH_KEY remains a secret.
ssh-keyscan and rsync's -e ssh both need the port passed via -p rather
than embedded in the hostname; parse DEPLOY_HOST accordingly, defaulting
to 22 when no port is given.
Avoids tying CI to a personal/bot Gitea account: the same DEPLOY_SSH_KEY
secret used for the webserver rsync step is reused as a read-only Gitea
deploy key on hmk/pelican-latex. The submodule's tracked HTTPS URL is
overridden to SSH just for this checkout so it authenticates with that
key instead of needing a token with access to both repos.
The default per-job Actions token only covers the triggering repo; the
theme submodule lives in a separate private repo (hmk/pelican-latex), so
cloning it needs a token with read access to both. Add CHECKOUT_TOKEN
as a repo secret (a Gitea access token with repo read scope) for this
to work.