Deploying your static site using GitHub Action workflow
/ 3 min read
Table of Contents
Prerequisites
- Basics are explained in the previous post about deploying an artefact
- As you might have guessed already: a GitHub Action workflow requires your repository to be on GitHub.
- Some of the steps in that workflow are specific to my site/project, e.g., the node version, the package manager (yarn, pnpm, npm, …), and so on.
- Set up environment/repository secrets and variables in GitHub
This is actually very similar to the previous post, but instead of on your laptop/pc this happens on a GitHub runner. It deals differently with variables and secrets, to protect your private key or other sensitive information from being leaked accidentally. It also helps with managing those for several environments, but let’s pretend there is no staging first.
Step by step
- Create
.github/workflows/deploy.yml
in your project - Add trigger
name: 'Deploy artefact'on: workflow_dispatch:
jobs: deploy: runs-on: ubuntu-latest steps:
- Add step: check out the repository
- name: 'Check out repository' uses: actions/checkout@v4
- Add steps: install node and pnpm
- name: 'Install node' uses: actions/setup-node@v4 with: node-version: 18 registry-url: 'https://npm.pkg.github.com'- name: 'Install pnpm' uses: pnpm/action-setup@v4 with: version: 8.6.1 run_install: false
- Add steps: install dependencies and build artefact
- name: 'Install dependencies' run: pnpm install- name: 'Build artefact' run: pnpm build
- Add step: prepare deployment and execute deployment via rsync
- name: 'Prepare secrets for ssh connection and execute deployment' env: DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} SSH_PASS: ${{ secrets.SSH_PASS }} USER: ${{ vars.REMOTE_USER }} HOST: ${{ vars.REMOTE_HOST }} DIR: ${{ vars.REMOTE_DIR }} run: | mkdir -p ~/.ssh echo "$DEPLOY_KEY" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 ssh-keyscan -t ed25519, "$HOST" >> ~/.ssh/known_hosts eval "$(ssh-agent -s)" echo "$SSH_PASS" | ssh-add <(echo "$DEPLOY_KEY") rsync -avzr -e 'ssh -o StrictHostKeyChecking=no -v' --delete ./dist/ "${USER}"@"${HOST}":/var/www/html/"${DIR}"
Obviously, it is the step that is the most complex one. Let’s analyse what happens there:
env: DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} SSH_PASS: ${{ secrets.SSH_PASS }} USER: ${{ vars.REMOTE_USER }} HOST: ${{ vars.REMOTE_HOST }} DIR: ${{ vars.REMOTE_DIR }}
Additionally to the action, I stored two secrets and three variables in GitHub.
DEPLOY_KEY
: the private ssh key necessary to access the vps via sshSSH_PASS
: the corresponding passphrase for the private keyUSER
: name of the user the private ssh key belongs toHOST
: ip address of the vpsDIR
: name of the directory on the vps that contains the artefact
Next, the ssh key needs to be stored on the runner (which is also a Ubuntu machine):
mkdir -p ~/.sshecho "$DEPLOY_KEY" > ~/.ssh/id_ed25519chmod 600 ~/.ssh/id_ed25519
- After that, the ssh key is added to the known_hosts file and associated to the remote host (
$HOST
):
ssh-keyscan -t ed25519, "$HOST" >> ~/.ssh/known_hosts
Before we can open a ssh connection we need to start the ssh agent and add the private key together with its corresponding passphrase to the ssh agent:
eval "$(ssh-agent -s)"echo "$SSH_PASS" | ssh-add <(echo "$DEPLOY_KEY")
Finally, the artefact can be deployed via rsync to the configured :
rsync -avzr -e 'ssh -o StrictHostKeyChecking=no -v' --delete ./dist/ "${USER}"@"${HOST}":/var/www/html/"${DIR}"
Troubleshooting
Why can I not find my manually triggered workflow?
An ‘instance’ of the workflow must first exist on the main
branch of your repository.
After you have merged your workflow into your main
branch, it will show up in Actions
But I don’t want to test my workflow on my main branch
- Register dummy file with manual trigger on
main
- Then work on ti branch
The deployment step does not work as expected
- Please check whether you have properly set up your environment/repository variables and secrets.
- Please check whether the user that technically executes the deployment (the owner of the private key) has ownership of the directories on your vps.
- Please read the error logs of the failed run.