Onion Information
Publishing (Material for) MkDocs website to GitHub Pages using custom Actions workflow - GASERI
As you can probably see, this website is built using the Material theme for MkDocs, which we have been happily using for over one year after using Sphinx for many years prior to that. GitHub Pages offers built-in support for Jekyll, but not...
Onion Details
Page Clicks: 0
First Seen: 03/15/2024
Last Indexed: 10/23/2024
Onion Content
Preskoči na sadržaj Publishing (Material for) MkDocs website to GitHub Pages using custom Actions workflow As you can probably see, this website is built using the Material theme for MkDocs , which we have been happily using for over one year after using Sphinx for many years prior to that. GitHub Pages offers built-in support for Jekyll , but not for MkDocs and therefore it requires the manual building and deployment of our website. However, it automates many other things, including HTTPS certificate provisioning on our domain via Let's Encrypt . There are several somewhat related approaches using GitHub Actions for automating the deployment of MkDocs-generated sites, usually with the Material theme, to GitHub Pages. These guides are not only found on blogs written by enthusiasts; the official Getting started section of the Material for MkDocs documentation describes the usage of GitHub Actions for deployment and provides a generic YAML file for that purpose . Using the approaches mentioned above avoids the requirement to run the build and gh-deploy steps locally; GitHub Actions does both on GitHub's CI/CD servers, where the free plan offers 2000 minutes of GitHub-hosted runners per month . As many sites build in less than a minute, this amount allows from 50 to 100 builds and deployments per day , which is quite a bit more than most sites require. Additionally, the repository layout remains the same as it would be if the build and deployment steps were done locally; the main branch contains the site source in Markdown and the gh-pages branch contains the site files that get built for serving. Since this summer, GitHub offers publishing Pages using a custom Actions workflow as a public beta , which was a unique feature of GitLab Pages for years. I thought that it would be interesting to see if we could use the existing GitHub Actions workflow configuration for Jekyll and simply replace the Jekyll build step with the MkDocs build step. This would streamline the usage of MkDocs with GitHub Pages, and, in particular, eliminate the requirement for publishing the site from a separate gh-pages branch, offering a Jekyll-like experience. Let's see how far we can get. Without going into details about the syntax for GitHub Actions , here is the starter workflow configuration file for deploying a Jekyll site to GitHub Pages: # Sample workflow for building and deploying a Jekyll site to GitHub Pages name : Deploy Jekyll with GitHub Pages dependencies preinstalled 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 only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. concurrency : group : "pages" cancel-in-progress : false jobs : # Build job build : runs-on : ubuntu-latest steps : name : Checkout uses : actions/checkout@v4 - name : Setup Pages uses : actions/configure-pages@v5 - name : Build with Jekyll uses : actions/jekyll-build-pages@v1 with : source : ./ destination : ./_site - name : Upload artifact uses : actions/upload-pages-artifact@v3 # Deployment job deploy : environment : name : github-pages url : ${{ steps.deployment.outputs.page_url }} runs-on : ubuntu-latest needs : build steps : name : Deploy to GitHub Pages id : deployment uses : actions/deploy-pages@v4 The highlighted lines are Jekyll-specific. We can easily replace these lines with: the Python setup Action, the installation, using pip and the requirements.txt file, of MkDocs with extra internationalization support , the Material for MkDocs framework , the optional dependencies required for the generation of social cards , that is, CairoSVG , which will pull Pillow as a dependency, and, finally, the MkDocs site build command. In this case, since we want a drop-in replacement for Jekyll so that the remaining commands work perfectly, we will perform the MkDocs build using the mkdocs.yml configuration file in the current directory and write the built site output files into the _site directory. The .github/workflows/mkdocs-gh-pages.yml file will look like: # Sample workflow for building and deploying a MkDocs site to GitHub Pages name : Deploy MkDocs with GitHub Pages dependencies preinstalled on : # Runs on pushes targeting the default branch push : branches : [ "main" ] # 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 only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. concurrency : group : "pages" cancel-in-progress : false jobs : # Build job build : runs-on : ubuntu-latest steps : name : Checkout uses : actions/checkout@v4 - name : Setup Pages uses : actions/configure-pages@v5 - name : Setup Python uses : actions/setup-python@v5 with : python-version : '3.x' - name : Install yamllint run : pip install yamllint - name : Check MkDocs YAML configuration run : yamllint ./mkdocs.yml continue-on-error : true - name : Check Markdown files uses : DavidAnson/markdownlint-cli2-action@v16 with : globs : '**/*.md' continue-on-error : true - name : Install required packages run : pip install -r requirements.txt - name : Build site (_site directory name is used for Jekyll compatiblity) run : mkdocs build --config-file ./mkdocs.yml --strict --site-dir ./_site env : CI : true - name : Upload artifact uses : actions/upload-pages-artifact@v3 # Deployment job deploy : environment : name : github-pages url : ${{ steps.deployment.outputs.page_url }} runs-on : ubuntu-latest needs : build steps : name : Deploy to GitHub Pages id : deployment uses : actions/deploy-pages@v4 Two linters are used: for mkdocs.yml , yamllint configuration is in the .yamllint.yaml file. It should reside in the root of the repository and contain the following: extends : default rules : document-end : present : false document-start : present : false line-length : level : warning allow-non-breakable-inline-mappings : true for Markdown files, markdownlint configuration is in the .markdownlint.json file. It should also reside in the root of the repository and contain the following: { "default" : true , "MD007" : { "indent" : 4 } Finally, we can see the mention of the requirements.txt file. You guessed it, it should reside in the root of the repository as well. It should contain the following text: mkdocs-material[recommended,imaging] And that's it! There is no more requirement for the .nojekyll file as Jekyll never gets ran in the build process. There is also no more separate gh-pages branch that the built files get pushed to, so there is also no more worry whether the site builds over time will add up to the 1 GB soft limit . Finally, if you want to use a custom domain, having the CNAME file in the repository root or the docs subfolder will no longer have the desired effect; the domain has to be configured through the repository settings or using the API . Updated on 2022-11-25: changed Python version from 3.10 to 3.11, resulting in faster docs builds (see Faster CPython for details). Updated on 2022-12-03: changed caching to use github.sha instead of github.ref , enabling rebuilds of social cards when site contents change. Updated on 2023-06-06: rebased our additions on top of the latest version of jekyll-gh-pages.yml from Starter Workflows . Changed Python version from 3.11 to the latest stable 3.x , which is 3.11 at the moment. However, using the current beta version of Python 3.12 already works well with mkdocs-material , so it's unlikely to cause issues even when 3.12 gets released and becomes the latest stable version. Updated on 2023-09-08: simplified the workflow to use the existing requirements.txt file instead of duplicating the package names in the pip command run. Updated on 2023-10-24: updated requirements.txt to use the extras for the installation of the optional dependencies . Updated on 2023-12-28: bumped Actions versions by rebasing our additions on top of the latest version of jekyll-gh-pages.yml from Starter Workflows . Updated on 2024-05-12: added yamllint and markdownlint steps. Removed caching as (Material for) MkDocs version is not pinned and therefore the site builds are not reproducible.