From 8680b31aa4996a147085b0762b5c940001e0ea39 Mon Sep 17 00:00:00 2001 From: Nubenetes Bot Date: Sat, 20 Jun 2026 23:55:32 +0200 Subject: [PATCH] feat(v2): auto-version static assets from release tag (no more manual ?v=) Adds a MkDocs on_config hook (scripts/mkdocs_hooks.py) that appends the release version as the ?v= cache-buster on v2_elite.css and v2_filter.js, resolved from $SITE_VERSION or the latest git tag. Removes the hand- maintained query strings from v2-mkdocs.yml. This prevents the class of bug fixed in v2.9.46: a CSS/JS change going invisible to returning visitors because ?v= was never bumped (it had drifted to 2.9.42 for the CSS and 2.9.19 for the JS). Now every release stamps a fresh URL automatically. Falls back to leaving URLs untouched when no version is resolvable (e.g. local mkdocs serve in a shallow checkout), so the build never fails. Verified: build from git tag -> ?v=2.9.46; SITE_VERSION=9.9.9 -> ?v=9.9.9. Co-Authored-By: Claude Opus 4.8 --- scripts/mkdocs_hooks.py | 57 +++++++++++++++++++++++++++++++++++++++++ v2-mkdocs.yml | 11 ++++++-- 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 scripts/mkdocs_hooks.py diff --git a/scripts/mkdocs_hooks.py b/scripts/mkdocs_hooks.py new file mode 100644 index 00000000..842bbf4e --- /dev/null +++ b/scripts/mkdocs_hooks.py @@ -0,0 +1,57 @@ +"""MkDocs build hooks for the Nubenetes V2 portal. + +Auto-versions cache-busted static assets so a CSS/JS change never goes stale +behind a hand-maintained `?v=` query string again (see v2.9.45 regression where +the Trending "Show more" disclosure was invisible to returning visitors because +`?v=` was pinned to 2.9.42). + +The version is resolved from, in order: + 1. $SITE_VERSION (set explicitly by the deploy workflow) + 2. the latest git tag (`git describe --tags --abbrev=0`) +If neither is available (e.g. a local `mkdocs serve` in a shallow checkout), +the asset URLs are left untouched so the build never fails. +""" +import os +import subprocess + +# Static assets whose URL should carry the release version as a cache-buster. +_VERSIONED_ASSETS = ("v2_elite.css", "v2_filter.js") + + +def _resolve_version(): + v = os.environ.get("SITE_VERSION", "").strip() + if not v: + try: + v = subprocess.check_output( + ["git", "describe", "--tags", "--abbrev=0"], + stderr=subprocess.DEVNULL, + ).decode().strip() + except Exception: + return None + return v.lstrip("v") or None + + +def _bump(items, version): + out = [] + for item in items: + # extra_javascript entries may be plain strings or ExtraScript objects. + path = item if isinstance(item, str) else getattr(item, "path", None) + if path and any(name in path for name in _VERSIONED_ASSETS): + new_path = f"{path.split('?')[0]}?v={version}" + if isinstance(item, str): + out.append(new_path) + else: + item.path = new_path + out.append(item) + else: + out.append(item) + return out + + +def on_config(config, **kwargs): + version = _resolve_version() + if not version: + return config + config["extra_css"] = _bump(config.get("extra_css", []), version) + config["extra_javascript"] = _bump(config.get("extra_javascript", []), version) + return config diff --git a/v2-mkdocs.yml b/v2-mkdocs.yml index 2d705532..b588581b 100644 --- a/v2-mkdocs.yml +++ b/v2-mkdocs.yml @@ -60,6 +60,11 @@ theme: # the per-page Markdown "## Table of Contents" we no longer render. - toc.follow +# Auto-version cache-busted static assets (v2_elite.css / v2_filter.js) from the +# release tag, so a CSS/JS change never goes stale behind a hand-maintained ?v=. +hooks: + - scripts/mkdocs_hooks.py + plugins: - search # "Last updated" per-page date (freshness signal for SEO + reader trust). @@ -115,10 +120,12 @@ extra: extra_css: - https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap - static/extra.css - - static/v2_elite.css?v=2.9.46 + # ?v= cache-buster is appended automatically from the release tag by + # scripts/mkdocs_hooks.py — do not hand-maintain it here. + - static/v2_elite.css extra_javascript: - - static/v2_filter.js?v=2.9.19 + - static/v2_filter.js markdown_extensions: - admonition