deploy/deploy.sh you would run by hand. The server builds its own images, so
CI needs no registry and holds no application secrets — two repository secrets total,
SSH_KEY (the private key for deploy@) and SSH_HOST.
.github/workflows/deploy.yml
Hardening the CI key
A key that can run any command is a key that can read your.env. Lock it to one command
with a forced command in the server’s ~deploy/.ssh/authorized_keys:
ssh argument is then ignored and the key cannot open a shell.
Add
feather check and feather security-check to the test job. Both exit non-zero on
failure, so a convention violation or a weak secret stops the deploy rather than
shipping.