scp
on GitHub Actions
I decided to try and use a GitHub Action to copy some content onto an FTP server. At first I tried to use an existing action, but it didn't work and debugging was proving to be cumbersome. Then, I changed strategy and used an action with CLI commands instead.
Note: I would prefer using rsync
but it is not an option in this case. Also, I do not have SSH access to the server – it's SFTP only.
The action looks roughly like this:
name: Copy files
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: scp
run: |
mkdir -p ~/.ssh/
chmod 700 ~/.ssh/
touch ~/.ssh/known_hosts
ssh-keyscan ${{ secrets.HOST }} >> ~/.ssh/known_hosts
echo "$SSH_PRIVATE_KEY" > ~/.ssh/deploy_key
chmod 600 ~/.ssh/deploy_key
scp -i ~/.ssh/deploy_key -s -r some_file some_dir "${{ secrets.USERNAME }}@${{ secrets.HOST }}:"
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
Getting to this has been a bit difficult, so here are a few notes on the details:
scp
needs to use a private SSH key, which cannot be added to GitHub as a file. I've added the key material as a GitHub secret and imported it as an environment variable. The key file is then (re)written by the action itself.- The
.ssh
directory has to be created manually, first of all because the host key has to be added toknown_hosts
(here withssh-keyscan
). If this is not done,scp
fails withHost key verification failed.
(Seen on StackOverflow) - The
scp
command needs to include the-s
switch to force the SFTP protocol. This will likely change in the future, but with the currentubuntu-latest
the installed OpenSSH version does not use SFTP as a default.
I am not yet 100% sure this is completely secure, so I'll keep checking. For example: is ssh-keyscan
good enough, or do I need to get the key beforehand and then inject it manually into known_hosts
?