Skip to content

feat: version-pinned documentation orchestrator (per-repo aggregation) - #54

Draft
sstruzik wants to merge 21 commits into
mainfrom
docs/migration
Draft

feat: version-pinned documentation orchestrator (per-repo aggregation)#54
sstruzik wants to merge 21 commits into
mainfrom
docs/migration

Conversation

@sstruzik

Copy link
Copy Markdown
Contributor

GenerateDocs no longer holds content. Each component owns/builds its own Sphinx docs; this repo pins versions (modules.json) and assembles them (orchestrate.py): two-pass build so cross-component intersphinx resolves, then rewrites cross-links to page-relative (relocatable, works under file://). Slimmed src/ to a landing; drained ~45 duplicated sections/ + schema//releases//redoc/.

Part of the cross-repo Oasis documentation restructure (Option B).

Replace the monolithic docs build with a version-pinned orchestrator that aggregates each repo's own documentation.

…repo aggregation)

GenerateDocs no longer holds documentation content. Each component owns and builds its
own Sphinx docs; this repo pins versions and assembles them:

- modules.json: pinned manifest (repo, ref, docs_source, publish path, site_base_url).
- orchestrate.py: builds each component from its repo (--clone at ref, or --use-local),
  two-pass so cross-component intersphinx resolves, then rewrites cross-links to
  page-relative so the assembled site is relocatable (works under file://).
- src/: slimmed to a landing (component cards + home + use cases); drained ~45 duplicated
  sections/, plus schema/, releases/, redoc/, update-redoc.py (now owned by the components).
- build.sh: thin wrapper (./build.sh clone+build; ./build.sh --local).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sstruzik and others added 20 commits July 17, 2026 17:26
Rewrite README for the orchestrator: local build (--local from sibling checkouts, or
orchestrate.py directly), pinned clone (CI), flags, and how to view the static site.
Update requirements to the union of every component's Sphinx extensions (add myst-nb,
myst-parser, sphinx-design, sphinx-copybutton, oasislmf; drop py3.12-incompatible
monolith leftovers) so a fresh-venv build can build all components.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Brand the landing with the Oasis logo and palette (matching oasislmf.github.io), and
rewrite the per-page 'Oasis documentation home' link (and cross-links) to page-relative
so the assembled site is relocatable and the home link works from any component/page.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A fresh build venv pulled setuptools>=81, which dropped pkg_resources and broke
sphinxcontrib.redoc (OasisPlatform docs). Pin setuptools<81 so the redoc extension
imports. Also make the three `here`_ FAQ links anonymous to clear duplicate-target
warnings on the landing under Sphinx 7.4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hinx 9

OasisPlatform now renders its REST API with a vendored Redoc bundle (no Sphinx
extension), so the aggregator toolchain no longer needs sphinxcontrib-redoc or the
setuptools<81 pkg_resources workaround. Recompiled requirements now resolve Sphinx 9.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The executable tutorials (PiWind analysis, ORD results, EP curves) plot with matplotlib,
but it wasn't in requirements — only numpy/pandas came transitively via oasislmf. A fresh
build venv therefore failed executing run-piwind-analysis.md with ModuleNotFoundError:
matplotlib. Add matplotlib so build.sh's venv can run the notebooks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
src/_templates/page.html was a full copy of Furo's page template carried over from the
old monolith, with a hardcoded Oasis logo (pointing at the prod oasislmf.github.io URL)
injected into the sidebar. With light_logo/dark_logo now set in conf.py, Furo already
renders the logo — so the page showed two logos with different link targets. Drop the
override; Furo's default template renders the single, correctly-relative logo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Furo links its sidebar-brand logo to each component's own index. The post-assembly
rewrite now repoints that logo at the site-root landing (page-relative, depth-correct),
so clicking the Oasis logo from anywhere in the aggregated site returns to the top-level
index — resolving locally (file://), on any server, and under a project sub-path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The sidebar logo returns to the aggregated landing, so the redundant 'Oasis
documentation home' announcement bar is removed. GitHub link moved to Furo's
footer icons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…checkout

Mark oasislmf and ods-tools '"editable": true' in modules.json; before building such a
module the orchestrator runs 'pip install -e <checkout> --no-deps' (setuptools compat mode,
so all submodules resolve and it overrides any pre-existing wheel). Sphinx/autoapi and the
executable notebooks then document the source at the pinned ref rather than the last PyPI
release — fixing e.g. autoapi rendering inherited docstrings from the stale installed package.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ploy CI)

The orchestrator emitted output/site while the deploy/preview workflows publish build/html
(the old monolith path). Rather than change the CI, produce build/html so the existing
Build-and-Deploy and PR-preview workflows publish the orchestrated site unchanged. build.sh
still packages output/oasis_docs.tar.gz.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ion)

--deploy-version NAME assembles the site into build/html/NAME/, maintains versions.json +
a root redirect, and injects a sidebar version dropdown into every page. Switching goes to
the same page under the chosen version, falling back to that version's landing when the page
is absent there (JS HEAD check; direct jump under file://). Runs accumulate: the version list
is scanned from the sub-dirs present, so re-running for a new version refreshes versions.json,
the redirect and every dropdown. --latest points the root redirect at the given version.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give developers a linear path: clone GenerateDocs + the component repos side by side,
create a venv and install requirements, build with --use-local, and preview via a local
server (recommended over file:// since search and the version selector's 404 fallback need
a served site). Fix the stale prerequisites list (redoc is now a vendored bundle, not a
Sphinx extension). Repo README only — not part of the published site.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rework build-deploy.yml for versioned publishing: trigger on release (tag = version) or
manual dispatch (version + set_latest inputs); restore the currently-published site so
versions accumulate; build the new version with orchestrate.py --deploy-version; deploy the
full tree to the Pages branch. Also make the version ordering semver-aware (2.5.10 > 2.5.6,
ignoring a 'v' prefix) so 'latest' leads and the newest release follows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repo-only runbook (not in the published site) for the person doing a release: pin
modules.json to the release tags, then cut a GitHub release or run the deploy workflow;
what CI does, how to verify, and edge cases (back-versions, first deploy, Pages branch).
Linked from the README's versioned-publishing section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rch form

Anchor on Furo's sidebar-search-container form (always present) instead of the preceding
</a>, so injection is robust across templates — including the legacy site's older Furo
template. Same placement (under the brand); verified it still injects on all component pages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The aggregated site has one Sphinx search index per component, so the top-level search only
covered the landing (e.g. 'geocoding' returned nothing). Add build_federated_search: a
top-level search page that fetches every component's searchindex.js, searches them together
(title/path hits + approximate-stem term matching), and lists results grouped by component;
every page's sidebar search box is repointed at it. Verified 'geocoding' now returns hits
from oasislmf/oed/etc. (Fetching indexes needs the site served, same as Sphinx's own search.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fetch each result page's source (_sources/<filename>.txt, as Sphinx does) and render a short
cleaned excerpt around the matched term with the query highlighted — matching the snippet UX
of the old single-index site. Light reST/MyST cleanup (drop underline rows, :role:`` markup,
directive lines, stray backticks/stars) so the excerpt reads as prose.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Convert each use-case page's section list into a toctree of external links, so Furo renders
the sections as a collapsible dropdown under the use case in the sidebar (e.g. Model
Developers → Oasis Model Data Formats, OED, Keys Service, …). Links use absolute site URLs so
the orchestrator's rewrite makes them page-relative/depth-correct; external links (Oasis UI)
are left alone. Targets point at the real component pages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Previously a build could leave a full latest/ copy of the site, which showed up as a
'version' in the dropdown and duplicated content. Now 'latest' is purely a redirect: the
site root and /latest/ both forward to the newest version (or the one built with --latest),
/latest/ is a 1-file redirect stub (any stale full copy is replaced), and it never appears
in versions.json or the dropdown. Docs updated to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The version selector now appends '(latest)' to whichever version the root/latest redirect
points at (the --latest version, or the newest by number) — e.g. '2.5.7 (latest)', '2.5.6'.
write_versions_index returns the resolved latest so inject_version_switcher can label it
consistently on every page.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants