Multi-version docs: local preview#
Note
This page documents the preview workflow on the
feat/versioned-docs-preview branch. The full release plan is in
MADDENING/docs/developer_guide/versioned_docs.md.
The version switcher is off by default — CI keeps deploying the
single-version site. To preview the multi-version layout locally,
opt in with DOCS_MULTIVERSION=1 (the Makefile targets below do this
for you).
Quick start#
cd MICROROBOTICA/docs
# One-shot build of every version + serve locally
make preview-versions # builds, then runs http.server on :8000
# Open http://localhost:8000/maddening/ in a browser.
# The version switcher is in the top navbar.
sphinx-build must be reachable. The Makefile auto-detects the
sibling shared venv (../../.venv); otherwise activate your docs
venv first (source ../../.venv/bin/activate) or pass an explicit
make … SPHINXBUILD=/path/to/sphinx-build.
The output structure mirrors the production target:
_build/html/
├── index.html ← MICROROBOTICA latest
├── _static/switcher.json ← MICROROBOTICA version list
├── sitemap.xml ← MICROROBOTICA sitemap
├── maddening/
│ ├── index.html ← MADDENING latest (= main tip)
│ ├── _static/switcher.json ← canonical MADDENING version list
│ ├── sitemap.xml ← MADDENING sitemap (latest only)
│ ├── v0.1/index.html ← MADDENING v0.1.0 tag
│ └── v0.2/index.html ← MADDENING v0.2.0 tag
└── mime/
├── index.html ← MIME latest
└── _static/switcher.json ← MIME version list (one entry)
Every version’s HTML references /maddening/_static/switcher.json via
a root-relative URL, so v0.1 pages pick up the switcher dropdown even
though v0.1’s source tree predates the switcher.
Iterating on docs without committing#
The default make all-versions builds every version from its remote
git ref. When you’re editing a docs file on the latest line and want
to see the change without committing, point the “latest” tier at your
local working copy:
make preview-local MADDENING_LOCAL=/home/you/MSF/msf/MADDENING
# Edit MADDENING/docs/... files, then re-run — <30 s incremental.
Older versions (v0.1, v0.2) still come from git tags — they’re frozen
and don’t need re-builds unless you nuke _build/.
What’s running#
Knob |
Default |
Multi-version build |
|---|---|---|
|
unset |
|
|
unset |
the build label ( |
|
|
|
|
from caller |
|
|
unset → submodule path |
tempdir worktree |
navbar shows version switcher |
no |
yes (rendered, fetches JSON at page-load) |
The switcher JSON contract: a flat list of
{version, name, url, preferred} rows. version is the value that
DOCS_VERSION must match for the theme to highlight the row as
“current”. preferred: true marks the stable release (the one new
visitors should land on if they have no preference).
Canonical URLs and the sitemap#
Multi-version docs publish the same page at several URLs
(/maddening/quickstart.html, /maddening/v0.2/quickstart.html,
/maddening/v0.1/quickstart.html). To stop search engines treating
those as duplicate content, the latest version is declared
canonical:
conf.pysetshtml_baseurlwithout a version segment (.../maddening/, never.../maddening/v0.2/). Sphinx derives every page’s<link rel="canonical">from it, so a versioned page emits<link rel="canonical" href=".../maddening/<page>">— it canonicalises to the latest copy of that page.The sitemap is generated by the latest build only.
conf.pydrops thesphinx_sitemapextension whenDOCS_VERSION != latest, so/maddening/v0.1/and/maddening/v0.2/ship nositemap.xml. Only/maddening/sitemap.xml(latest) exists, and that is the oneseo/sitemap_index.xmlreferences.seo/robots.txtkeepsAllow: /— crawlers must be able to reach the versioned pages so they can see the canonical link and consolidate. Don’tDisallowthe version subdirs.
Net effect: search engines index one copy of each page (the latest), and the version switcher is the only way readers reach older docs.
Adding a version#
MADDENING/docs/_static/switcher.json is the source of truth for the
MADDENING dropdown; MICROROBOTICA/docs/_static/switcher.json and
MIME/docs/_static/switcher.json are the (currently single-entry)
lists for the other two. When a project cuts a release:
Tag the release in that project’s repo (e.g.
v0.3.0).Add a row to that project’s
switcher.json—versionis the label, and movepreferred: trueto the new stable release.Update the project’s
*_VERSIONSline indocs/Makefile, e.g.MADDENING_VERSIONS := v0.1:v0.1.0 v0.2:v0.2.0 v0.3:v0.3.0 latest:origin/main.Rebuild.
The latest row builds from origin/main; the canonical
switcher.json it ships is whatever is on main, so commit the
switcher.json edit to main.
Cleaning up#
make clean # rm -rf _build/
make clean-worktrees # remove /tmp/msf-docs-worktree-*
clean-worktrees is safe to run anytime — it removes the git
worktrees the multi-version build creates under /tmp/. Subsequent
builds re-create them on demand.
Knobs that won’t affect production#
Everything in this preview is gated on env vars that default to “production single-version”:
make all(no-versionssuffix) — unchanged from v0.1 behaviour.CI workflow (
.github/workflows/docs.yml) — untouched.The
docs/conf.pyswitcher block is wrapped inif _multiversion:so it’s a no-op withoutDOCS_MULTIVERSION=1.
To actually ship multi-version, the steps are in
MADDENING’s versioned_docs.md
§ “Rollout sequence” — three small CI changes once you’re ready.
Troubleshooting#
“sphinx-build not found” — activate the docs venv
(source ../../.venv/bin/activate) or pass
SPHINXBUILD=/path/to/sphinx-build.
“projects/maddening submodule missing” — run
git submodule update --init --recursive.
“worktree add failed for … @ origin/…” — the submodule’s local
clone hasn’t fetched that branch yet. Run
git -C docs/projects/maddening fetch origin --tags and retry.
“worktree at /tmp/… has no docs/index.md (ref too old?)” —
the ref you’re trying to build predates the current docs layout.
Drop that row from MADDENING_VERSIONS in the Makefile.
Switcher shows nothing in the dropdown — open the browser
DevTools network tab and check that /maddening/_static/switcher.json
returns 200. It’s served from _build/html/maddening/_static/; the
“latest” build is what writes it.
Switcher shows but the current version isn’t highlighted —
the version field in switcher.json has to match DOCS_VERSION
exactly. The Makefile sets DOCS_VERSION to the LABEL part of
the <label>:<ref> pair (e.g. v0.1, v0.2, latest).