Skip to content

Add documentation version switcher (dev vs stable)#497

Draft
raphaelvallat wants to merge 2 commits intomainfrom
dev_doc_toggle
Draft

Add documentation version switcher (dev vs stable)#497
raphaelvallat wants to merge 2 commits intomainfrom
dev_doc_toggle

Conversation

@raphaelvallat
Copy link
Copy Markdown
Owner

Add documentation version switcher (dev vs stable)

Summary

The docs were previously re-deployed on every push to main, meaning users could read unreleased API changes. This PR adds a version toggle identical to the one used by NumPy, SciPy, and other scientific Python libraries, letting users switch between the development (main branch) and latest stable (PyPI release) documentation.

Changes

  • docs/switcher.json — New JSON file consumed by the pydata_sphinx_theme version-switcher component. Lists dev and 0.6.0 (stable) with their respective URLs. Auto-regenerated with the correct version number on every stable release.
  • docs/conf.py — Reads a DOC_VERSION environment variable ("dev" or "stable") to:
    • Set the active item in the version-switcher dropdown (version_match)
    • Show a yellow announcement banner on dev docs: "You are reading the development version…"
    • Expose switcher.json at the root of the HTML output via html_extra_path
  • .github/workflows/deploy_doc.yml — Reworked dev-docs deployment:
    • Switches from actions/deploy-pages (whole-site replace) to JamesIves/github-pages-deploy-action (subdirectory-aware)
    • Deploys to pingouin-stats.org/dev/
    • Deploys a meta-refresh redirect + switcher.json to the site root (with clean: false to preserve other subdirectories)
  • .github/workflows/deploy_stable_doc.yml — New workflow triggered on every published GitHub Release (and manually via workflow_dispatch):
    • Auto-updates switcher.json with the new stable version number
    • Deploys to pingouin-stats.org/stable/
    • Updates the root redirect and switcher.json

Result

URL Content
pingouin-stats.org/ Redirect → stable/
pingouin-stats.org/stable/ Latest PyPI release
pingouin-stats.org/dev/ Main branch (unreleased changes, with banner)
pingouin-stats.org/switcher.json Version list for the navbar toggle

Required one-time setup after merge

Important

  1. GitHub Settings → Pages: change source from "GitHub Actions" to "Deploy from a branch"gh-pages / /(root)
  2. Run "Deploy Stable Documentation" manually (via workflow_dispatch) to populate stable/ for the first time

Test plan

  • Change GitHub Pages source to gh-pages branch
  • Merge PR → confirm dev/ is populated at pingouin-stats.org/dev/ with the dev banner visible
  • Trigger "Deploy Stable Documentation" manually → confirm stable/ is populated and the switcher dropdown shows both versions with the correct one highlighted
  • Publish a new release → confirm switcher.json is updated automatically with the new version number

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a documentation “dev vs stable” version switcher and updates GitHub Pages deployment so unreleased changes on main are published under /dev/ while release docs are published under /stable/, with the site root redirecting to stable.

Changes:

  • Add docs/switcher.json and wire it into pydata_sphinx_theme’s version switcher via docs/conf.py (including a dev-docs announcement banner).
  • Rework dev docs deployment to publish under dev/ and deploy a root redirect + switcher.json.
  • Add a new stable docs deployment workflow intended to run on GitHub Releases and publish under stable/.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
docs/switcher.json Adds the version list consumed by the theme’s version switcher.
docs/conf.py Adds DOC_VERSION-driven switcher selection + dev announcement banner; exposes switcher.json in built HTML.
docs/index.rst Updates Binder link to use the main branch.
README.rst Updates Binder link to use the main branch.
.github/workflows/deploy_doc.yml Deploys dev docs to dev/ and also deploys root redirect + switcher.json.
.github/workflows/deploy_stable_doc.yml New workflow to build/deploy stable docs to stable/ and update root redirect + switcher.json.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/conf.py
release = pingouin.__version__

doc_version = os.environ.get("DOC_VERSION") # "dev", "stable", or None (local build)
version_match = "dev" if doc_version == "dev" else version
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When DOC_VERSION is unset (local builds and the existing doc.yml CI job), version_match is set to pingouin.__version__. On main this is typically a dev version string that won’t match any entry in switcher.json, so the version switcher will likely highlight the preferred (stable) entry even for dev docs. If the intent is to default to dev in these cases, set version_match to "dev" when DOC_VERSION is missing and the codebase version indicates a dev build (or make CI set DOC_VERSION=dev).

Suggested change
version_match = "dev" if doc_version == "dev" else version
if doc_version is None:
# When building from a dev version locally/without DOC_VERSION, default to "dev"
version_match = "dev" if "dev" in version else version
elif doc_version == "dev":
version_match = "dev"
else:
version_match = version

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +50
- name: Update switcher.json with current stable version
run: |
python -c "
import json, pingouin
stable_version = pingouin.__version__
switcher = [
{
'name': 'dev (main branch)',
'version': 'dev',
'url': 'https://pingouin-stats.org/dev/'
},
{
'name': f'{stable_version} (stable)',
'version': stable_version,
'url': 'https://pingouin-stats.org/stable/',
'preferred': True
}
]
with open('docs/switcher.json', 'w') as f:
json.dump(switcher, f, indent=2)
f.write('\n')
print(f'Updated switcher.json with stable version {stable_version}')
"
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The python -c "..." block embeds leading indentation spaces in the Python code (because of YAML indentation), which will raise IndentationError: unexpected indent at runtime. Use a heredoc (python - <<'PY' ... PY) or make the -c argument a single line without leading spaces so the workflow can actually update docs/switcher.json.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +22
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version-file: "pyproject.toml"
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

workflow_dispatch runs will check out the selected branch (typically main), so this workflow can end up publishing “stable” docs built from unreleased code and a non-stable pingouin.__version__. To ensure stable docs always match a release, make the checkout use a release tag/commit (e.g., checkout ${{ github.event.release.tag_name }} on release events and require an explicit tag/ref input for manual runs, then checkout that).

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +49
- name: Create root redirect and switcher
run: |
mkdir -p /tmp/root-pages
cp docs/switcher.json /tmp/root-pages/switcher.json
cat > /tmp/root-pages/index.html << 'EOF'
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dev-docs workflow deploys docs/switcher.json to the site root on every push to main. After a release, the stable-docs workflow will deploy an updated switcher with the new stable version, but the next dev deploy will overwrite it with whatever is committed on main (likely stale). Consider having only the stable-docs workflow update root switcher.json, or generate the stable version dynamically in this workflow (e.g., from the latest GitHub Release/PyPI) before deploying it.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants