Skip to content

Commit 3857fd9

Browse files
committed
docs: integrate sphinx-multiversion for versioned documentation
Add sphinx-multiversion so each release gets its own docs version with a sidebar dropdown switcher. Tags v0.4.0+ are whitelisted (older tags lack docs/). The main branch builds as development docs. - Add sphinx-multiversion extension and smv_* configuration - Create version switcher sidebar template and CSS - Update CI workflow to build all versions on release publish - Generate root redirect to latest tagged version - Add docs-multi Makefile target for local multi-version builds
1 parent f1adcf2 commit 3857fd9

6 files changed

Lines changed: 119 additions & 3 deletions

File tree

.github/workflows/docs.yml

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ name: Deploy Documentation
33
on:
44
push:
55
branches: [main]
6+
release:
7+
types: [published]
68
workflow_dispatch:
79

810
permissions:
@@ -20,6 +22,11 @@ jobs:
2022
steps:
2123
- name: Checkout
2224
uses: actions/checkout@v4
25+
with:
26+
fetch-depth: 0
27+
28+
- name: Fetch all tags
29+
run: git fetch --tags
2330

2431
- name: Set up Python
2532
uses: actions/setup-python@v5
@@ -42,8 +49,33 @@ jobs:
4249
- name: Copy example notebooks
4350
run: python docs/copy_notebooks.py
4451

45-
- name: Build documentation
46-
run: sphinx-build -b html docs docs/_build/html
52+
- name: Build versioned documentation
53+
run: sphinx-multiversion docs docs/_build/html
54+
55+
- name: Create root redirect
56+
run: |
57+
# Find the latest tag that matches our whitelist, fall back to main
58+
LATEST_TAG=$(git tag --sort=-v:refname | grep -E '^v0\.([4-9]|[0-9]{2,})\.[0-9]+$|^v[1-9][0-9]*\.[0-9]+\.[0-9]+$' | head -1)
59+
TARGET="${LATEST_TAG:-main}"
60+
cat > docs/_build/html/index.html << 'REDIRECT_EOF'
61+
<!DOCTYPE html>
62+
<html>
63+
<head>
64+
<meta charset="utf-8">
65+
<title>Redirecting...</title>
66+
<script>
67+
// Redirect to latest tagged version, or main if none exist
68+
var defined_target = "DEFINED_TARGET_PLACEHOLDER";
69+
window.location.href = defined_target + "/index.html";
70+
</script>
71+
<meta http-equiv="refresh" content="0; url=DEFINED_TARGET_PLACEHOLDER/index.html">
72+
</head>
73+
<body>
74+
<p>Redirecting to <a href="DEFINED_TARGET_PLACEHOLDER/index.html">latest documentation</a>...</p>
75+
</body>
76+
</html>
77+
REDIRECT_EOF
78+
sed -i "s|DEFINED_TARGET_PLACEHOLDER|${TARGET}|g" docs/_build/html/index.html
4779
4880
- name: Upload artifact
4981
uses: actions/upload-pages-artifact@v3

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: install format lint test test-all test-sentinel clean redis-start redis-stop check-types check docs docs-clean docs-serve
1+
.PHONY: install format lint test test-all test-sentinel clean redis-start redis-stop check-types check docs docs-clean docs-serve docs-multi
22

33
install:
44
poetry install --all-extras
@@ -49,6 +49,10 @@ docs-clean:
4949
rm -rf docs/_build
5050
rm -rf docs/examples/checkpoints docs/examples/human_in_the_loop docs/examples/memory docs/examples/middleware docs/examples/react_agent
5151

52+
docs-multi:
53+
python docs/copy_notebooks.py
54+
sphinx-multiversion docs docs/_build/html
55+
5256
docs-serve: docs
5357
python -m http.server 8085 --directory docs/_build/html
5458

docs/_static/css/custom.css

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,39 @@ html[data-theme="dark"] .table tbody tr:hover {
187187
text-decoration: none !important;
188188
color: #DC382D !important;
189189
}
190+
191+
/* -- Version switcher ------------------------------------------------------ */
192+
.version-switcher {
193+
padding: 0.5rem 1rem 1rem;
194+
border-top: 1px solid var(--pst-color-border);
195+
margin-top: 0.5rem;
196+
}
197+
198+
.version-switcher h4 {
199+
font-size: 0.75rem;
200+
text-transform: uppercase;
201+
letter-spacing: 0.05em;
202+
color: var(--pst-color-text-muted);
203+
margin: 0.5rem 0 0.4rem;
204+
}
205+
206+
.version-switcher select {
207+
width: 100%;
208+
padding: 0.35rem 0.5rem;
209+
font-size: 0.85rem;
210+
border: 1px solid var(--pst-color-border);
211+
border-radius: 6px;
212+
background-color: var(--pst-color-surface);
213+
color: var(--pst-color-text-base);
214+
cursor: pointer;
215+
appearance: auto;
216+
}
217+
218+
.version-switcher select:hover {
219+
border-color: var(--pst-color-text-muted);
220+
}
221+
222+
.version-switcher select:focus {
223+
outline: 2px solid #DC382D;
224+
outline-offset: 1px;
225+
}

docs/_templates/versioning.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{% if versions %}
2+
<div class="version-switcher">
3+
<h4>Version</h4>
4+
<select onchange="if (this.value) window.location.href = this.value;">
5+
{%- for item in versions.tags %}
6+
<option
7+
value="{{ vpathto(item.name) }}"
8+
{% if item.name == current_version.name %}selected{% endif %}
9+
>
10+
{{ item.name }}{% if loop.first %} (latest){% endif %}
11+
</option>
12+
{%- endfor %}
13+
{%- for item in versions.branches %}
14+
<option
15+
value="{{ vpathto(item.name) }}"
16+
{% if item.name == current_version.name %}selected{% endif %}
17+
>
18+
{{ item.name }}{% if item.name == "main" %} (dev){% endif %}
19+
</option>
20+
{%- endfor %}
21+
</select>
22+
</div>
23+
{% endif %}

docs/conf.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"_extension.gallery_directive",
3232
"myst_nb",
3333
"sphinx_favicon",
34+
"sphinx_multiversion",
3435
]
3536

3637
templates_path = ["_templates"]
@@ -98,3 +99,22 @@
9899
"Redis_Favicon_16x16_Red.png",
99100
"Redis_Favicon_144x144_Red.png",
100101
]
102+
103+
# -- sphinx-multiversion options ---------------------------------------------
104+
# Tag whitelist: match v0.4.0+ and v1.0.0+ (skip old tags without docs/)
105+
smv_tag_whitelist = r"^v0\.(([4-9]|\d{2,})\.\d+)$|^v([1-9]\d*)\.\d+\.\d+$"
106+
smv_branch_whitelist = r"^main$"
107+
smv_remote_whitelist = r"^origin$"
108+
smv_released_pattern = r"^refs/tags/.*$"
109+
smv_outputdir_format = "{ref.name}"
110+
111+
# -- Sidebar with version switcher ------------------------------------------
112+
html_sidebars = {
113+
"**": [
114+
"navbar-logo.html",
115+
"icon-links.html",
116+
"search-button-field.html",
117+
"sbt-sidebar-nav.html",
118+
"versioning.html",
119+
],
120+
}

docs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ myst-nb>=1.0
44
sphinx-design>=0.5
55
sphinx-copybutton>=0.5
66
sphinx-favicon>=1.0
7+
sphinx-multiversion>=0.2.4
78
pyyaml>=6.0

0 commit comments

Comments
 (0)