Skip to content

Documentation

Builds an mkdocs site and publishes it to GitHub Pages.

This workflow is part of the nolte/cookiecutter-gh-project template.


Usage

.github/workflows/release-cd-deliver-docs.yml
on:
  push:
    branches:
      - develop

jobs:
  deliver_docs:
    uses: nolte/gh-plumbing/.github/workflows/reusable-mkdocs.yaml@<tag>
    secrets:
      token: ${{ secrets.GITHUB_TOKEN }}

GitHub Pages

The target repository must declare has_pages: true. The shared Probot settings already include this—see Settings.


Central configuration

.github/workflows/reusable-mkdocs.yaml
name: Reusable — MkDocs Deploy

on:
  workflow_call:
    inputs:
      requirements:
        description: 'path of the requirements dependencies file'
        required: false
        default: "./requirements-dev.txt"
        type: string
      pre-build-command:
        description: |
          Optional shell command run on the runner after checkout and
          before the gh-pages build/deploy. Use it to generate derived
          pages (for example a skill/agent catalog) that are gitignored
          and therefore absent from a fresh checkout. The requirements
          file is installed on the runner first, so a Python generator
          can import its deps directly; the generated files live in the
          workspace and are picked up by the deploy step. Empty
          (default) skips the step.
        required: false
        type: string
        default: ""
      python-version:
        description: |
          Python version for the pre-build command step. Only used when
          pre-build-command is set.
        required: false
        type: string
        # Concrete rather than "3.x": a floating interpreter means the same
        # commit can resolve differently over time, and .tool-versions already
        # pins 3.14 for local work. Consumers override via this input.
        default: "3.14"
      app-id:
        description: |
          Numeric GitHub App ID of the portfolio App. When set, the
          reusable mints a short-lived installation token from
          `secrets.app-private-key` and uses it for the gh-pages push.
          When empty (the default), the reusable falls through to
          `secrets.token` — typically the consumer's `GITHUB_TOKEN`.
          gh-pages is not branch-protected, so the App token here is a
          consistency / audit-trail improvement, not a permissions
          requirement (issue #357, spec/project/workflow-health/
          §Known platform constraints).
        required: false
        type: string
        default: ""
    secrets:
      token:
        required: true
      app-private-key:
        description: |
          PEM-encoded private key for the App identified by `inputs.app-id`.
          Required when `app-id` is set; ignored otherwise.
        required: false
# Explicit permissions per spec/project/github-actions-best-practices §B:
# workflow level is the minimum, write scopes are granted per job.
permissions:
  contents: read


# The deploy pushes to gh-pages, so concurrent runs race on one branch
# regardless of which ref triggered them -- hence a static group rather than a
# ref-derived one.
#
# cancel-in-progress stays false per spec/project/github-actions-best-practices
# §F: cancelling a half-finished gh-pages push is worse than queueing behind it.
concurrency:
  group: mkdocs-deploy
  cancel-in-progress: false


jobs:
  publish_docs:
    permissions:
      contents: write # the mkdocs deploy pushes the built site to gh-pages
    name: "Publish the HTML Documentation"
    runs-on: ubuntu-latest
    steps:
      # Mint an App installation token only when the caller has set
      # inputs.app-id. The output token replaces secrets.token in the
      # mhausenblas/mkdocs-deploy-gh-pages step via the
      # steps.app-token.outputs.token || secrets.token fallback.
      - name: Mint App installation token
        id: app-token
        if: ${{ inputs.app-id != '' }}
        # Tolerate a half-configured setup. On any failure outputs.token
        # is empty and the fallback to secrets.token kicks in — the
        # gh-pages push keeps working, only the audit-trail consistency
        # with the rest of the release toolchain is lost.
        continue-on-error: true
        uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2
        with:
          app-id: ${{ inputs.app-id }}
          private-key: ${{ secrets.app-private-key }}

      - name: Checkout master
        uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

      # Optional pre-build hook. Runs on the runner host before the
      # Dockerised deploy action; files it writes into the workspace
      # (e.g. a generated catalog under docs/) are mounted into and
      # picked up by mkdocs gh-deploy.
      - name: Set up Python for pre-build
        if: ${{ inputs.pre-build-command != '' }}
        uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
        with:
          python-version: ${{ inputs.python-version }}

      - name: Pre-build command
        if: ${{ inputs.pre-build-command != '' }}
        run: |
          pip install -r ${{ inputs.requirements }}
          ${{ inputs.pre-build-command }}

      - name: Deploy docs
        uses: mhausenblas/mkdocs-deploy-gh-pages@d77dd03172e96abbcdb081d8c948224762033653 # 1.26
        env:
          GITHUB_TOKEN: ${{ steps.app-token.outputs.token || secrets.token }}
          REQUIREMENTS: ${{ inputs.requirements }}