Why My GitHub Page Failed to Deploy

I was working on a few tech blogs on my reading notes. I felt that the content of the blogs became verbose, it would be nice to add a table of content to these blog posts for easier navigation. I searched around and found one Jekyll plugin jekyll-toc, which fit to my problem nicely. I set it up and tested. It worked perfectly. Then I pushed my changes.

Boom, a build failure

The build log says:

 Liquid Exception: Liquid syntax error (line 39): Unknown tag 'toc' in /_layouts/post.html
/usr/local/bundle/gems/liquid-4.0.4/lib/liquid/document.rb:23:in `unknown_tag': Liquid syntax error (line 39): Unknown tag 'toc' (Liquid::SyntaxError)

It seemed that the Jekyll plugin jekyll-toc is not officially supported by Github Page.

Dig deeper: GitHub Action uses this jekyll-build-pages by default to build the Jekyll artifacts. The github-pages dependencies need to be satisfied.

A Hacky Solution (Reference)

By understanding how GitHub Pages works for Jekyll, we can find one way to solve this problem - to build the static source files locally and push the generated files and serve that directly. Here’s the steps:

bundle exec jekyll build
cp -r _site /tmp/
git checkout -b gh-pages
rm -rf *
cp -r /tmp/_site/* ./
git commit -a -m "your commit message"
git push origin gh-pages

A Proper Solution

However the above approach is a bit manual and hacky. A better solution however, is to customize the GitHub Action Workflow. Touch the following config script as .github/workflows/jekyll.yml. The key is that we need a proper Ruby Runtime for the build to run with.

From GitHub Action starter-workflows:

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Deploy Jekyll site to Pages

on:
  push:
    branches: ["master"]
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Ruby
        uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
        with:
          ruby-version: '3.1'
          bundler-cache: true
          cache-version: 0
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v3
      - name: Build with Jekyll
        # Outputs to the './_site' directory by default
        run: bundle exec jekyll build --baseurl "$"
        env:
          JEKYLL_ENV: production
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
    
  deploy:
    environment:
      name: github-pages
      url: $
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2

Now it works for me!

References

Buy Me A Coffee