Continuous Deployment of Ghost Themes
When I restarted my blog (this is at least blog v3) using Ghost I wanted to get up and running as quickly as possible so I purchased the Horace theme and followed the installation instructions - which basically came down to:
- Extract the theme’s .zip file to a directory.
- Make any modifications you need.
- Create a new .zip file.
- Upload the .zip file in Ghost Admin.
This process was fine once, maybe twice, but as I made more tweaks it was mind-numbing. This is where GitHub Actions saved the day (DISCLAIMER: I work at GitHub but not on GitHub Actions).
The first thing I did was create a new GitHub repository (blog-theme
) and I added the contents of the theme’s .zip
file to that repository. I kept this as a private repository because the Horace theme is commercially license so I can’t legally share it.
Once I had the theme’s contents in a repository I looked to see if Ghost has an API for uploading themes - it turned out it did. I knew it wouldn’t be hard to write a GitHub action that used the API to upload a theme but on the off-chance someone had already written it I searched the GitHub Marketplace - lo and behold there was. Not only that, it was an official GitHub action from Ghost!
With that knowledge in hand I set to creating an extremely simple GitHub Actions workflow which I saved to .github/workflows/CD.yaml
in the repository:
name: CD
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy Ghost Theme
uses: TryGhost/action-deploy-theme@v1.4.1
with:
api-url: https://willbar.com
api-key: ${{ secrets.GHOST_ADMIN_API_KEY }}
This workflow would trigger whenever there was a push to the main
branch and I also added workflow_dispatch
which allows me to manually trigger the workflow from the GitHub Actions user interface.
The job then simply calls a GitHub Action (actions/checkout
) to clone the repository and then calls the GitHub Action from Ghost to deploy the theme (TryGhost/action-deploy-theme
). To give me control over upgrades to the GitHub actions I pinned them both to specific tags (if I was being extra paranoid I could have pinned them to specific commits).
The TryGhost/action-deploy-theme
action assumes the theme’s content is in the default directory that actions/checkout
clones to so I didn’t have to configure any paths, I simply had to provide the base URL for the API (my blog https://willbar.com
in this case) and an API key.
To get an API key you go to Integrations in Ghost Admin and create a custom integration, give it any name you like (I simply called mine GitHub
), and then copy the generated Admin API key. Committing secrets to your repository - even if it’s private - should be avoided, so I used GitHub Action’s built-in feature to protect the secret. This was as simple as going to the repository’s Settings, clicking Secrets, and adding a new secret called GHOST_ADMIN_API_KEY
(this name has to match the one in the workflow) and pasting the Admin API key generated earlier.
Now whenever I push a new commit to the repository my blog’s theme is automatically updated.