The last time I dabbled in the background for this Hugo-powered site, I was deploying it to a webserver I pay for. Since then, I’ve been looking at how to deploy it to GitHub Pages for free, and to simplify a multiple-workstation-life.
The caveat to GitHub Pages is that, on a free GitHub account, you can only use the feature on public repositories. What I wanted to do was keep my source files and drafts in a private repository, and have the generated static site pushed to the public repository which GitHub Pages would pull from.
This is how I managed it using
git submodule. A word of warning: submodules are complicated. This setup works well for me, a singular person, who updates on one machine. Nonetheless, I hope this post helps someone as a starting point.
Note: If you really do not want it to be a public repository, Netlify allows deploys in private repositories!
Setting up submodules
I have two GitHub repositories:
<username>.github.iois the public, GitHub pages-enabled repository
blogis the private repository holding source files and all drafts
In Hugo, the
hugo command generates the static site in a /public directory by default. So /public has to be move from being a directory in the
blog private repository to its own public repository pointing to
I used Git submodules for this. It’s confusing. So here is what worked for me.
First, I deleted the public folder (
rm -rf public). This is okay because we can generate those files again. Then:
git submodule add email@example.com:<username>/<username>.github.io.git public git submodule init
The first line checks out the GitHub Page repository and adds it to the blog repository under the directory public.
The second line pulls the code from the repository.
For sanity check, I
hugo to generate files to the
public directory. I
cd public and check
git remote -v and then
cd .. and check
git remote -v to make sure they’re pointing to different repositories.
If, like me, you managed to mess up your submodules, checking what was up in the /.git/modules directory helped me to clean up.
A new deploy script
All right, so now the commands to deploy are a little finicky. I have to generate the site, push the changes to the public repository, then push the source files to the private repository. Not only that, Hugo changes and adds files, it doesn’t delete. So I have to wipe the contents of public without removing its references to Git. Whew.
So I ended up with an executable (
chmod +x deploy.sh) deploy.sh script like this:
rm -rf public/* # Remove all files except dot files # echo "<domain.tld>" >> public/CNAME # If you use a custom domain hugo # Generate the static files into /public cd public git add . git commit -m "Rebuilding site" git push origin master cd .. git add . git commit -m "Updating source and draft content" git push origin master
Now, once you create your content, you can use
./deploy.sh and it will generate the new files, and add it to each respective Git repository. It is not quite clean — if you are using multiple machines, you will need to
git submodule init and then
git submodule update to set the remotes correctly.