This is the setup that deploys this site. Every push to master runs a GitHub Actions job that connects to the server over SSH and resets the theme folder to the new commit. There’s no build step and no FTP, and a deploy takes about 20 seconds.

1. Create a dedicated deploy key

Use a key that exists only for deployments, without a passphrase, so you can revoke it without touching your personal key.

ssh-keygen -t ed25519 -f ~/.ssh/theme_deploy -N "" -C "github-actions-deploy"

2. Authorise the key on the server

ssh USER@HOST "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys" < ~/.ssh/theme_deploy.pub
ssh -i ~/.ssh/theme_deploy -o IdentitiesOnly=yes USER@HOST "echo ok"

If the second command prints ok, the key works on its own. If it fails, check /var/log/auth.log on the server: it names the exact reason.

3. Clone the theme on the server

cd /var/www/html/wp-content/themes
git clone https://github.com/YOUR_USER/YOUR_THEME.git your-theme

For a private repository, add a read-only deploy key to the repository settings and clone over SSH instead.

4. Add the GitHub secrets

In the repository, open Settings → Secrets and variables → Actions and add:

5. Write the workflow

Create .github/workflows/deploy.yml:

name: Deploy theme

on:
  push:
    branches: [master]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy over SSH
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            set -e
            cd "${{ secrets.VPS_THEME_PATH }}"
            git fetch origin master
            git reset --hard origin/master
            chown -R www-data:www-data .
            find . -type f -exec chmod 644 {} ;
            find . -type d -exec chmod 755 {} ;

git reset --hard makes the server match the repository exactly, so a deploy can never leave half-edited files behind. Never edit theme files directly on the server: the next deploy overwrites them.

6. Test and troubleshoot

Push a commit and open the Actions tab. Common failures: