I thought I’d share my github action which deploys this site whenever a push a new file to main. It compiles the site with hugo and the rsyncs across to the server.

This means that my workflow is:

  1. fire up neovim and write
  2. commit and push
  3. sit back and wait for the site to update

The code for the action is below. It requires a couple of secrets to be set up:

  • SSH_PRIVATE_KEY: private key used to authenticate with the server
  • SERVER_IP: ip address of the server
  • SERVER_PATH: location on the server to sync the files to

I recommend creating a brand new keypair and use it exclusively for the github to server sync. Generate it on your local machine so that the private key is only known to you and to github. It’s also best to set up a brand new user on the server which is locked down to only accept rsync and does not permit login. There will be a subsequent post which explains how to do that.

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0

      - name: Install Hugo
        run: |
          HUGO_VERSION=0.152.2
          wget -O hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
          sudo dpkg -i hugo.deb

      - name: Build site
        run: hugo --minify

      - name: Setup SSH
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts

      - name: Deploy to server via rsync
        run: |
          rsync -avz --delete \
            -e "ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=no" \
            public/ \
            ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }}:${{ secrets.SERVER_PATH }}