Skip to content

Publish PR previews and versioned documentation with GitHub Pages #517

Description

@munechika-koyo

Summary

I propose publishing the Sphinx documentation with GitHub Actions + GitHub Pages, with three kinds of hosted documentation:

  1. Pull request previews for reviewing documentation changes before merge.
  2. Versioned release documentation that is kept permanently for each release.
  3. A continuously updated latest build from the development branch.

This follows up on #405, where versioned documentation in GitHub Pages subdirectories was suggested and rossjrw/pr-preview-action was identified as a potentially useful tool.

The proposal assumes the Pixi setup introduced in #489, or an equivalent configuration, is merged.

In #489, the documentation is built with:

pixi run -e docs doc-build

and the generated HTML is written to:

docs/build/html

Using the same Pixi task in all workflows would keep local and CI documentation builds consistent.

Proposed GitHub Pages layout

Use a single gh-pages deployment branch, with separate directories for each type of documentation:

gh-pages/
├── latest/                  # current development branch
├── versions/
│   ├── v1.5.0/
│   ├── v1.6.0/
│   └── ...
└── pr-preview/
    ├── pr-123/
    ├── pr-456/
    └── ...

This keeps temporary PR previews separate from permanent release documentation and from the continuously updated development documentation.

1. Pull request documentation previews

For pull requests, build the documentation using Pixi and deploy the generated HTML with rossjrw/pr-preview-action.

A workflow could look approximately like this:

on:
  pull_request:
    types:
      - opened
      - reopened
      - synchronize
      - closed

permissions:
  contents: write
  pull-requests: write

steps:
  - uses: actions/checkout@v4

  - uses: prefix-dev/setup-pixi@v0
    if: github.event.action != 'closed'

  - name: Build documentation
    if: github.event.action != 'closed'
    run: pixi run -e docs doc-build

  - name: Deploy documentation preview
    uses: rossjrw/pr-preview-action@v1
    with:
      source-dir: docs/build/html
      preview-branch: gh-pages

This would produce URLs such as:

https://<pages-url>/pr-preview/pr-489/

The action can:

  • update the preview when new commits are pushed,
  • add/update a link in the PR,
  • remove the preview when the PR is closed.

This would provide a convenient way to visually review documentation changes without requiring reviewers to build the documentation locally.

This also follows the discussion in #405, where PR documentation previews and pr-preview-action were already mentioned.

Fork PR limitation

At present, pr-preview-action@v1 does not support previews for pull requests originating from forks.

We should avoid working around this by checking out untrusted fork code using pull_request_target with write permissions or repository secrets.

For fork PRs, the Sphinx build could still run as normal CI, while hosted previews remain unavailable until a safe mechanism for fork previews is available.

2. Versioned documentation on release

When a GitHub Release is published, the workflow should:

  1. check out the release tag,
  2. build the documentation with Pixi,
  3. deploy it permanently under versions/<tag>/.

Cherab already uses release tags such as v1.5.0, so the resulting URL would be:

https://<pages-url>/versions/v1.5.0/

The workflow could be triggered with:

on:
  release:
    types: [published]

and the core steps could look like:

- uses: actions/checkout@v4
  with:
    ref: ${{ github.event.release.tag_name }}

- uses: prefix-dev/setup-pixi@v0

- name: Build documentation
  run: pixi run -e docs doc-build

- name: Deploy versioned documentation
  uses: JamesIves/github-pages-deploy-action@v4
  with:
    branch: gh-pages
    folder: docs/build/html
    target-folder: versions/${{ github.event.release.tag_name }}
    force: false

Release documentation should be treated as permanent once published, so that users of older Cherab versions can access documentation matching the installed version.

This is related to the concern raised in #405: currently, online documentation generally corresponds only to the latest published version, which can make it difficult for users of older releases to find matching documentation.

3. development branch as latest

Whenever new commits are pushed to development, build the documentation using the same Pixi task and publish it under:

latest/

For example:

on:
  push:
    branches:
      - development

with deployment similar to:

- uses: actions/checkout@v4

- uses: prefix-dev/setup-pixi@v0

- name: Build documentation
  run: pixi run -e docs doc-build

- name: Deploy latest documentation
  uses: JamesIves/github-pages-deploy-action@v4
  with:
    branch: gh-pages
    folder: docs/build/html
    target-folder: latest
    force: false

This would provide:

https://<pages-url>/latest/

as documentation corresponding to the current development branch.

Initially, it may be simplest to rebuild documentation on every push to development.

Although a paths: filter could reduce unnecessary builds, changes outside docs/ can affect autodoc output and API documentation, so filtering only documentation files may miss relevant changes.

Deployment considerations

Because all three workflows modify the same gh-pages branch, they must avoid deleting or overwriting files owned by the other workflows.

The ownership would be:

pr-preview/       -> PR preview workflow
versions/         -> release workflow
latest/           -> development workflow

In particular:

  • pr-preview-action should only manage pr-preview/.
  • release deployment should only write to versions/<tag>/.
  • development deployment should only replace latest/.
  • deployment workflows should avoid force-pushing the entire gh-pages branch.
  • concurrent deployments should use appropriate concurrency/retry handling to avoid push conflicts.

GitHub Pages should be configured to deploy from the gh-pages branch, which is also the deployment model expected by pr-preview-action.

Possible follow-up

Once versioned hosting is available, we could add a version selector to the Sphinx theme, for example:

Version: [ latest ▼ ]

latest
v1.6.0
v1.5.0
...

A root landing page or a stable alias pointing to the latest released version could also be added later.

These are not required for the initial implementation.

Proposed result

The final structure would be roughly:

GitHub Pages
│
├── latest/
│     current development documentation
│
├── versions/
│   ├── v1.5.0/
│   ├── v1.6.0/
│   └── ...
│
└── pr-preview/
    ├── pr-123/
    ├── pr-456/
    └── ...

All documentation builds would use the same command:

pixi run -e docs doc-build

with only the deployment destination changing depending on the GitHub event.

Implementation checklist

  • Merge/adopt the Pixi documentation environment and doc-build task from ✨ Introduce pixi for project management #489.
  • Configure GitHub Pages to deploy from gh-pages.
  • Add PR documentation preview workflow using rossjrw/pr-preview-action.
  • Add release workflow publishing to versions/<release-tag>/.
  • Add development workflow publishing to latest/.
  • Ensure deployments preserve content produced by the other workflows.
  • Verify closing a PR removes only the corresponding PR preview.
  • Verify old release documentation remains accessible after later releases and development deployments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions