Automating Documentation Builds and Deployment with GitHub Actions and GitHub Pages
Picture this: you’ve just fixed a critical bug in your Python library, updated all the docstrings, and added a new tutorial. You’re ready to push the changes, but then you remember… you need to rebuild and deploy the documentation. Again. Manually. For the third time today.
If this sounds familiar, you’re not alone. I’ve been there, and I’ve learned that automating documentation deployment isn’t just a nice-to-have - it’s essential for maintaining your sanity and ensuring your docs stay in sync with your code. In this post, I’ll show you how to set up GitHub Actions workflows that automatically build your Sphinx docs and deploy them to GitHub Pages every time you push to master.
Before We Start
You’ll need:
- A GitHub repository with your Sphinx documentation
- Basic familiarity with GitHub Actions (but don’t worry if you’re new to it)
- GitHub Pages enabled for your repository
Setting Up GitHub Pages
First things first, let’s get GitHub Pages configured. Head over to your repository’s settings and look for the “Pages” section. You have two main options:
- Deploy from a
gh-pages
branch (my preferred approach) - Deploy from the
/docs
folder on your main branch
I recommend the gh-pages
branch approach because it keeps your documentation builds separate from your source code. We’ll set up our workflow to automatically push the built HTML files to this branch.
Creating Your Documentation Workflows
We’ll create two GitHub Actions workflows:
- One for deploying documentation when pushing to master
- Another for validating documentation builds on pull requests
Let’s create these files in your .github/workflows/
directory.
The Deployment Workflow
Create .github/workflows/docs.yml
:
name: "Master Docs Publication"
on:
push:
branches: [ master ]
jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Clone
uses: actions/checkout@v1
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Build Docs
uses: ammaraskar/sphinx-action@master
with:
docs-folder: "./docs/"
- name: Deploy Docs
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: "./docs/build/html/"
The Pull Request Validation Workflow
Create .github/workflows/test-docs-build.yml
:
name: "Pull Request Docs Check"
on:
- pull_request
jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Build Docs
uses: ammaraskar/sphinx-action@master
with:
docs-folder: "docs/"
Understanding the Workflows
Let’s break down what these workflows do:
The Deployment Workflow (
docs.yml
):- Triggers when you push to the master branch
- Clones your repository
- Sets up Python 3.10
- Uses uv (a fast Python package installer) for dependency management
- Builds your documentation using sphinx-action
- Deploys the built docs to GitHub Pages
The PR Validation Workflow (
test-docs-build.yml
):- Triggers on pull requests
- Does everything the deployment workflow does except the deployment step
- Acts as a quality check to catch documentation build errors before they hit master
Treating Warnings as Errors
In many cases, you’ll want to ensure your documentation is pristine by treating warnings as errors. This helps catch issues like broken links, invalid cross-references, or missing docstrings early. To enable this in your workflow, modify the sphinx-action configuration:
- name: Build Docs
uses: ammaraskar/sphinx-action@master
with:
docs-folder: "docs/"
build-command: "sphinx-build -W -b html . build/html" # -W flag treats warnings as errors
This configuration will fail the build if any warnings are encountered, ensuring your documentation stays clean and accurate.
Setting Up Custom Domains
While GitHub Pages provides a default domain (username.github.io/repo), you might want to use a custom domain for your documentation. Here’s how to set it up:
Configure DNS: First, set up your DNS records:
- For apex domains (example.com): Create an A record pointing to GitHub’s IP addresses
- For subdomains (docs.example.com): Create a CNAME record pointing to your GitHub Pages domain
Add CNAME File: Create a CNAME file in your documentation source that will be built and deployed. Add this to your
docs/source
directory:echo "docs.example.com" > docs/source/CNAME
Update Sphinx Configuration: Modify your
docs/conf.py
to copy the CNAME file into the build output:# At the end of conf.py # Copy CNAME file to output directory html_extra_path = ['CNAME']
This tells Sphinx to copy the CNAME file directly into the HTML build output directory, ensuring it’s included in your documentation deployment.
Enable in GitHub: In your repository settings under Pages, enter your custom domain and ensure “Enforce HTTPS” is checked.
Remember that DNS changes can take up to 48 hours to propagate, though they often take effect much sooner.
Project Setup Requirements
To use these workflows, your project should have:
- A
docs/
directory at the root of your repository containing your Sphinx documentation - A
requirements.txt
file in yourdocs/
directory listing all documentation dependencies. This is required by the sphinx-action. For example:sphinx>=7.0.0 sphinx-rtd-theme>=1.3.0 myst-parser>=2.0.0 # If you use Markdown sphinx-autodoc-typehints>=1.25.0 # For better type hints
Making It Your Own
While these workflows will work out of the box for many projects, here are some common customizations:
Different Python Version: Change the python-version in the “Set up Python” step:
python-version: '3.11' # or whatever version you need
Different Branch Name: If you use ‘main’ instead of ‘master’:
branches: [ main ]
Custom Documentation Path: If your docs are in a different location:
docs-folder: "path/to/your/docs/"
The Real Benefits
This two-workflow setup gives you:
- Automatic documentation deployment on merges to master
- Early warning system for documentation issues in PRs
- Fast dependency installation with uv
- Clean separation between validation and deployment
One Last Tip
Add badges to your README to show your documentation status:
[](https://username.github.io/repo/)
[](https://github.com/username/repo/actions)
Remember: good documentation is a continuous process, not a one-time task. By automating the deployment and validation, you’re free to focus on what matters - writing great docs and great code.
Subscribe to the Newsletter
Get the latest posts and insights delivered straight to your inbox.