Create GitHub Pages Blog with Wyam

A guide to setting up a blog hosted by GitHub Pages generated with wyam

Published on 21 September 2019

Introduction

This is a guide to setting up a blog website that is hosted by github pages and uses wyam to generate the static content. It is based off an older guide which had some issues when following through the steps. This guide fixes those steps and streamlines the process

The overall strategy that will be used it to make a github repository called <username>.github.io that will get published to that same url. Only html content in the master branch will get published, so there will be a second orphaned branch that will contain all the source markdown and configuration files. Then the master branch will get populated by using the git subtree split command from the wyam output

First thing to do is create a folder and initialize the git repository

$ cd /path/to/dev-stuff
$ mkdir <username>.github.io
$ cd <username>.github.io
$ git init

This will initialize the master branch which should only contain the wyam output, so immediately switch to some other branch, which will be called dev here

$ git checkout --orphan dev

It is also a good idea to add the .gitignore at this stage to ensure that only the correct files are added to the repository. Note that the output folder is not added to the ignores and will be kept under source control

# Visual Studio
.vs/

# Cake build
tools/
!tools/packages.config

# Wyam
wwwroot/
config.wyam.hash
config.wyam.dll

Just a quick note, I use VisualStudio and an extension for rendering markdown content called MarkdownEditor which is why .vs/ is excluded in the ignores. It isn't required at all, but worth adding the ignore for any editor specific files that might be created

Setting up the Blog

Wyam is a excellent tool for generating static web content. It is all written in dotnet and highly modular, so you can extend it fairly easily, but also has pre-baked recipes. We'll be using the blog recipe which will give us a pipeline for transforming markdown files into a full blog site

The easiest way install wyam is through the dotnet cli as below, and other methods can be found on the wyam site

$ dotnet tool install -g Wyam.Tool

Wyam comes with a blog recipe that contains a pipeline of wyam modules. The recipe is initialized with the following command which will pull down additional tools it needs from nuget, create some configuration files, and a folder called input which is where all the source markdown pages are stored

$ wyam new -r Blog

From the input files, the wyam build command will execute the static generation pipeline and create the html pages in the output folder. This can take a few moments for a mostly blank project and up to a few minutes when there are a lot of pages to generate

$ wyam build

A development server with the standard file watch and hot reload is included to allow previewing the site on a localhost server

$ wyam preview

Cake Build

Cake is a wonderful build automation tool that uses C# script files to define the build process and some Roslyn magic to compile and run them. It is very easy to extend and has an extensive set of add-ins that cover all sorts of tools that are useful for build, including wyam

First thing to do is download the powershell bootstrapper which, when run, will download the cake executable and execute the cake script

Next is the cake build script itself, which is split into a couple of subsections. The first section does two things, first it uses preprocessor directives to inform cake that the Cake.Wyam nuget package should be downloaded and loaded for use in the script. Second it gets the command line target argument which will be used to set which task is going to be invoked

#addin nuget:?package=Cake.Wyam

var target      = Argument("target", "Deploy");

Next is the most interesting section. It defines but does not execute the tasks (yet). The first two tasks are very simple, either run the Build or run the Preview server (which includes a build). These call the Wyam() method, which is a cake extension imported from the Cake.Wyam nuget package in the first section and used the settings objects created in the second section

The final Deploy task is where the git subtree split magic happens. Deploy has a dependency on Build, so the output directory will have updated with the latest set of generated files. These files get committed to git and then subtree split will filter out all changes and files other than those in the output folder and then put those new commits into the master branch (omitting the ./output directory in the path as well). The result of this will be that the master branch has a complete versioned history of the generated (and only the generated) output, which is exactly what github pages wants

Task("Build")
    .Does(() => Wyam());

Task("Preview")
    .Does(() => Wyam(new WyamSettings {
        Preview     = true,
        Watch       = true,
    }));

Task("Deploy")
    .IsDependentOn("Build")
    .Does(() => {
        StartProcess("git", "add .");
        StartProcess("git", "commit -m \"Output files generated for subtree\"");
        StartProcess("git", "subtree split --prefix output -b master");
        StartProcess("git", "push -f origin master");
    });

The final step is a method call to tell cake which task to run. In this case target will default to Deploy unless the parameter is set when calling the script. Cake will find the specified task and create a tree of tasks that need to be run using the dependency information to execute all the required tasks

RunTarget(target);

Running the Build

Execution of the script is fairly easy. From a command prompt and assuming powershell is on the path

$ powershell ".\build.ps1"

Running the preview server is done by setting the target parameter and passing in the preview task name

$ powershell ".\build.ps1" -target Preview

Note: the versions of the cake tool and add-ins don't always match up, so it is likely you will want to add an extra argument to silence the version mismatch warning. Ignoring the warning could cause issues running the script, but most often it is fine

$ powershell ".\build.ps1" --settings_skippackageversioncheck=true

GitHub Repository

The final step is to create a repository on github and push the initial contents. The repository must be named <username>.github.io for github to understand that it is for pages, and you might also need to enable it in the 'GitHub Pages' section of the repository settings page

All that is required now is set this as the origin remote in the local repository with an https or ssh uri (both shown)

$ git remote add origin https://github.com/<username>/<username>.github.io.git
$ git remote add origin git@github.com:<username>/<username>.github.io.git

Now the cake build will push the output to github and a few seconds later the content will be available on the world-wide-web


See the next post for a complete cake build script for working with wyam