Hosting With GitHub Pages

Over the past couple of days, I made the switch to using GitHub as the hosting platform for my website by using GitHub Pages. This felt like a natural progression as I already used GitHub for version control for the source of my website. I initially thought the move would be confusing and time-consuming, but after the DNS changes propagated, everything was up and running just as it had been before the move.

When dealing with User Pages with GitHub Pages, the hosted files must be located in the master branch of the repository. Since I didn’t want to have separate repositories for the source of the website and for the generated files, I opted to make an orphaned branch named src which would contain the source files. While I thought this would be complicated, it turned out to be quite straightforward.

Within the root directory of my website’s source, there is an output directory that the static site files generated by Pelican go. Prior to using GitHub Pages, I had written a Bash script that would run the pelican command to generate the static site files and upload them using rsync. Obviously, this script had to be rewritten, as in order to use GitHub Pages, changes need to be pushed to a Git repository rather than being uploaded to a web server.

To accomplish this, there are two Git repository: one in the root directory of my website’s source and one in the output directory. Both remotes are configured to push to the same remote repository stored on GitHub. The local repository in the root directory has the output/ directory in its .gitignore file and commits to the src branch while the output/ repository commits to the master branch. While they are technically part of the same remote repository, each local repository is completely separate from the other.

I created an SSH key so that I do not have to manually authenticate every time git push is run by my site generation script. (Also because I have two-factor authentication enabled on my GitHub account.) While this did not work initially, it turns out that I was using the wrong remote URL; the proper URL to use over SSH (which in retrospect is quite obvious) is ssh://git@github.com:user/repo.git, rather than the HTTPS URL that is shown by default on the right side of the page when browsing the repository on GitHub.

While I use GitHub for Mac to manage the repository for the source files (the src branch), the repository for the output/ directory is only modified by the site generation script. Making use of GitHub Flavoured Markdown, the commit messages in the master branch contain links to the most recent commit in the src branch. When viewing the master branch on GitHub, the SHA hashes automagically link to the corresponding commits in the src branch that generated the changes in the static site files, making it easy to determine what changes in the source files led to changes in the generated files.

To achieve this, the script runs the following code after the pelican command generates the static site files.

#!bash
cd $sourceDirectory
commitHash=$(git rev-parse HEAD)
cd $outputDirectory
git add -A
git checkout master
read -p "Extended commit message: " commitMessage
if [ -z "$commitMessage" ]; then
    git commit -m "Generated by $commitHash"
else
    git commit -m "Generated by $commitHash" -m "$commitMessage"
fi
git push

The command git rev-parse HEAD returns the hash of the last commit in the Git repository’s history and is stored in the variable $commitHash. The directory is then changed to output/ and git checkout is run to ensure the branch that changes will be committed to is the master branch (not that it should change, but in case I were to accidentally change branches manually, this would prevents anything problematic from happening). Any changes made are then added via git add -A.

Following this, the script prompts for an extended commit message (what gets shown on GitHub after expanding the message). The first line of the commit message is “Generated by” followed by the hash of the last commit made in the src branch, and if an extended commit message is provided, the script will add it in. Finally, the commit is pushed to the master branch on GitHub.

All in all, this solution seems to work very well. I would highly recommend using GitHub Pages for static sites.