In order to migrate my Ghost blog I needed to customize the default theme to support some of the features I'm relying on in bold:

In the mean time Ghost is working on their new Koenig editor, causing a steady stream of small changes to the default Casper theme. To be able to quickly integrate updates without too much fuss I'm maintaining a forked version of the Casper theme containing all my changes.

This raises two questions:

  1. How do I integrate the changes from the main Casper repo without overwriting my own changes.
  2. How do I deploy my changes from GitHub to my blog without hassle.

Integrating changes from the main Casper Theme

I created my own fork of the Casper theme by forking the main repository to my own GitHub account. In that repo I've created a new branch called Customized. This is where I keep all my own changes. After cloning the repository I added the original repo as a remote:

git remote add ghost https://github.com/TryGhost/Casper.git

This will allow me to pull in changes to my own repository using

git checkout master
git pull ghost master

And then integrate these changes to my customized version:

git checkout customized
git merge master -m "Updating to Casper-2.3.3"

And then resolving the conflicts, testing on a local Ghost Development instance and pushing back to GitHub.

Deploy Ghost theme using VSTS

The next step is to get these changes from GitHub back to Ghost. I'm using Visual Studio Team Services to automate this workflow. The steps were pretty straight forward:

  1. Link VSTS to GitHub.
  2. Install the Ghost extension from the marketplace.
  3. Setup a CI pipeline to push the changes from GitHub to Ghost.

The Ghost extension for VSTS is still a bit rough around the edges, but the developer is quickly responding to feedback, removing my initial issues with the task. It's now very fast and does what it needs to do.

Next step is to create a new Build Definition in Visual Studio Team service and to link it to your GitHub account. Make sure you select the customized branch, as this is going to be the version of the theme we want to publish.

Create a Build Definition and link it to the GitHub repository.

Depending on the level of customization, you may need to build the theme. In my case I haven't ventured that deep into customization yet, so it suffices to just zip up the archive:

Zip up the theme in order to prepare it for publishing

The final required step is to let the Ghost Task publish the theme to your Ghost instance. I found out that the name of the theme is important, as Ghost may decide to create a new theme or overwrite the existing one depending on the name.

Click the Manage link next to Blog connection to create a new Ghost Credential:

Add a Ghost connection to your project.

While debugging you may want to use the Take Screenshots option to see what the Ghost extension is up to. It relies on controlling a browser instance to upload the theme. The Hosted Agent has Chrome installed and the Ghost task should detect it automatically, meaning you won't have to download Chromium. If you agent doesn't have Chrome installed and installing is not an option, you can use the Chromium task to grab Chromium on the fly.

Use the Hosted VS2017 agents to satisfy the requirement for interactive agents.
If Chromium isn't detected automatically, add the chromium.bin variable and point it to chrome.exe.

That's all! Queue your build, if needed analyze the logs and the screenshots, but if all was well your theme should now be versioned in GitHub and auto-deploy through Visual Studio Team Services!

The Ghost task in action.

Are you using Ghost to blog? Is your customized Theme easy to upgrade whenever Ghost releases a new version? If not, there really is no excuse :).