Deploy your package documentation on GitHub Pages in the RTD style: preview PRs, and more!
epassaro
Posted on November 15, 2021
Overview
In the recent years, lot of Python packages moved their documentation pipelines from third party services like ReadTheDocs to GitHub Pages, but some useful features were missing in the process.
In this post, I'm going to describe how to write an -almost- complete RTD pipeline for GitHub Actions.
Features
Support of pip and conda dependency files.
Build and deploy branches under /branches/<branch>.
Build and deploy tags under /tags/<tag>
Secure build and preview of pull requests under /pull/<number> via labels.
Manual trigger for branches.
Select branch to deploy the site (default: gh-pages).
Redirect the main domain to /latest or /stable (default: /latest).
Redirect the /stable subdomain to the latest SemVer tag, or the stable branch (if exists).
Automatic removal of pages from closed/merged pull requests, and deleted branches or tags.
The pipeline should be triggered on the following events:
After pushing commits to main and other specified branches.
After pushing a semantic versioned tag to the repository.
After (re)opening, labeling or pushing commits on a PR using the pull_request_target event to allow sharing secrets. This behavior is constrained later at job level for security reasons.
Manually, from the GitHub Actions tab.
on:push:branches:-main# default branch-new-feature# extra branches to buildtags:-'v[0-9]+.[0-9]+.[0-9]+'# semantic versionspull_request_target:# pull request buildbranches:-'*'types:-opened-synchronize-reopened-labeled# requires the `build-docs` labelworkflow_dispatch:# manual triggerbranches:-'*'
Parameters
These are the parameters you can tweak from the env section.
PYTHON: the Python version (default: 3.9)
PKGS_FILE: a txt or yml file, depending if you want to use conda or pip to deploy your environment.
BUILD_CMD: the Sphinx build command (default: cd docs && make html).
DEPLOY_BRANCH: your GitHub Pages branch (default: gh-pages)
ROOT_REDIRECT: redirect the root URL to /latest or /stable (default: /latest, the build of default branch).
env:PYTHON:3.9PKGS_FILE:docs/requirements.txt# .txt (`pip`) or .yml (`conda`) fileBUILD_CMD:cd docs/ && make htmlDEPLOY_BRANCH:gh-pages# target branch to deploy _build/htmlROOT_REDIRECT:latest# `latest` or `stable`
The build job
Sharing secrets safely
The if condition at the top of the build job constraints the pull_request_target trigger by requiring the build-docs label trigger the job.
Only people with write access to a repository can label pull requests, so this a nice way to allow sharing secrets safely with trustworthy contributors.
Note that malicious changes to the code (in this case the Sphinx Makefile) can lead to all kinds of security issues, so make sure to review the PRs of untrusted contributors before labeling them.
Since the deployment of the site depends on the combinations of the event triggers, I needed to write a not-so-complicated bash script to handle the destination path appropriately.
Then, the peaceiris/actions-gh-pages action deploys the site on the resulting $DEST_DIR variable.