|
| 1 | +# improved-octo-fortnight |
| 2 | + |
| 3 | +A reference implementation of a documentation workflow using [zensical](https://zensical.org/) and GitHub Pages. |
| 4 | + |
| 5 | +- [latest](https://taisakuma.github.io/improved-octo-fortnight/latest/) |
| 6 | +- [dev](https://taisakuma.github.io/improved-octo-fortnight/dev/) |
| 7 | + |
| 8 | +## Features |
| 9 | + |
| 10 | +- **Versioned docs** -- Release docs at `/<version>/`, dev docs at `/dev/`, and a `/latest/` alias |
| 11 | +- **PR previews** -- Every PR gets a preview deployment at `/pr/<number>/` with an automatic comment linking to it |
| 12 | +- **PR cleanup** -- Preview deployments are removed when PRs are closed |
| 13 | +- **Version index** -- An auto-generated root `index.html` lists all available versions |
| 14 | +- **Deploy verification** -- The preview URL is polled before posting the PR comment; a note is added if the site isn't ready yet |
| 15 | +- **Custom domain support** -- Works with both default GitHub Pages URLs and custom domains |
| 16 | +- **API reference** -- Auto-generated from Python docstrings using [mkdocstrings](https://mkdocstrings.github.io/). Add `:::` directives in Markdown to render any module (see `docs/api.md` for an example) |
| 17 | + |
| 18 | +## How it works |
| 19 | + |
| 20 | +Documentation is built with [zensical](https://zensical.org/) and deployed by pushing subdirectories to a `gh-pages` branch. Four workflows handle the different deployment scenarios: |
| 21 | + |
| 22 | +| Workflow | Trigger | Deploys to | |
| 23 | +| --------------------- | -------------------------------- | ----------------------------------------- | |
| 24 | +| `docs.yml` | Push to `main` | `/dev/` | |
| 25 | +| `docs-release.yml` | Release (via changelog workflow) | `/<version>/` + `/latest/` + `index.html` | |
| 26 | +| `docs-pr-preview.yml` | PR opened/updated | `/pr/<number>/` | |
| 27 | +| `docs-pr-cleanup.yml` | PR closed | removes `/pr/<number>/` | |
| 28 | + |
| 29 | +The `gh-pages` branch has the following structure: |
| 30 | + |
| 31 | +``` |
| 32 | +gh-pages |
| 33 | +├── .nojekyll |
| 34 | +├── index.html # auto-generated version index |
| 35 | +├── latest/ # copy of the latest release |
| 36 | +├── dev/ # built from main |
| 37 | +├── 0.2.1/ # release versions |
| 38 | +├── 0.2.0/ |
| 39 | +└── pr/ |
| 40 | + ├── 14/ # PR preview |
| 41 | + └── 13/ |
| 42 | +``` |
| 43 | + |
| 44 | +Shared logic is extracted into two composite actions: |
| 45 | + |
| 46 | +- **`.github/actions/build-docs`** -- Overrides `site_url` for the target subdirectory, builds the site, and stages the output |
| 47 | +- **`.github/actions/deploy-to-gh-pages`** -- Checks out (or creates) the `gh-pages` branch and pushes the built site to a target subdirectory |
| 48 | + |
| 49 | +A Python script (`.github/scripts/override_site_url.py`) uses [tomlkit](https://github.com/sdispater/tomlkit) to modify `site_url` in `zensical.toml` so that navigation and search work correctly in each subdirectory. |
| 50 | + |
| 51 | +## Setup |
| 52 | + |
| 53 | +1. Install [uv](https://docs.astral.sh/uv/) |
| 54 | +2. Build docs locally: |
| 55 | + ``` |
| 56 | + uv run --group docs zensical serve |
| 57 | + ``` |
| 58 | +3. Set GitHub Pages source to **Deploy from a branch** > `gh-pages` (root `/`) |
0 commit comments