Skip to content

Instantly share code, notes, and snippets.

@stanbar
Last active July 13, 2022 13:09
Show Gist options
  • Save stanbar/4d113f91b0f5ad6544c3d130d01ea21a to your computer and use it in GitHub Desktop.
Save stanbar/4d113f91b0f5ad6544c3d130d01ea21a to your computer and use it in GitHub Desktop.
Deploy GH Pages via dedicated branch

Deployment via gh-pages branch

I find this the cleanes and robust approach to deploying website via gh pages. It deploys site through a separate branch called "gh_pages". That approach is a bit more complex but has some advantages:

  • It keeps sources and generated HTML in two different branches
  • It uses the default public folder
  • It keeps the histories of source branch and gh-pages branch fully separated from each other

Preparations

These steps only need to be done once (replace "upstream" with the name of your remote, e.g. "origin"): First, add the public folder to .gitignore so it's ignored on the master branch:

echo "public" >> .gitignore

Then initialize the gh-pages branch as an empty orphan branch:

git checkout --orphan gh-pages
git reset --hard
git commit --allow-empty -m "Initializing gh-pages branch"
git push origin gh-pages
git checkout main

Building and Deployment

Now check out the gh-pages branch into your public folder, using git's worktree feature (essentially, it allows you to have multiple branches of the same local repo to be checked out in different directories):

rm -rf public
git worktree add -B gh-pages public origin/gh-pages

Regenerate the site using Hugo and commit the generated files on the gh-pages branch:

hugo
cd public && git add --all && git commit -m "Publishing to gh-pages" & cd ..

If the changes in your local gh-pages branch look alright, push them to the remote repo:

git push origin gh-pages

After a short while you'll see the updated contents on your GitHub Pages site.

Putting it into a script

To automate these steps, you can create a script scripts/publish_to_ghpages.sh with the following contents:

#!/bin/sh

DIR=$(dirname "$0")

cd $DIR/..

if [[ $(git status -s) ]]
then
    echo "The working directory is dirty. Please commit any pending changes."
    exit 1;
fi

echo "Deleting old publication"
rm -rf public
mkdir public
git worktree prune
rm -rf .git/worktrees/public/

echo "Checking out gh-pages branch into public"
git worktree add -B gh-pages public origin/gh-pages

echo "Removing existing files"
rm -rf public/*

echo "Generating site"
hugo

echo "Updating gh-pages branch"
cd public && git add --all && git commit -m "Publishing to gh-pages (publish.sh)"

This will abort if there are pending changes in the working directory and also makes sure that all previously existing output files are removed. Adjust the script to taste, e.g. to include the final push to the remote repository if you don't need to take a look at the gh-pages branch before pushing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment