From 2e5eceb65612beceeb800616a54d9efb074c19c5 Mon Sep 17 00:00:00 2001 From: bcastets-robotiq Date: Mon, 28 Sep 2026 10:23:01 -0400 Subject: [PATCH 1/3] Automate cutting Stable/Previous versions with scripts/cut-version.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the by-hand checkout/sync/version/restore procedure documented in docs/contribute/versioning.mdx with a single command per cut (`node scripts/cut-version.js stable|previous-versions`), per explicit direction that the site's job is to render docs with no manual intervention. Covers every step the manual procedure required — tag discovery, submodule checkout/restore, stale-content and stale-sidebar-cache pruning, dangling sub-page link pruning, main->tag link rewriting, the Development-only admonition strip, the Previous-versions signpost, and the Stable label (now read from versioned-tools-stable.json instead of hand-typed in docusaurus.config.js) — with best-effort cleanup so a failure partway through never leaves Development's own live content broken. Also fixes a latent bug this surfaced: sidebars.adaptive-grippers-cpp.js's "Introduction guides" category linked unconditionally to a docs/index doc id, even for a version (a previous-versions signpost, or a tag predating the guide folder) that has no docs/ content at all — frozen into that version's sidebar snapshot, only caught by Docusaurus's build-time checkSidebarsDocIds, not by the cut itself. Guarded the same way the neighboring doxygenApiCategory already was. Validated by re-cutting all three versioned tools' stable and previous-versions end to end and confirming a clean npm run build, with only pre-existing, unrelated diffs (a stray leftover _readme.md under each tool's previous-versions snapshot, plus a capitalization/line-wrap fix in the signpost text). Co-Authored-By: Claude Sonnet 5 --- .../version-previous-versions/_readme.md | 14 - .../version-stable/docs/index.mdx | 15 + .../version-stable/index.mdx | 8 + .../version-previous-versions-sidebars.json | 10 +- .../version-stable-sidebars.json | 20 +- adaptive-grippers-cpp_versions.json | 4 +- docs/contribute/versioning.mdx | 211 ++++---- docusaurus.config.js | 28 +- scripts/cut-version.js | 501 ++++++++++++++++++ scripts/versioned-tools.js | 44 ++ sidebars.adaptive-grippers-cpp.js | 25 +- .../version-previous-versions/_readme.md | 304 ----------- .../version-previous-versions/index.mdx | 8 +- tactile-cpp_versions.json | 5 +- .../version-previous-versions/_readme.md | 170 ------ .../version-previous-versions/index.mdx | 8 +- tactile-python_versions.json | 5 +- test/cut-version.test.js | 172 ++++++ versioned-tools-stable.json | 5 + 19 files changed, 928 insertions(+), 629 deletions(-) delete mode 100644 adaptive-grippers-cpp_versioned_docs/version-previous-versions/_readme.md create mode 100644 adaptive-grippers-cpp_versioned_docs/version-stable/docs/index.mdx create mode 100644 scripts/cut-version.js create mode 100644 scripts/versioned-tools.js delete mode 100644 tactile-cpp_versioned_docs/version-previous-versions/_readme.md delete mode 100644 tactile-python_versioned_docs/version-previous-versions/_readme.md create mode 100644 test/cut-version.test.js create mode 100644 versioned-tools-stable.json diff --git a/adaptive-grippers-cpp_versioned_docs/version-previous-versions/_readme.md b/adaptive-grippers-cpp_versioned_docs/version-previous-versions/_readme.md deleted file mode 100644 index a9c3674..0000000 --- a/adaptive-grippers-cpp_versioned_docs/version-previous-versions/_readme.md +++ /dev/null @@ -1,14 +0,0 @@ - - -C++ driver with functions to control `Robotiq` Adaptive Grippers: 2F85, 2F140 and Hand-E. It allows high communication frequency. - -:::note -With the default baudrate of the gripper the maximum achievable communication -frequency is 250Hz. The communication frequency is set with the -`ConnectionConfig::connectionFrequency` parameter, which defaults to 100Hz. -::: - -Cross-platform: Linux, Windows, macOS — and freestanding/RTOS targets such -as STM32 microcontrollers. - - diff --git a/adaptive-grippers-cpp_versioned_docs/version-stable/docs/index.mdx b/adaptive-grippers-cpp_versioned_docs/version-stable/docs/index.mdx new file mode 100644 index 0000000..ad6a4ad --- /dev/null +++ b/adaptive-grippers-cpp_versioned_docs/version-stable/docs/index.mdx @@ -0,0 +1,15 @@ +--- +title: Introduction guides +sidebar_label: Introduction guides +--- + +import Readme from '../_readme.md'; + + + +## Contents + +{/* AUTO-GENERATED-GUIDES-TABLE:START */} + +{/* AUTO-GENERATED-GUIDES-TABLE:END */} + diff --git a/adaptive-grippers-cpp_versioned_docs/version-stable/index.mdx b/adaptive-grippers-cpp_versioned_docs/version-stable/index.mdx index 929d4eb..ad17b43 100644 --- a/adaptive-grippers-cpp_versioned_docs/version-stable/index.mdx +++ b/adaptive-grippers-cpp_versioned_docs/version-stable/index.mdx @@ -15,6 +15,14 @@ import Readme from './_readme.md'; +## Get started + +{/* AUTO-GENERATED-SUBPAGES-TABLE:START */} + +{/* AUTO-GENERATED-SUBPAGES-TABLE:END */} + ## Source Code GitHub Repository diff --git a/adaptive-grippers-cpp_versioned_sidebars/version-previous-versions-sidebars.json b/adaptive-grippers-cpp_versioned_sidebars/version-previous-versions-sidebars.json index 8505830..a8402c3 100644 --- a/adaptive-grippers-cpp_versioned_sidebars/version-previous-versions-sidebars.json +++ b/adaptive-grippers-cpp_versioned_sidebars/version-previous-versions-sidebars.json @@ -14,9 +14,13 @@ "label": "Libraries", "items": [ { - "type": "doc", - "id": "index", - "label": "C++" + "type": "category", + "label": "C++", + "link": { + "type": "doc", + "id": "index" + }, + "items": [] }, { "type": "link", diff --git a/adaptive-grippers-cpp_versioned_sidebars/version-stable-sidebars.json b/adaptive-grippers-cpp_versioned_sidebars/version-stable-sidebars.json index 8505830..f7b12a9 100644 --- a/adaptive-grippers-cpp_versioned_sidebars/version-stable-sidebars.json +++ b/adaptive-grippers-cpp_versioned_sidebars/version-stable-sidebars.json @@ -14,9 +14,23 @@ "label": "Libraries", "items": [ { - "type": "doc", - "id": "index", - "label": "C++" + "type": "category", + "label": "C++", + "link": { + "type": "doc", + "id": "index" + }, + "items": [ + { + "type": "category", + "label": "Introduction guides", + "link": { + "type": "doc", + "id": "docs/index" + }, + "items": [] + } + ] }, { "type": "link", diff --git a/adaptive-grippers-cpp_versions.json b/adaptive-grippers-cpp_versions.json index 402035e..47ba807 100644 --- a/adaptive-grippers-cpp_versions.json +++ b/adaptive-grippers-cpp_versions.json @@ -1,4 +1,4 @@ [ - "stable", - "previous-versions" + "previous-versions", + "stable" ] diff --git a/docs/contribute/versioning.mdx b/docs/contribute/versioning.mdx index 1d42c5d..bd51884 100644 --- a/docs/contribute/versioning.mdx +++ b/docs/contribute/versioning.mdx @@ -204,106 +204,68 @@ also swizzled shorter, to one line (`src/theme/DocVersionBanner/index.jsx`) — unrelated to any of the above, just bundled into the same theme-swizzling work. -## Cutting Stable or Previous versions by hand +## Cutting Stable or Previous versions -There's no CI automation for this yet — every version cut is a manual, -local operation, run once and committed. `scripts/list-submodule-tags.js` -finds the current tags directly off each submodule's remote (`git -ls-remote --tags`, not the local checkout, which can go stale): +One command each, via `scripts/cut-version.js`: ```bash -node scripts/list-submodule-tags.js +node scripts/cut-version.js stable [] # defaults to the newest +node scripts/cut-version.js previous-versions ``` -**To cut (or re-cut) Stable at the newest tag:** - -```bash -cd external/ -git checkout -cd ../.. -SKIP_SUBMODULE_RESET=1 node scripts/sync-external-docs.js -npm run docusaurus -- docs:version: stable -cd external/ && git checkout main && cd ../.. -SKIP_SUBMODULE_RESET=1 node scripts/sync-external-docs.js # restore Development (main)'s own content -``` - -`SKIP_SUBMODULE_RESET=1` is required — `sync-external-docs.js` runs `git -submodule update --init --force` on every normal invocation, which would -silently revert the manual `git checkout ` right back to the pinned -commit before the sync even ran. - -**Rewrite any `main`-branch source links to the tag, before cutting.** -Content synced from the submodule (its README, guides) routinely links -back to its own source on GitHub — `tree/main/...`, `blob/main/...` — which -is correct for Development but wrong once that same text is frozen into a -Stable snapshot: the file at `main` can already differ from what shipped -in the tag Stable is supposed to represent. Rewrite every such link to -`tree//...` / `blob//...` in the checked-out content *before* -running `docs:version:`, and do the same for any hand-authored "Source -Code" button/CTA on the tool's own wrapper page -(`https://github.com//` → `https://github.com///tree/`). -There's no automation for this yet — grep the synced content for -`/main/` under `github.com/robotiq/` before cutting, and check by hand. - -**Watch for stale-content contamination.** `sync-external-docs.js` never -deletes a previously-written folder (e.g. a tool's `docs/` guides or -generated `API/`) just because the currently-checked-out tag's job skips -(no `Doxyfile` yet at that tag, no `docs/` folder yet, ...) — it only -writes what the current job list produces. If `versioned-tools///` -already has content left over from a *different* (usually newer) checkout -when you cut a version, that stale content gets captured into the -snapshot too. Before cutting a version that should be sparse (an early -tag that predates a guide folder, or a `previous-versions` signpost that -should hold only its own hand-written `index.mdx`), move anything the -current tag's own sync wouldn't produce out of the way first, cut, then -restore it afterward for Development's own benefit. Verify with a plain -`find _versioned_docs/version- -type f` before trusting the -cut — skipping this step is an easy way to leak a stale `docs`/`API` tree -into what should have been a two-file signpost. - -**Writing the `Previous versions` signpost.** It's a hand-authored -`index.mdx`, temporarily written over the live wrapper page (back it up -first), cut with `docs:version: previous-versions`, then -restored: - -```mdx ---- -title: C++ -sidebar_label: C++ ---- - -**Stable** currently tracks ``'s newest release, **vX.Y.Z**. - -We only host **Development (main)** and **Stable** here — older releases -aren't archived on this site. Browse their own tag in the source -repository instead: - -- **vA.B.C** — [browse source](https://github.com/robotiq//tree/vA.B.C) -``` - -**List only tags OLDER than the one Stable tracks — never re-list Stable's -own tag.** A tool with only one tag total has *nothing* to list here yet; -say so explicitly ("there are no older releases archived here yet") rather -than reusing another tool's list shape unchanged. "Exclude whatever Stable -tracks" is the actual rule, not "list every tag that isn't literally the -newest" — those only coincide once a tool has 2+ tags, so copying a -multi-tag tool's signpost as a template for a single-tag one silently -re-lists Stable's own tag as if it were archived separately. Check each -tool's actual tag count before authoring its signpost; don't assume the -same shape applies. - -**Make the Stable tag visible.** Nothing on a Stable page itself ever -prints which tag it is — without a visible marker, the only tag a visitor -ever sees named anywhere is whatever the `Previous versions` page lists, -which reads as "only 1 of N releases is on this site" even when Stable -silently *is* the newest one. Label it in `docusaurus.config.js`'s -`versions` config: - -```js -stable: { label: 'Stable (v2.0.0)', path: '' }, -``` - -Update this by hand every time Stable is re-cut to a newer tag. +`` is one of the ids registered in `scripts/versioned-tools.js` +(`tactile-cpp`, `tactile-python`, `adaptive-grippers-cpp`, ...). Cut +`stable` before `previous-versions` for a tool that needs both — the +`previous-versions` signpost excludes whichever tag `stable` currently +tracks, so that has to already be current. + +The script runs the whole procedure that used to be done by hand, in +order, and undoes every step's own side effects even if a later step +fails: + +- Finds the target tag off the submodule's remote + (`scripts/list-submodule-tags.js`, `git ls-remote --tags` — not the + local checkout, which can go stale) and checks it out. +- Re-syncs the tool's docs at that tag (`sync-external-docs.js`, with + `SKIP_SUBMODULE_RESET` so the checkout isn't immediately reverted). +- Clears any content and generated-sidebar cache left over from a + *different* checkout before syncing, so a tag that predates a guide + folder or a Doxyfile ends up genuinely sparse rather than inheriting + another checkout's leftovers (`scripts/lib/prune.js`'s + `pruneLegacyFolder`, plus wiping `scripts/generated/`). +- Prunes any `AUTO-GENERATED-*-TABLE` sub-page link that wouldn't + actually exist in this cut (`pruneDanglingSubpageLinks`). +- Rewrites the synced content's `tree/main/...` / `blob/main/...` + GitHub links (READMEs, guides, the wrapper page's own "Source Code" + button) to point at the tag instead (`rewriteMainLinksToTag`) — the + file at `main` can already differ from what shipped in the tag Stable + represents. +- Strips the "Use a released version" admonition that's real content on + Development but wrong once frozen into Stable itself + (`stripDevelopmentOnlyAdmonition`). +- For `previous-versions`, replaces the wrapper page with a generated + signpost (`buildSignpost`) listing every tag older than the one Stable + tracks, or saying so explicitly when there aren't any — the live + sub-pages are backed up first and restored after, since this cut must + hold only that one page. +- Runs `docs:version:` into a scratch version name first, then renames it + into place — `docusaurus.config.js`'s `lastVersion`/`versions` config + has to keep resolving to an existing version for the entire duration of + *any* `docusaurus` CLI invocation, including the cut itself, so + deleting-then-recutting the real name directly trips + `lastVersion: ... is invalid`. +- Restores the submodule's actual pinned commit and Development's own + synced content, regardless of whether the cut itself succeeded. +- Records the cut tag in `versioned-tools-stable.json` (for `stable`), + which `docusaurus.config.js` reads to build the `Stable (vX.Y.Z)` + switcher label — no by-hand label edit needed. +- Regenerates every versioned sidebar snapshot against the current live + site nav tree (`regenerate-versioned-sidebars.mjs`), so this cut (and + any earlier one) reflects the site's current navigation shape. + +Review the resulting diff and run a full `npm run build` before +committing — the script prints this reminder itself. Unit tests for its +pure helpers live in `test/cut-version.test.js`. ## Checklist: adding versioning to a new tool @@ -316,33 +278,60 @@ Assuming the tool already has its own wrapper page and a 2. Move the tool's existing content (its wrapper `index.mdx`, and any other hand-authored files) from `docs/drivers////` to `versioned-tools////`. -3. Add a new `@docusaurus/plugin-content-docs` entry to +3. Add a `:::tip Use a released version` admonition to that wrapper + `index.mdx` — see any existing versioned tool's wrapper page for the + exact text, and [API Stability Policy](/docs/api-stability). This page + is what becomes Development's own content once the plugin instance + below exists, so it needs the same "this documents unreleased `main`" + nudge every other versioned tool's wrapper page already has. If the + tool also gets a generated API reference (a `doxygen2docusaurus` job), + nothing extra is needed there — `injectExperimentalNotice` in + `sync-external-docs.js` already adds the matching notice to every page + that pipeline produces, for any tool. +4. Add a new `@docusaurus/plugin-content-docs` entry to `docusaurus.config.js`'s `plugins` array — copy `tactile-cpp`'s or `adaptive-grippers-cpp`'s as a starting point depending on whether the - tool is a single page or split into guides/API. -4. In `sidebars.js`, replace the tool's doc-id sidebar entry with a + tool is a single page or split into guides/API. See + [Which version the root URL serves](#which-version-the-root-url-serves) + above for the `versions` config shape once the tool has a tag (skip + `versions`/`lastVersion` entirely until then, matching `isaac-sim`). +5. In `sidebars.js`, replace the tool's doc-id sidebar entry with a `{ type: 'link', href: encodeURI('/docs/drivers///') }` item (see any existing versioned tool's entry there for the exact shape) — it no longer belongs to the default instance. -5. Create `sidebars..js`, calling +6. Create `sidebars..js`, calling `buildInstanceSidebar('', activeItem)` from `scripts/site-nav-tree.mjs` — `activeItem` is a single `{type: 'doc', id: 'index', label: ''}` for a one-page tool, or a nested category for a tool split into guides/API (see - `sidebars.adaptive-grippers-cpp.js`). -6. Add the tool's `versioned` node (`{ label, tool: '' }`) to + `sidebars.adaptive-grippers-cpp.js`). For a split tool, guard *every* + category whose `link` targets content that might not exist yet (a + `previous-versions` cut is a pure signpost with no `docs/`, and an + early tag can predate a guide folder or a Doxyfile) — check the real + file exists on disk before including that category at all, the same + way `sidebars.adaptive-grippers-cpp.js`'s `doxygenApiCategory` and + `guidesCategory` both do. Skipping this leaves a category whose `link` + points at a doc id that doesn't exist in that version at all, which + only Docusaurus's own build-time `checkSidebarsDocIds` catches — not + the cut itself, which reports success. +7. Add the tool's `versioned` node (`{ label, tool: '' }`) to `scripts/site-nav-tree.mjs`'s `SITE_TREE`, replacing whatever `leaf(...)` entry described it before, and add its path to `VERSIONED_TOOL_PATHS`. -7. If the tool already has a tag, cut `stable` (and `previous-versions`, - if it has 2+ tags) following [Cutting Stable or Previous versions by - hand](#cutting-stable-or-previous-versions-by-hand) above, and add the - matching `versions`/`lastVersion` config plus a +8. Register the tool in `scripts/versioned-tools.js` (submodule, repo URL, + sidebar key, `toolPath`) — `scripts/cut-version.js` needs this entry to + cut `stable`/`previous-versions` for it. +9. If the tool already has a tag, cut `stable` (and `previous-versions`, + if it has 2+ tags) following [Cutting Stable or Previous + versions](#cutting-stable-or-previous-versions) above, and add a `custom-scopedVersionDropdown` navbar item. If it has no tags yet, skip - this step entirely — leave `includeCurrentVersion: true` with no - `versions` config, matching `isaac-sim`, and come back to it once a tag - exists. -8. Run a full clean rebuild (`rm -rf .doxygen2docusaurus-staging build + this step entirely and come back to it once a tag exists. +10. Run a full clean rebuild (`rm -rf .doxygen2docusaurus-staging build .docusaurus scripts/generated node_modules/.cache && npm run build`) - and check the tool's `