Deploy to GitHub Pages using Actions
Custom Actions workflow for Jekyll and GitHub Pages that actually works.
A GitHub Page site can be set up for either one of the following scenario:
- a repository named «user».github.io containing only the site itself in the main
- a repository containing a project and gh-pages branch for the site
The notes below apply to the former case only, which I refer to as stand-alone site. In this case GitHub by default builds and deploy the Jekyll site every time you push new commits to the repo.
This approach works fine for the majority of the cases especially when using one of the GitHub Pages supported themes and whitelisted plugins. However, this list is pretty slim compared for example to the whole rubygems.org and if your site uses a plugin not included you can’t use the default GitHub deploy method.
If this is the case you’re left with two options, both of which rely on custom GitHub Actions workflows:
- build the static site on your local machine, push the files to the remote (usually inside _site folder) and then use GitHub Actions only to publish it
- create an end-to-end GitHub Actions workflow to automatically build and deploy the site for you on remote
Going forward I analyze the end-to-end method (for a “standalone” site) since it is the most similar to the default deployment with advantage of not being limited to whitelisted plugins (i.e. any plugin from any supported source, even own repos, are allowed).
NOTE - Since August 2022 the very own GitHub Pages deployment framework is based upon GitHub Actions.
CAUTION - Many of the articles I found online refer to ‘gh-pages’ branch without providing too much details on the context. As discussed above this is a very specific scenario of project and site contained in (different branches of) the same repository. This scenario might require a specialized workflow NOT DESCRIBED HERE.
Configure the use of Actions
The build and deploy method can be changed to ‘GitHub Actions’ in the repository Settings > Pages > Build and Deploy settings.
GitHub Actions provides a set of starter workflows to be used as a base to craft your own. The workflow I picked has a basis is jekyll.yml
# Sample workflow for building and deploying a Jekyll site to GitHub Pages name: Deploy Jekyll site to Pages on: # Runs on pushes targeting the default branch push: branches: [$default-branch] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: read pages: write id-token: write # Allow one concurrent deployment concurrency: group: "pages" cancel-in-progress: true jobs: # Build job build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Setup Ruby uses: ruby/setup-ruby@0a29871fe2b0200a17a4497bae54fe5df0d973aa # v1.115.3 with: ruby-version: '3.0' # Not needed with a .ruby-version file bundler-cache: true # runs 'bundle install' and caches installed gems automatically cache-version: 0 # Increment this number if you need to re-download cached gems - name: Setup Pages id: pages uses: actions/configure-pages@v2 - name: Build with Jekyll # Outputs to the './_site' directory by default run: bundle exec jekyll build --baseurl "$" env: JEKYLL_ENV: production - name: Upload artifact # Automatically uploads an artifact from the './_site' directory by default uses: actions/upload-pages-artifact@v1 # Deployment job deploy: environment: name: github-pages url: $ runs-on: ubuntu-latest needs: build steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v1
The Jekyll starter workflow did not work out of the box for me. Here are the changes I made.
Branch to use
The starter workflow uses the ‘default branch’ variable to listen to pushes. That didn’t work for me so I hardcoded the name of the branch to listen to
on: push: branches: ['main']
I adjusted the GITHUB_TOKEN permissions removing ‘content: read’
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: pages: write id-token: write
Fine tuning the jekyll config file is possibly the most important step of the process. Running my custom workflow I stumbled upon the ‘invalid date’ issue documented in Jekyll issue #5267
Following the solution in the Jekyll issue #2938 I went on and updated my _config.yml file to exclude ‘vendor’
exclude: - vendor ## add here other paths to exclude
See also the following links for actions related to GitHub Pages build and deployment: