Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .github/workflows/build_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,5 @@ jobs:
- if: ${{ steps.skip_check.outputs.should_skip != 'true' }}
name: Build Sphinx Docs
run: |
# sphinx-multiversion expects at least a "main" branch
git branch main || echo "branch main already exists."
cd docs
sphinx-multiversion . _build/html

DOCS_VERSION=test make versioned-html
21 changes: 15 additions & 6 deletions .github/workflows/docs_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
pip check
mpas_analysis sync diags --help
cd docs
sphinx-multiversion . _build/html
DOCS_VERSION=${{ github.ref_name }} make versioned-html
- name: Copy Docs and Commit
run: |
set -e
Expand All @@ -71,17 +71,26 @@ jobs:
cd docs
# gh-pages branch must already exist
git clone https://github.com/MPAS-Dev/MPAS-Analysis.git --branch gh-pages --single-branch gh-pages

# Only replace docs in a directory with the destination branch name with latest changes. Docs for
# releases should be untouched.
rm -rf gh-pages/${{ github.ref_name }}

# don't clobber existing release versions (in case we retroactively fixed them)
cp -r _build/html/${{ github.ref_name }} gh-pages/

mkdir -p gh-pages/shared
cp shared/version-switcher.js gh-pages/shared/version-switcher.js

# Update the list of versions with all versions in the gh-pages directory.
python generate_versions_json.py

# Make sure we're in the gh-pages directory.
cd gh-pages
# Create `.nojekyll` (if it doesn't already exist) for proper GH Pages configuration.
touch .nojekyll
# Add `index.html` to point to the `develop` branch automatically.
printf '<meta http-equiv="refresh" content="0; url=./develop/index.html" />' > index.html
# Only replace docs in a directory with the destination branch name with latest changes. Docs for
# releases should be untouched.
rm -rf ${{ github.head_ref || github.ref_name }}
# don't clobber existing release versions (in case we retroactively fixed them)
cp -r -n ../_build/html/* .
# Configure git using GitHub Actions credentials.
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,7 @@ developers". Then run:
To generate the `sphinx` documentation, run:
```
cd docs
make clean
make html
DOCS_VERSION=test make clean versioned-html
```
The results can be viewed in your web browser by opening:
```
Expand Down
1 change: 0 additions & 1 deletion dev-spec.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,4 @@ m2r2>=0.3.3
mistune<2
sphinx
sphinx_rtd_theme
sphinx-multiversion
tabulate
21 changes: 21 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,23 @@ SPHINXPROJ = MPAS-Analysis
SOURCEDIR = .
BUILDDIR = _build

# Build into a versioned subdirectory
versioned-html:
@echo "Building version: $(DOCS_VERSION)"
$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html/$(DOCS_VERSION)"
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html/$(DOCS_VERSION)."
@echo "Setting up shared version switcher for local preview..."
mkdir -p _build/html/shared
cp shared/version-switcher.js _build/html/shared/version-switcher.js
python generate_versions_json.py --local

# Override html target to include local setup
html:
$(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html"
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."


# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
Expand All @@ -16,6 +33,10 @@ clean:
rm -rf users_guide/*obs_table.rst developers_guide/generated users_guide/obs
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

clean-versioned-html:
rm -rf $(BUILDDIR)/html/*
@echo "Cleaned versioned HTML builds."

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
Expand Down
26 changes: 26 additions & 0 deletions docs/_static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,29 @@
max-width: 1200px !important;
}

#version-switcher select {
background-color: #2980b9;
color: white;
border: none;
border-radius: 4px;
padding: 4px 30px 4px 10px;
font-size: 0.9em;
appearance: none; /* Remove default dropdown arrow */
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg fill='white' height='10' viewBox='0 0 24 24' width='10' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 10px center;
background-size: 12px;
}

#version-switcher select:focus {
outline: none;
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.4);
background-color: #2c89c4; /* slightly lighter blue on focus */
}

/* Selected item in the dropdown menu */
#version-switcher option:checked {
background-color: #dddddd; /* for selected */
color: black;
}

23 changes: 23 additions & 0 deletions docs/_templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,26 @@
<link href="{{ pathto("_static/style.css", True) }}" rel="stylesheet" type="text/css">
{% endblock %}


{% block footer %}
{{ super() }}

<!-- Meta tags for JS to use -->
<meta name="doc-version" content="{{ current_version }}">
<meta name="doc-site-root" content="{{ pathto('', 1) }}">

<!-- Create version switcher container -->
<script>
const sidebar = document.querySelector('.wy-side-nav-search');
if (sidebar) {
const versionDiv = document.createElement('div');
versionDiv.id = 'version-switcher';
versionDiv.style.marginTop = '1em';
sidebar.appendChild(versionDiv);
}
</script>

<!-- Load version-switcher.js using the correct relative path -->
<script src="{{ pathto('../shared/version-switcher.js', 1) }}"></script>
{% endblock %}

28 changes: 0 additions & 28 deletions docs/_templates/versions.html

This file was deleted.

13 changes: 2 additions & 11 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
# ones.
extensions = [
'sphinx_rtd_theme',
'sphinx_multiversion',
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
'sphinx.ext.intersphinx',
Expand Down Expand Up @@ -222,14 +221,6 @@
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]

html_sidebars = {
"**": [
"versions.html",
],
html_context = {
"current_version": os.getenv("DOCS_VERSION", "main"),
}

# -- Options sphinx-multiversion -------------------------------------------
# Include tags like "tags/1.0.0" -- 1.7.2 doesn't build
smv_tag_whitelist = r'^(?!1.7.2)\d+\.\d+.\d+$'
smv_branch_whitelist = r'^(develop|main)$'
smv_remote_whitelist = 'origin'
69 changes: 69 additions & 0 deletions docs/generate_versions_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python
import argparse
import json
import os
import re


def version_key(name):
"""Key function for sorting versions."""
match = re.match(r'^(\d+)\.(\d+)\.(\d+)$', name)
if match:
# Sort by major, minor, patch
return tuple(map(int, match.groups()))
return ()


# Mode: local or production
parser = argparse.ArgumentParser(
description='Generate versions.json for MPAS Analysis documentation.')
parser.add_argument(
'--local',
action='store_true',
help='Generate versions.json for local build.'
)
args = parser.parse_args()
local = args.local
base_dir = '_build/html' if local else 'gh-pages'
shared_dir = os.path.join(base_dir, 'shared')

entries = []

if not os.path.exists(base_dir) or not os.listdir(base_dir):
raise FileNotFoundError(
f"Base directory '{base_dir}' does not exist or is empty.")

versions = os.listdir(base_dir)
numeric_versions = []
non_numeric_versions = []

for version in versions:
# Check if it matches version pattern
if re.match(r'^\d+\.\d+\.\d+$', version):
numeric_versions.append(version)
else:
non_numeric_versions.append(version)

# Sort numeric versions by major, minor, patch in descending order
numeric_versions.sort(key=version_key, reverse=True)
# Sort non-numeric versions alphabetically
non_numeric_versions.sort()

# Combine the sorted lists
versions = non_numeric_versions + numeric_versions

if 'main' in versions:
versions.insert(0, versions.pop(versions.index('main')))

for name in versions:
path = os.path.join(base_dir, name)
if os.path.isdir(path) and name not in ('shared', '.git'):
entries.append({
'version': name,
'url': f'../{name}/' if local else f'/MPAS-Analysis/{name}/'
})

os.makedirs(shared_dir, exist_ok=True)
with open(os.path.join(shared_dir, 'versions.json'), 'w') as f:
json.dump(entries, f, indent=2)

48 changes: 48 additions & 0 deletions docs/shared/version-switcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
(async function () {
const container = document.getElementById("version-switcher");
if (!container) return;

const metaVersion = document.querySelector('meta[name="doc-version"]');
const currentVersion = metaVersion ? metaVersion.content : "unknown";
console.log("Detected current version:", currentVersion);

async function fetchVersions() {
try {
const scriptUrl = document.currentScript.src;
const basePath = scriptUrl.substring(0, scriptUrl.lastIndexOf('/') + 1);
const versionsUrl = basePath + "versions.json";

const res = await fetch(versionsUrl);
if (!res.ok) throw new Error(`Failed to load ${versionsUrl}`);
return await res.json();
} catch (err) {
console.error("Could not load versions.json:", err);
return [];
}
}

const versions = await fetchVersions();
if (!versions.length) return;

const select = document.createElement("select");
select.style.marginLeft = "1em";
select.onchange = () => {
window.location.href = select.value;
};

versions.forEach(({ version, url }) => {
const option = document.createElement("option");
option.value = url;
option.textContent = version;
if (version === currentVersion) {
option.selected = true;
}
select.appendChild(option);
});

const label = document.createElement("label");
label.textContent = "Version: ";
label.style.color = "white";
label.appendChild(select);
container.appendChild(label);
})();
2 changes: 1 addition & 1 deletion docs/tutorials/dev_add_task.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1143,7 +1143,7 @@ With the ``mpas_analysis_dev`` environment activated, you can run:
.. code-block:: bash

cd docs
make clean html
DOCS_VERSION=test make clean versioned-html

to build the docs locally in the ``_build/html`` subdirectory. When generating
documentation on HPC machines, you will want to copy the html output to the
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ docs = [
"mistune<2",
"sphinx",
"sphinx_rtd_theme",
"sphinx-multiversion",
"tabulate",
]

Expand Down
3 changes: 1 addition & 2 deletions suite/run_dev_suite.bash
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ branch=$(git symbolic-ref --short HEAD)
# test building the docs
conda activate ${env_name}
cd docs
make clean
make html
DOCS_VERSION=test make clean versioned-html
cd ..

machine=$(python -c "from mache import discover_machine; print(discover_machine())")
Expand Down
3 changes: 1 addition & 2 deletions suite/run_suite.bash
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ conda deactivate
py=${main_py}
conda activate test_mpas_analysis_py${py}
cd docs
make clean
make html
DOCS_VERSION=test make clean versioned-html
cd ..

machine=$(python -c "from mache import discover_machine; print(discover_machine())")
Expand Down