Login

Build and Deploy with GitHub Actions

Let the machines take the wheel with GitHub Actions. Push an update to your Ghost theme and then see it automatically built and deployed, anywhere and everywhere.

by Ryan Feigenbaum

Build and Deploy with GitHub Actions
Photo by carlos manich / Unsplash

Share this post

Build and Deploy with GitHub Actions

Build and Deploy with GitHub Actions

GitHub Actions is a continuous integration/delivery platform that allows you to automate all kinds of things, courtesy of GitHub's servers. Ghost already provides an official GitHub Action for theme deployment.

Deploy Ghost Theme - GitHub Marketplace
Build & deploy a theme to your Ghost site

With this action configured, anytime you push an update to your theme, that update will be sent directly to your website. No upload required.

Setting up the GitHub Action couldn't be simpler. With the Ghost VS Code extension—you have the extension installed, right?—choose Ghost: Add GitHub Action from the command palette. The extension will set up everything for you. Add your secrets to GitHub, and the next time you push to GitHub, your theme changes will be pushed to your Ghost site automatically.

Ghost - Visual Studio Marketplace
Extension for Visual Studio Code - Official Ghost extension for theme development in Visual Studio Code.

You can also manually set up the Deploy Action by adding a .github folder to your theme. In that folder, create a workflows folder. Inside there, create a YAML file. You can call it whatever you want. Mine's currently called deploy-theme.yml.

Paste this juicy deploy theme recipe:

name: Deploy Theme
on:
  push:
    branches:
      - master
      - main
jobs:
  deploy:
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v3
      - name: Deploy Ghost Theme
        uses: TryGhost/action-deploy-theme@v1
        with:
          api-url: ${{ secrets.GHOST_ADMIN_API_URL }}
          api-key: ${{ secrets.GHOST_ADMIN_API_KEY }}

Remember to configure the secrets in your GitHub settings. The data for said secrets will come from setting up a custom integration in Ghost Admin. See the Action page for full installation instructions.

What's excellent about GitHub Actions is that they are infinitely customizable. I had two other things I wanted to do with my Smart theme in addition to automatically deploying it.

First, I wanted to build the theme's assets—JavaScript and CSS—before deploying. This ensures that I'm always working with a fresh build, and it helps keep my git log cleaner because I don't have to sync my build folder.

It was fairly trivial to implement. Under jobs, I added the following lines:

build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18.x'
          cache: 'npm'
      - run: npm ci
      - run: npm run build

What this does is set up a Node action that installs the necessary dependencies using npm ci or clean install. Then, it runs npm run build, which is the build script defined in package.json. (That, in turn, runs rollup -c --environment BUILD:production.)

With a fresh build of my theme's assets, the next task I wanted to accomplish was to deploy the theme, not just to a single site, but to three sites where I have the theme installed.

      - name: Deploy mc site
        uses: TryGhost/action-deploy-theme@v1
        with:
          api-url: ${{ secrets.GHOST_ADMIN_API_URL }}
          api-key: ${{ secrets.GHOST_ADMIN_API_KEY }}
      - name: Deploy demo site
        uses: TryGhost/action-deploy-theme@v1
        with:
          api-url: ${{ secrets.GHOST_DEMO_URL }}
          api-key: ${{ secrets.GHOST_DEMO_KEY }}
      - name: Deploy my site
        uses: TryGhost/action-deploy-theme@v1
        with:
          api-url: ${{ secrets.GHOST_ME_URL }}
          api-key: ${{ secrets.GHOST_ME_KEY }}

Again, not too difficult. I set up additional secrets for each site and then run the Ghost deploy action for each site. It works perfectly and is a huge quality of life-improvement. Imagine the alternative: building assets, zipping up the theme, and then logging into each site and manually uploading the file 🤮

Here's the whole YAML file:

# Learn more → https://github.com/TryGhost/action-deploy-theme#getting-started
name: Deploy Theme
on:
  push:
    branches:
      - master
      - main
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18.x'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - name: Deploy mc site
        uses: TryGhost/action-deploy-theme@v1
        with:
          api-url: ${{ secrets.GHOST_ADMIN_API_URL }}
          api-key: ${{ secrets.GHOST_ADMIN_API_KEY }}
      - name: Deploy demo site
        uses: TryGhost/action-deploy-theme@v1
        with:
          api-url: ${{ secrets.GHOST_DEMO_URL }}
          api-key: ${{ secrets.GHOST_DEMO_KEY }}
      - name: Deploy my site
        uses: TryGhost/action-deploy-theme@v1
        with:
          api-url: ${{ secrets.GHOST_ME_URL }}
          api-key: ${{ secrets.GHOST_ME_KEY }}

Now I just push the changes, sit back with a beer, and let the machines take the wheel.

Robot dancing the robot.