To get Hugo up to the webserver, I had to scp the files up there using my keyfile. For that, I started with the image that I gave the docker tag, which is one of the default Forgejo images.
Setting up variables#
First I set up a bunch of variables:
WEBSERVER_SSH_USERNAME: my username on the webserverWEBSERVER_SSH_HOST: the hostname of the webserver I upload toWEBSERVER_HTML_DIR: the directory where the webserver files get sent
Setting up secrets#
I ended up with two secrets:
SSH_PRIV_KEY: my private keySSH_KNOWN_HOSTS: I also needed to set up my~/.ssh/known_hostsso that I wouldn’t get errors when connecting via scp. I temporarily threw away my existingdeploy.yamland built a new one that did a little (very little) ssh using sftp:
on: [push]
deployscp:
runs-on: docker
steps:
- run: |
echo dir > ftpbatch
echo bye >> ftpbatch
- name: setup ssh
run: |
mkdir -p ~/.ssh
chmod 0700 ~/.ssh
echo "${{ secrets.SSH_PRIV_KEY }}" > ~/.ssh/id_rsa_webserver
chmod 0600 ~/.ssh/id_rsa_webserver
ssh-keyscan ${{ vars.WEBSERVER_SSH_HOST }} >> ~/.ssh/known_hosts
cat ~/.ssh/known_hosts
- name: push public
run: |
echo about to sftp
sftp -i ~/.ssh/id_rsa_webserver -b ./ftpbatch ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }}
echo did sftpThe first time I ran that, I copied the output of the cat ~/.ssh/known_hosts line into the secret SSH_KNOWN_HOSTS. Then I updated deploy.yaml to use the secret instead:
on: [push]
deployscp:
runs-on: docker
steps:
- run: |
echo dir > ftpbatch
echo bye >> ftpbatch
- name: setup ssh
run: |
mkdir -p ~/.ssh
chmod 0700 ~/.ssh
echo "${{ secrets.SSH_PRIV_KEY }}" > ~/.ssh/id_rsa_webserver
chmod 0600 ~/.ssh/id_rsa_webserver
echo "${{ secrets.SSH_KNOWN_HOST }}" > ~/.ssh/known_hosts
chmod 0600 ~/.ssh/known_hosts
- name: push public
run: |
echo about to sftp
sftp -i ~/.ssh/id_rsa_webserver -b ./ftpbatch ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }}
echo did sftpI was hoping that Forgejo would preserve the line separators that I pasted into the secret dialog. It did! Nice!
Add Hugo back to the build and really upload#
With a working sftp (and presumably a working ssh) and a good private key, I could add the hugo step back. It packages up the build, then the docker image retrieves the build and uploads the important bit. Here’s the whole enchilada:
on: [push]
jobs:
buildhugo:
runs-on: hugo
steps:
- run: hugo version
- uses: actions/checkout@v4
with:
submodules: 'recursive'
- name: run hugo
run: hugo --gc --minify
- name: fix up RSS
run: cp ./public/index.xml ./public/rss.xml
- name: stash public files
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
with:
name: public
path: ./public/
deployscp:
runs-on: docker
needs: buildhugo
steps:
- name: grab public files
uses: https://code.forgejo.org/forgejo/download-artifact@v4
- name: setup ssh
run: |
mkdir -p ~/.ssh
chmod 0700 ~/.ssh
echo "${{ secrets.SSH_PRIV_KEY }}" > ~/.ssh/id_rsa_webserver
chmod 0600 ~/.ssh/id_rsa_webserver
echo "${{ secrets.SSH_KNOWN_HOST }}" > ~/.ssh/known_hosts
chmod 0600 ~/.ssh/known_hosts
- name: push public
run: |
ssh -i ~/.ssh/id_rsa_webserver ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }} 'rm -rf /home/${{ vars.WEBSERVER_SSH_USERNAME }}/${{ vars.WEBSERVER_HTML_DIR }}/*'
scp -r -i ~/.ssh/id_rsa_webserver ./public/* ${{ vars.WEBSERVER_SSH_USERNAME }}@${{ vars.WEBSERVER_SSH_HOST }}:/home/${{ vars.WEBSERVER_SSH_USERNAME }}/${{ vars.WEBSERVER_HTML_DIR }}/This makes it look easy. It wasn’t. I was nervous about the process, and started with echo ssh -i ~/... and echo scp -r -i ~/... instead of actually running the ssh and scp commands. I made sure things looked right in the Actions window on the Forgejo server before I did the scp for real, and it took me a couple more deep breaths before I did the ssh (which does a rm -rf).
Ultimately, I had to run things 70 times — I counted — before I got a working deploy. Lots of echo and ls -al to make sure I was oriented. And probably a third of the commits were fixes for this error:
Workflow was not executed due to an error that blocked the execution attempt.
Unable to parse supported events in workflow: yaml: line 25: found a tab character where an indentation space is expectedI really need to set my Emacs up so it uses only spaces for yaml files. Esc-X untabify was my best friend.
Now, I have a website that updates automatically when I push the code. Not when I commit — I’m still trying to remember that git push origin after publishing. I think I’ll commit this and do that now.