Using GitHub Actions to deploy static sites to GitHub Pages

Tom van Neerijnen
2 min readJan 8, 2021

Recently I used Docusaurus to create a documentation site for localhost.run. Given it builds to a static site and I was already pushing it to a GitHub repository I wanted to also host it on GitHub pages.

The thing I didn’t want to do was configure a SSH key in a GitHub secret to do this.

Turns out not only does GitHub Actions already give you a GITHUB_TOKENsecret that you can push with, but the checkout action takes care of configuring your action’s git client with this token for you. All you need to do is set an email and a name and you’re ready to push.

The example workflow I will give is for Docusaurus, but the workflow can be adapted to any framework that builds a static site.

To get ready, create your gh-pages branch (I called mine build), add a placeholder index.html, push it and configure GitHub pages to use it.

Once that’s in place, switch back to your main branch, add a .github/workflows/build.yml that does roughly what mine does, and you should be deploying your static site on every push.

My workflow can be viewed here, it looks like this at the time of writing:

name: buildon:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v2
if: github.event_name == 'push'
with:
ref: build
path: build_final
- uses: actions/setup-node@v1
with:
node-version: '12.x'
- uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: build
run: |
npm ci
npm run build
- name: push
if: github.event_name == 'push'
run: |
git config --global user.email "robot@localhost.run"
git config --global user.name "lhr robot"
cd build_final
git rm -r .
tar -C ../build/ -cf - . | tar -xf -
git add -A
test -z "$(git diff-index --name-only HEAD --)" || git commit -m "build for $GITHUB_SHA"
git push

The items to note are:

  • I only run the action on pushes to my main branch, other wise any branch, including the GitHub pages branch itself, could trigger a deploy to GitHub pages and things would get weird.
  • There are two checkout actions, one checks out the changed code and the other checks out the GitHub pages branch, in my case the build branch.
  • Docusaurus deletes the build directory, which is why you see the dance between build_final and build, if your framework changes the build directory in place you can simplify.

--

--