Skip to content

Commit 4ba3ab2

Browse files
authored
feat(docs): versioned Sphinx docs with sphinx-multiversion (#89)
feat(docs): add script-driven versioned Sphinx docs Final state: - Introduces a script-driven versioned docs build flow replacing the prior sphinx-multiversion approach for this repo. - Adds docs/scripts/build_versioned_docs.sh, docs/scripts/build_versioned_docs.py, and docs/scripts/select_versions.py. - Implements deterministic version selection: - latest patch for last 5 minor series in current major - latest release for last 3 majors - descending order - Publishes main as current and generates docs/build/html/versions.json for selector/metadata rendering. - Ensures version links target <version>/index.html and root redirects to current/index.html. - Aligns local and CI entrypoints: - docs/Makefile html-multiversion targets - .github/workflows/main-docs.yml uses docs/scripts/build_versioned_docs.sh - Keeps RTD bottom selector and breadcrumb version/release-date metadata as the final UI state. - Adds docs/README.md guidance and ADR 0007 documenting docs build/UI decisions.
1 parent 07c9a0b commit 4ba3ab2

14 files changed

Lines changed: 796 additions & 31 deletions

.github/workflows/main-docs.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ name: Deploy Lakeflow Framework Documentation to GitHub Pages
33
on:
44
push:
55
branches: ["main"]
6+
tags: ["v*.*.*"]
67

78
permissions:
89
contents: read
@@ -20,8 +21,11 @@ jobs:
2021
group: databricks-solutions-protected-runner-group
2122
labels: linux-ubuntu-latest
2223
steps:
23-
- name: Checkout
24+
- name: Checkout (full history + tags)
2425
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
26+
with:
27+
fetch-depth: 0
28+
fetch-tags: true
2529

2630
- name: Set up Python
2731
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
@@ -38,10 +42,9 @@ jobs:
3842
python -m pip install --upgrade pip
3943
pip install --require-hashes --no-deps -r requirements-docs.lock
4044
41-
- name: Build HTML
45+
- name: Build versioned HTML
4246
run: |
43-
cd docs
44-
make html
47+
bash docs/scripts/build_versioned_docs.sh
4548
4649
- name: Setup Pages
4750
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dist/
44
__pycache__/
55
*.egg-info
66
.venv/
7+
.venv*/**
78
scratch/**
89
!scratch/README.md
910
.DS_Store

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.16.1
1+
v0.17.0

docs/Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# from the environment for the first two.
66
SPHINXOPTS ?= -c .
77
SPHINXBUILD ?= sphinx-build
8+
PYTHON ?= python3
89
SOURCEDIR = source
910
BUILDDIR = build
1011
IMAGEDIR = source/images
@@ -13,7 +14,7 @@ IMAGEDIR = source/images
1314
help:
1415
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
1516

16-
.PHONY: help Makefile markdown spelling
17+
.PHONY: help Makefile markdown spelling html-multiversion html-multiversion-preview
1718

1819
# Add custom markdown build command
1920
md:
@@ -30,6 +31,14 @@ md:
3031
spelling:
3132
@$(SPHINXBUILD) -M spelling "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
3233

34+
# Build versioned docs without sphinx-multiversion.
35+
html-multiversion:
36+
@./scripts/build_versioned_docs.sh
37+
38+
# Local preview build including all local branches.
39+
html-multiversion-preview:
40+
@./scripts/build_versioned_docs.sh --preview
41+
3342
# Catch-all target: route all unknown targets to Sphinx using the new
3443
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
3544
%: Makefile

docs/README.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# Docs Build and Versioning
2+
3+
This folder contains the Sphinx documentation source and build tooling for local development and GitHub Pages publishing.
4+
5+
## Contents
6+
7+
- [Prerequisites](#prerequisites)
8+
- [Make Targets](#make-targets)
9+
- [Multiversion Implementation (No sphinx-multiversion)](#multiversion-implementation-no-sphinx-multiversion)
10+
- [What Gets Built](#what-gets-built)
11+
- [Version Selection Rules](#version-selection-rules)
12+
- [How the Sidebar Switcher Works](#how-the-sidebar-switcher-works)
13+
- [Purge and Rebuild Behavior](#purge-and-rebuild-behavior)
14+
- [Local Build and Testing](#local-build-and-testing)
15+
- [GitHub Pages Deployment](#github-pages-deployment)
16+
- [Notes and Troubleshooting](#notes-and-troubleshooting)
17+
18+
## Prerequisites
19+
20+
- Python environment with docs dependencies installed:
21+
- `pip install --require-hashes --no-deps -r requirements-docs.lock`
22+
- or (less strict) `pip install -r requirements-docs.txt`
23+
- Install the Enchant C library (required by `sphinxcontrib-spelling`):
24+
- macOS (Homebrew): `brew install enchant`
25+
- Windows (Chocolatey): `choco install enchant`
26+
- Run commands from the repo root with `make -C docs ...`, or from this folder with `make ...`.
27+
28+
## Make Targets
29+
30+
The `docs/Makefile` supports these explicit targets:
31+
32+
- `make help`
33+
- Shows Sphinx make-mode help and all supported builder targets.
34+
- `make html`
35+
- Standard single-version HTML build into `docs/build/html`.
36+
- `make spelling`
37+
- Runs the spelling builder (`sphinxcontrib-spelling`).
38+
- `make md`
39+
- Builds Markdown output to `docs/build/markdown` and copies images/static assets.
40+
- `make html-multiversion`
41+
- Builds versioned docs without `sphinx-multiversion` using `scripts/build_versioned_docs.sh`.
42+
- `make html-multiversion-preview`
43+
- Same as above, plus local branches for preview/testing.
44+
45+
Catch-all behavior is enabled:
46+
47+
- Any unknown target is forwarded to `sphinx-build -M`.
48+
- Example: `make clean`, `make linkcheck`, `make dirhtml`.
49+
50+
## Multiversion Implementation (No sphinx-multiversion)
51+
52+
Versioned docs are generated by:
53+
54+
- `docs/scripts/build_versioned_docs.sh` (entrypoint)
55+
- `docs/scripts/build_versioned_docs.py` (orchestrator)
56+
- `docs/scripts/select_versions.py` (version selection rules)
57+
58+
### What Gets Built
59+
60+
- `main` branch is always built and published as `current`.
61+
- Selected release tags are built from git tags.
62+
- Output layout:
63+
- `docs/build/html/current/index.html`
64+
- `docs/build/html/vX.Y.Z/index.html`
65+
- `docs/build/html/versions.json`
66+
- `docs/build/html/index.html` (redirects to `current/index.html`)
67+
68+
### Version Selection Rules
69+
70+
`scripts/select_versions.py` applies these rules:
71+
72+
1. Identify the highest major version present in tags.
73+
2. Include the latest patch release for the last 5 minor series in that major.
74+
3. Include the latest available release for each of the last 3 majors.
75+
4. De-duplicate and sort descending (newest first).
76+
77+
Example ordering:
78+
79+
- `current`
80+
- `v0.16.0`
81+
- `v0.15.5`
82+
- `v0.14.0`
83+
- `v0.13.0`
84+
- `v0.12.1`
85+
86+
### How the Sidebar Switcher Works
87+
88+
- `scripts/build_versioned_docs.py` writes `versions.json` with `name`, `url`, and `is_latest`.
89+
- `docs/conf.py` loads this manifest via `DOCS_VERSIONS_FILE`.
90+
- `docs/_templates/versions.html` renders the version list in the RTD sidebar.
91+
- Links target `.../index.html` explicitly to avoid directory-listing behavior in local `file://` browsing.
92+
93+
## Purge and Rebuild Behavior
94+
95+
Each versioned build is clean:
96+
97+
- `docs/build/html` is removed before rebuilding.
98+
- Temporary git worktrees under `docs/build/.worktrees` are removed after build.
99+
- `git worktree prune` runs at the end.
100+
101+
This ensures old/stale version folders are purged from the publish artifact.
102+
103+
## Local Build and Testing
104+
105+
Use this command order during docs development:
106+
107+
1. Quick content/format validation while iterating:
108+
109+
```bash
110+
make -C docs html
111+
```
112+
113+
1. Always run spelling before finalizing:
114+
115+
```bash
116+
make -C docs spelling
117+
```
118+
119+
1. If your change could affect versioned output or version switcher behavior:
120+
121+
```bash
122+
make -C docs html-multiversion
123+
```
124+
125+
1. If you need to test branch previews in the version menu:
126+
127+
```bash
128+
make -C docs html-multiversion-preview
129+
```
130+
131+
Practical rule of thumb:
132+
133+
- Doc text/layout change only: `html` + `spelling`
134+
- Versioning/switcher/build-script change: `html` + `spelling` + `html-multiversion`
135+
- Branch preview verification: add `html-multiversion-preview`
136+
137+
### Open docs
138+
139+
- Direct file open:
140+
- `docs/build/html/index.html`
141+
- Recommended local server (more browser-consistent):
142+
143+
```bash
144+
cd docs/build/html
145+
python3 -m http.server 8000
146+
```
147+
148+
Then open [http://localhost:8000](http://localhost:8000).
149+
150+
## GitHub Pages Deployment
151+
152+
The workflow is in `.github/workflows/main-docs.yml`.
153+
154+
On push to `main` or release tags:
155+
156+
1. Checkout full history and tags.
157+
2. Install docs dependencies.
158+
3. Run `bash docs/scripts/build_versioned_docs.sh`.
159+
4. Upload `docs/build/html` as Pages artifact.
160+
5. Deploy with GitHub Pages actions.
161+
162+
The deployed root redirects to `current/index.html`.
163+
164+
## Notes and Troubleshooting
165+
166+
- If version links look wrong, inspect `docs/build/html/versions.json`.
167+
- If tags seem missing, verify local git tags are fetched:
168+
- `git fetch --tags`
169+
- If local browser shows folder listing, use the explicit `index.html` URLs or run a local HTTP server.
170+

docs/_templates/breadcrumbs.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{% extends "!breadcrumbs.html" %}
2+
3+
{% block breadcrumbs_aside %}
4+
<li class="wy-breadcrumbs-aside docs-breadcrumb-version-meta">
5+
<span>
6+
<strong>Version:</strong> {{ docs_current_version_meta.display_version }}
7+
{%- if docs_current_version_meta.status == "current" %}
8+
<span class="docs-current-badge">current</span>
9+
{%- endif %}
10+
{%- if docs_current_version_meta.release_date_human %}
11+
<strong>Release Date:</strong> {{ docs_current_version_meta.release_date_human }}
12+
{%- endif %}
13+
</span>
14+
</li>
15+
{% endblock %}

docs/_templates/layout.html

Lines changed: 0 additions & 10 deletions
This file was deleted.

docs/_templates/versions.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{%- if docs_versions %}
2+
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
3+
<span class="rst-current-version" data-toggle="rst-current-version">
4+
<span class="fa fa-book">&nbsp&nbspVersion </span>
5+
{{ docs_current_version_meta.display_version }}{% if docs_current_version_meta.status == "current" %} (current){% endif %}
6+
<span class="fa fa-caret-down"></span>
7+
</span>
8+
<div class="rst-other-versions">
9+
<dl>
10+
{%- for item in docs_versions %}
11+
<dd>
12+
<a href="{{ item.url }}">
13+
{{ item.display_version }}{% if item.status == "current" %} (current){% endif %}
14+
</a>
15+
</dd>
16+
{%- endfor %}
17+
</dl>
18+
</div>
19+
</div>
20+
{%- endif %}

0 commit comments

Comments
 (0)