GitHub Pages Log#
13/08/2024#
The dilemma of build files#
Intuitively I knew that including build files into a git repository is bad practice. After all, the entire purpose of git is to track source code changes, so to bloat it with arbitrary build code changes isn’t ideal.
Because of this choice, GitHub Pages’ default behaviour to simply grab the raw web content straight from my repository was no longer possible. I did some research and instead found that I would need to use GitHub Actions.
GitHub Actions is a way to instruct GitHub to run ‘jobs’ (e.g. terminal commands) given some condition (e.g. when I push to main). This is done by creating .yml
files in the specific folder named .github/workflows
.[1] The idea is that I can instruct GitHub to automatically build the files using the source
folder, which are then uploaded to GitHub pages.
Creating the workflow file#
I created a file named build-and-deploy-sphinx-site.yml
in .github/workflows
. I chose this filename as I simply thought - much like a function name - it best summarised what I wanted the file to do.
Inside the file I had the following:
name: Build and Deploy Sphinx Site to GitHub Pages
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
container:
image: sphinxdoc/sphinx
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
pip install myst-nb
pip install pydata-sphinx-theme
- name: Make static files
run: make html
- name: Package and upload artifact of static files
uses: actions/upload-pages-artifact@v3
with:
path: ./build/html
deploy:
runs-on: ubuntu-latest
needs: build
permissions:
pages: write
id-token: write
steps:
- name: Deploy uploaded artifact to GitHub Pages
uses: actions/deploy-pages@v4
As its quite a large file, I’ll now describe the contents in chunks.
In a workflow, there a three main sections:[2]
name: the name of the workflow.
on: used to automatically run the workflow based on some condition.
jobs: what commands you want to be ran.
Specifying the name of the workflow#
name: Build and Deploy Sphinx Site to GitHub Pages
Much like before, I simply chose this name as I thought it best represented what the file does. This name will show up in the GitHub interface whenever the workflow is being referenced.
Setting the conditions for the workflow to be ran#
on:
push:
branches: [ main ]
Here I’m specifying that I want the workflow to be ran everytime I push to my main branch (which is the default branch of GitHub repositories). This is because I want any changes I make to the website to be realised immediately.
Specifying the jobs to be ran#
jobs:
build:
runs-on: ubuntu-latest
container:
image: sphinxdoc/sphinx
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
pip install myst-nb
pip install pydata-sphinx-theme
- name: Make static files
run: make html
- name: Package and upload artifact of static files
uses: actions/upload-pages-artifact@v3
with:
path: ./build/html
deploy:
runs-on: ubuntu-latest
needs: build
permissions:
pages: write
id-token: write
steps:
- name: Deploy uploaded artifact to GitHub Pages
uses: actions/deploy-pages@v4
Now onto the jobs section. This is by far the most complex section. So I’ll first describe its layout.
Under jobs:
, you can specify any number of arbitrary job names. Here I have two job names, which I named build
and deploy
. Again, these job names are similar to function names.
Under each individual job, you first specify an environment to run on using runs-on
, which can be set to any arbitrary Docker image. Then you specify an arbitrary amount of steps
to perform, which simply consist of commands, or even other entire pre-made GitHub workflows.
Note
When referencing an existing workflow, you are simply using a shortened version of its repository url (e.g. https://github.com/actions/checkout
becomes actions/checkout
). Then you are required to reference a specific version (e.g. actions/checkout
becomes actions/checkout@v4
).
The version simply comes from looking at the previously mentioned url and checking for the latest release number. Although this may seem redundant, as you can specify to automatically use whatever the latest version is, it is important as it prevents a workflow causing errors after it has been updated with breaking changes.
For example, if a workflow updates from v4
to v5
, by version semantics it means it has been updated with breaking changes. This may mean existing flags which you have used will no longer work, and you will be forced to tediously update your workflow file. This process simply avoids all that to save you as much time and effort as possible.
Job 1: Building the site#
build:
runs-on: ubuntu-latest
container:
image: sphinxdoc/sphinx
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
pip install myst-nb
pip install pydata-sphinx-theme
- name: Make static files
run: make html
- name: Package and upload artifact of static files
uses: actions/upload-pages-artifact@v3
with:
path: ./build/html
Under build
, I’m using a pre-built sphinx Docker container as our environment.
In the steps
section, there are 4 main actions:
Checkout: a pre-made workflow that grabs the GitHub repository contents for our workflow to use.
Install dependencies: running pip commands to install packages that we need to build our project.
Make static files: runs the command
make html
.Package and upload artifact of static files: uses an existing GitHub workflow specifically designed to compress the
build/html/
folder into a.tar
(much like a.zip
).
Job 2: Uploading the site onto GitHub Pages#
deploy:
runs-on: ubuntu-latest
needs: build
permissions:
pages: write
id-token: write
steps:
- name: Deploy uploaded artifact to GitHub Pages
uses: actions/deploy-pages@v4
Under deploy
, I again specify an Ubuntu Docker container. I also specify some permissions as these were required by the next step.[3]
Theres only one step in this section:
Deploy uploaded artifact to GitHub Pages: a pre-made workflow specifically designed to upload the previously created
.tar
onto GitHub pages.
30/08/2024#
Modifying the GitHub workflow#
In the dev container log, I spoke about syncing a requirements.txt
file between the dev container and github workflow.
In the build section of my workflow, I edited it to the following:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Python packages
run: pip install -r ./.devcontainer/requirements.txt
- name: Make static files
run: make html
- name: Package and upload artifact of static files
uses: actions/upload-pages-artifact@v3
with:
path: ./build/html
I removed using the sphinx Docker image as it was inconsistent with my Devcontainer, and then added the similar command as above into the Install Python packages section.
Now whenever I or others need to edit our packages, we can simply edit them in one place with no further work needed.