Skip to content

Static website deploy to GitHub

David Goldfarb edited this page Apr 4, 2018 · 2 revisions

(Hat tip to Timothy Pratley! The ideas here are based on his, from his whip project and Stack Overflow answer).

Many ClojureScript projects need no explicit server support. Either they do everything in the browser, or they use a cloud-based existing solution for their back-end. An example is my Trilystro toy project which is a re-frame browser app on the front-end and uses a Firebase app for persistent storage.

For this kind of project, a very easy deployment technique is to create a GitHub Pages project page. The cost is zero, and site availability seems to be good (in my very light testing).

Setup

GitHub configuration

GitHub's detailed instructions are on that page, but the steps are really amazingly simple:

  • Deploy your compiled project to the gh-pages branch of your project. (see below!)
  • On GitHub, go into your projects Settings|Options.
  • Turn on GitHub Pages (near the bottom of the options pages).
  • Your project will now be available at http://YOUR-GITHUB-ID.github.io/YOUR-GITHUB-REPOSITORY
  • Optionally setup a custom domain
    • Add your new URL as the custom domain in the options
    • At your DNS provider, add a CNAME record pointing YOUR-GITHUB-ID.github.io. Important: do not include the repository name here. (A CNAME must point to a host, not a URL).
    • Add a file named CNAME at the root of your deployed project, containing just the URL (Note: this step is done for you automatically by my Clojure deployment scripts, below)

Clojure deployment

We brushed over one critical step above. You must compile your ClojureScript project and get it into the gh-pages branch of your GitHub repository.

In broad strokes, this is very easy: just do a lein cljsbuild and push the results up to GitHub. As always, the devil is in the details. Based on Timothy Pratley's ideas, I've created two scripts that I use in Trilystro. The latest versions are here:

Let's look at them in detail: (Note, of course, that I'll probably continue to change these files in the future. The source will be more accurate than the copies below)

Trilystro is still hard-coded into these scripts in a few place. You'll need to search and replace for your own project.

  • Create a directory structure outside the local repo. This is where we will keep our working copy of the deployed site.
  • Initialize a git repo locally
  • Add the CNAME file
  • Associate this repo with the gh-pages branch on GitHub
#!/bin/bash

DEPLOYDIR=../trilystro-website
mkdir $DEPLOYDIR
pushd $DEPLOYDIR

git init

cat > CNAME <<EOF
trilystro.vuagain.com
EOF

git add .
git commit -m "Initial deploy to GitHub Pages"
git push --force --quiet "[email protected]:deg/trilystro.git" master:gh-pages

git branch gh-pages
git checkout gh-pages

popd
  • Check that the project is fully committed. We will be marking the deployment with a a git commit SHA, so we want to avoid capturing any stray changes.
  • Clean and build the project. Abort if any errors occur.
  • Clean the deployment directory, then reconstruct the CNAME file and copy in the compilation results.
  • Also copy info about the build into the deployment, in a file called git-describe.txt
  • Commit the new version to GitHub, with a comment describing the version
#!/bin/bash
# Adapted from https://github.com/timothypratley/whip/blob/master/deploy.sh
# See also https://stackoverflow.com/questions/37667931/how-do-i-deploy-a-single-page-app-written-in-clojurescript-figwheel-to-a-stat
set -e

DEPLOYDIR=../trilystro-website

RED='\033[0;31m'
NOCOLOR='\033[0m'

function die(){
  echo -e ${RED}"$1"${NOCOLOR}
  exit 1
}

if [ -n "$(git status --untracked-files=no --porcelain)" ]; then
  die "Aborting deploy. There are uncommited changes.";
fi


lein clean
lein cljsbuild once min || die "Lein cljsbuild failed!"

GIT_COMMIT=$(git show -s --oneline HEAD)

pushd $DEPLOYDIR
rm -rf *
cp -r ../trilystro/resources/public/* .
cat > CNAME <<EOF
trilystro.vuagain.com
EOF
popd

git describe --always               > $DEPLOYDIR/git-describe.txt
git log -1 --format=%cd --date=iso >> $DEPLOYDIR/git-describe.txt

pushd $DEPLOYDIR
git add .
git commit -m "Deploy $GIT_COMMIT"
git push "[email protected]:deg/trilystro.git" gh-pages:gh-pages

popd