From ca8718da3cdc8c2865a41cc809ba9e7210a17717 Mon Sep 17 00:00:00 2001 From: d3vyce Date: Wed, 11 Mar 2026 15:03:20 -0400 Subject: [PATCH] docs: add documentation versioning --- .github/workflows/docs.yml | 28 ++++++-- docs/overrides/partials/header.html | 69 +++++++++++++++++++ docs/stylesheets/version.css | 100 ++++++++++++++++++++++++++++ mkdocs.yml | 5 ++ scripts/mkdocs | 60 +++++++++++++++++ 5 files changed, 257 insertions(+), 5 deletions(-) create mode 100644 docs/overrides/partials/header.html create mode 100644 docs/stylesheets/version.css create mode 100644 mkdocs.yml create mode 100755 scripts/mkdocs diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 77b3423..ad3a756 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -5,7 +5,7 @@ on: types: [published] permissions: - contents: read + contents: write pages: write id-token: write @@ -16,9 +16,14 @@ jobs: url: ${{ steps.deployment.outputs.page_url }} runs-on: ubuntu-latest steps: - - uses: actions/configure-pages@v5 - - uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" - name: Install uv uses: astral-sh/setup-uv@v7 @@ -26,9 +31,22 @@ jobs: - name: Set up Python run: uv python install 3.13 - - run: uv sync --group dev + - run: uv sync --group docs - - run: uv run zensical build --clean + - name: Install mkdocs shim + run: cp scripts/mkdocs .venv/bin/mkdocs && chmod +x .venv/bin/mkdocs + + - name: Deploy docs version + run: | + VERSION="${GITHUB_REF_NAME#v}" + MINOR_VERSION="${VERSION%.*}" + uv run mike deploy --push --update-aliases "$MINOR_VERSION" latest + uv run mike set-default --push latest + + - name: Prepare site artifact + run: git worktree add site gh-pages + + - uses: actions/configure-pages@v5 - uses: actions/upload-pages-artifact@v4 with: diff --git a/docs/overrides/partials/header.html b/docs/overrides/partials/header.html new file mode 100644 index 0000000..a957872 --- /dev/null +++ b/docs/overrides/partials/header.html @@ -0,0 +1,69 @@ +{#- + Override of partials/header.html — adds version selector slot missing in Zensical. +-#} +{% set class = "md-header" %} +{% if "navigation.tabs.sticky" in features %} + {% set class = class ~ " md-header--shadow md-header--lifted" %} +{% elif "navigation.tabs" not in features %} + {% set class = class ~ " md-header--shadow" %} +{% endif %} +
+ + {% if "navigation.tabs.sticky" in features %} + {% if "navigation.tabs" in features %} + {% include "partials/tabs.html" %} + {% endif %} + {% endif %} +
diff --git a/docs/stylesheets/version.css b/docs/stylesheets/version.css new file mode 100644 index 0000000..b24b379 --- /dev/null +++ b/docs/stylesheets/version.css @@ -0,0 +1,100 @@ +/* Version selector styles for Zensical modern theme (backported from classic theme). + The JS appends .md-version into .md-header__topic, so we make that flex. */ +.md-header__topic:has(.md-version) { + display: flex; + align-items: center; +} + + +:root { + --md-version-icon: url('data:image/svg+xml;charset=utf-8,'); +} + +.md-version { + flex-shrink: 0; + font-size: .8rem; + height: 2.4rem; +} + +[dir=ltr] .md-version__current { margin-left: 1.4rem; margin-right: .4rem; } +[dir=rtl] .md-version__current { margin-left: .4rem; margin-right: 1.4rem; } + +.md-version__current { + color: inherit; + cursor: pointer; + outline: none; + position: relative; + top: .05rem; +} + +[dir=ltr] .md-version__current:after { margin-left: .4rem; } +[dir=rtl] .md-version__current:after { margin-right: .4rem; } + +.md-version__current:after { + background-color: currentcolor; + content: ""; + display: inline-block; + height: .6rem; + -webkit-mask-image: var(--md-version-icon); + mask-image: var(--md-version-icon); + -webkit-mask-position: center; + mask-position: center; + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: contain; + mask-size: contain; + width: .4rem; +} + +.md-version__alias { + margin-left: .3rem; + opacity: .7; +} + +.md-version__list { + background-color: var(--md-default-bg-color); + border-radius: .1rem; + box-shadow: var(--md-shadow-z2); + color: var(--md-default-fg-color); + list-style-type: none; + margin: .2rem .8rem; + max-height: 0; + opacity: 0; + overflow: auto; + padding: 0; + position: absolute; + scroll-snap-type: y mandatory; + top: .15rem; + transition: max-height 0ms .5s, opacity .25s .25s; + z-index: 3; +} + +.md-version:focus-within .md-version__list, +.md-version:hover .md-version__list { + max-height: 10rem; + opacity: 1; + transition: max-height 0ms, opacity .25s; +} + +.md-version:hover .md-version__list { animation: hoverfix .25s forwards; } +.md-version:focus-within .md-version__list { animation: none; } + +.md-version__item { line-height: 1.8rem; } + +[dir=ltr] .md-version__link { padding-left: .6rem; padding-right: 1.2rem; } +[dir=rtl] .md-version__link { padding-left: 1.2rem; padding-right: .6rem; } + +.md-version__link { + cursor: pointer; + display: block; + outline: none; + scroll-snap-align: start; + transition: color .25s, background-color .25s; + white-space: nowrap; + width: 100%; +} + +.md-version__link:focus, +.md-version__link:hover { color: var(--md-accent-fg-color); } + +.md-version__link:focus { background-color: var(--md-default-fg-color--lightest); } diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..209c700 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,5 @@ +# Minimal stub for mike compatibility. +# The actual build is handled by zensical (see scripts/mkdocs shim). +site_name: FastAPI Toolsets +docs_dir: docs +site_dir: site diff --git a/scripts/mkdocs b/scripts/mkdocs new file mode 100755 index 0000000..c439e2c --- /dev/null +++ b/scripts/mkdocs @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""mkdocs shim for mike compatibility. + +mike parses mkdocs.yml (valid YAML stub) for its Python internals, then calls +`mkdocs build --config-file ` as a subprocess. + +This shim intercepts that subprocess call, ignores the temp config, and +delegates the actual build to `zensical build -f zensical.toml` instead. +""" + +from __future__ import annotations + +import os +import subprocess +import sys + + +def main() -> None: + args = sys.argv[1:] + + # mike calls `mkdocs --version` to embed in the commit message + if args and args[0] == "--version": + print("mkdocs, version 1.0.0 (zensical shim)") + return + + if not args or args[0] != "build": + result = subprocess.run(["python3", "-m", "mkdocs"] + args) + sys.exit(result.returncode) + + config_file = "mkdocs.yml" + clean = False + + i = 1 + while i < len(args): + if args[i] in ("-f", "--config-file") and i + 1 < len(args): + config_file = args[i + 1] + i += 2 + elif args[i] in ("-c", "--clean"): + clean = True + i += 1 + elif args[i] == "--dirty": + i += 1 + else: + i += 1 + + # mike creates a temp file prefixed with "mike-mkdocs"; always delegate + # the actual build to zensical regardless of which config was passed. + del config_file # unused — zensical auto-discovers zensical.toml + + cmd = ["zensical", "build"] + if clean: + cmd.append("--clean") + + env = os.environ.copy() + result = subprocess.run(cmd, env=env) + sys.exit(result.returncode) + + +if __name__ == "__main__": + main()