Hat tip to Timothy Pratley for his answer.
I built on it with more details. See https://github.com/deg/clojure-then-you-think/wiki/Static-website-deploy-to-GitHub
But, since the Stack Overflow moderators are rightly worried about off-site answers going stale, here's a full copy, correct as of now:
(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:
- On GitHub, go into your projects Settings|Options.
- Turn on GitHub Pages (near the bottom of the options pages).
- Deploy your compiled project to the gh-pages branch of your project. (see below!)
- 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
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.
first-deploy.sh
- 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 "git@github.com:deg/trilystro.git" master:gh-pages
git branch gh-pages
git checkout gh-pages
popd
```
deploy.sh
- 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 "git@github.com:deg/trilystro.git" gh-pages:gh-pages
popd
```