From 6fedc43821af3d9c834566fd2e11aff9e3b888bf Mon Sep 17 00:00:00 2001 From: Claude Code Date: Mon, 11 May 2026 12:33:16 -0700 Subject: [PATCH] chore(docs): refresh auto-gen before cut, delete empty versions.json on remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related fixes to make the version cut self-contained and to clean up after itself. 1. addVersion now runs `generate:smart` before snapshotting, so the versioned copy captures fresh database pages (from engine spec metadata), API reference (from openapi.json), and component pages (from Storybook stories) rather than whatever happened to be on disk. Added a --skip-generate flag for canonical release cuts where the operator has placed the `database-diagnostics` artifact from a green Python-Integration CI run at docs/src/data/databases.json and wants to preserve the full Flask-context diagnostics rather than regenerate locally. 2. removeVersion previously left an empty `
_versions.json` file (`[]`) on disk when removing the last version. Docusaurus would then snapshot that empty file back into content directories on the next cut. (This is how the orphan files this PR already cleans up — docs/components/versions.json and docs/developer_docs/versions.json — got accidentally tracked.) The remove path now deletes the file when it becomes empty. Documented the cut prerequisites in docs/README.md ("Before You Cut") and docs/DOCS_CLAUDE.md. --- docs/DOCS_CLAUDE.md | 5 ++++ docs/README.md | 21 ++++++++++++++- docs/scripts/manage-versions.mjs | 46 ++++++++++++++++++++++++++++---- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/docs/DOCS_CLAUDE.md b/docs/DOCS_CLAUDE.md index 6aae4a2b21d..3e60b73b0d3 100644 --- a/docs/DOCS_CLAUDE.md +++ b/docs/DOCS_CLAUDE.md @@ -47,6 +47,11 @@ yarn build # Build production site yarn serve # Serve built site locally # Version Management (USE THESE, NOT docusaurus commands) +# The add scripts auto-run `generate:smart` so auto-gen content (database +# pages, API reference, component pages) is fresh before snapshotting. +# For maximum-detail databases.json, drop the `database-diagnostics` +# artifact from Python-Integration CI at src/data/databases.json before +# cutting. See README.md "Before You Cut". yarn version:add:docs # Add new docs version yarn version:add:admin_docs # Add admin docs version yarn version:add:developer_docs # Add developer docs version diff --git a/docs/README.md b/docs/README.md index 3c7f268a288..f5b8e719445 100644 --- a/docs/README.md +++ b/docs/README.md @@ -37,9 +37,19 @@ Each section maintains its own version history and can be versioned independentl To create a new version for any section, use the Docusaurus version command with the appropriate plugin ID or use our automated scripts: +#### Before You Cut + +The cut snapshots whatever's on disk into a frozen historical version, including auto-generated content (database pages from `superset/db_engine_specs/`, API reference from `static/resources/openapi.json`, component pages from Storybook stories). The cut script refreshes these via `generate:smart` before snapshotting, but the **`databases.json` diagnostics file** needs special care to capture full detail: + +1. **Canonical release cut**: download the `database-diagnostics` artifact from a green `Python-Integration` run on master, place it at `docs/src/data/databases.json`, then run the cut script with `--skip-generate` to preserve it. This is what the production deploy uses and includes full Flask-context diagnostics (driver versions, feature support matrix, etc.). +2. **Local dev cut**: just run the script normally. `generate:smart` will regenerate `databases.json` using your local Flask environment — accurate to whatever drivers/extras you have installed, but typically less complete than the CI artifact. +3. **No Flask available**: also fine — the database generator falls back to AST parsing of engine spec files. The MDX pages are still correct; only the diagnostics JSON is leaner. + +Also: confirm `master` CI is green, and that your local checkout matches the SHA you intend to cut from. + #### Using Automated Scripts (Required) -**⚠️ Important:** Always use these custom commands instead of the native Docusaurus commands. These scripts ensure that both the Docusaurus versioning system AND the `versions-config.json` file are updated correctly. +**⚠️ Important:** Always use these custom commands instead of the native Docusaurus commands. These scripts ensure that both the Docusaurus versioning system AND the `versions-config.json` file are updated correctly, AND that auto-generated content is refreshed before snapshotting. ```bash # Main Documentation @@ -55,8 +65,17 @@ yarn version:add:developer_docs 1.2.0 yarn version:add:components 1.2.0 ``` +What the script does: +1. Refreshes auto-generated content via `generate:smart` (database pages, API reference, component pages). +2. Calls `yarn docusaurus docs:version` (or the per-section equivalent) to snapshot the section. +3. Freezes any data-file imports (`@site/static/*.json`, `../../data/*.json`) into a snapshot-local `_versioned_data/` dir so the historical version doesn't silently mutate when the source files change. +4. Adjusts relative import paths (`../../src/...` → `../../../src/...`) for files now one directory deeper. +5. Updates `versions-config.json` and `
_versions.json`. + **Do NOT use** the native Docusaurus commands directly (`yarn docusaurus docs:version`), as they will: - ❌ Create version files but NOT update `versions-config.json` +- ❌ Skip auto-gen refresh, freezing whatever was on disk +- ❌ Skip data-import freezing, leaving the snapshot pointed at live data - ❌ Cause versions to not appear in dropdown menus - ❌ Require manual fixes to synchronize the configuration diff --git a/docs/scripts/manage-versions.mjs b/docs/scripts/manage-versions.mjs index 1ba79fdb4cf..163e200c64d 100644 --- a/docs/scripts/manage-versions.mjs +++ b/docs/scripts/manage-versions.mjs @@ -30,7 +30,9 @@ const __dirname = path.dirname(__filename); const CONFIG_FILE = path.join(__dirname, '..', 'versions-config.json'); // Parse command line arguments -const args = process.argv.slice(2); +const rawArgs = process.argv.slice(2); +const skipGenerate = rawArgs.includes('--skip-generate'); +const args = rawArgs.filter((a) => a !== '--skip-generate'); const command = args[0]; // 'add' or 'remove' const section = args[1]; // 'docs', 'developer_docs', or 'components' const version = args[2]; // version string like '1.2.0' @@ -213,6 +215,28 @@ function addVersion(section, version) { console.log(`Creating version ${version} for ${section}...`); + // Refresh auto-generated content (database pages, API reference, + // component playground) so the snapshot captures the current state of + // master rather than whatever happened to be on disk. `generate:smart` + // hashes its inputs and skips unchanged generators, so this is cheap + // when the dev already has fresh output. + // + // Use --skip-generate if you've placed a CI-artifact databases.json + // (the `database-diagnostics` artifact from Python-Integration) and + // want to preserve it instead of letting the local env regenerate it. + // See docs/README.md "Before You Cut" for the canonical release flow. + if (skipGenerate) { + console.log(` Skipping auto-gen refresh (--skip-generate set)`); + } else { + console.log(` Refreshing auto-generated docs...`); + try { + execSync('yarn run generate:smart', { stdio: 'inherit' }); + } catch (error) { + console.error(`Failed to refresh auto-generated docs: ${error.message}`); + process.exit(1); + } + } + // Run Docusaurus version command const docusaurusCommand = section === 'docs' ? `yarn docusaurus docs:version ${version}` @@ -309,8 +333,17 @@ function removeVersion(section, version) { const versionIndex = versions.indexOf(version); if (versionIndex > -1) { versions.splice(versionIndex, 1); - fs.writeFileSync(versionsJsonPath, JSON.stringify(versions, null, 2) + '\n'); - console.log(` Updated ${versionsJsonFile}`); + if (versions.length === 0) { + // Sections with no versions shouldn't carry an empty versions file + // on disk — Docusaurus doesn't require it, and an empty `[]` file + // gets picked up by `docusaurus version` and snapshotted into the + // next cut. + fs.unlinkSync(versionsJsonPath); + console.log(` Removed empty ${versionsJsonFile}`); + } else { + fs.writeFileSync(versionsJsonPath, JSON.stringify(versions, null, 2) + '\n'); + console.log(` Updated ${versionsJsonFile}`); + } } } @@ -335,12 +368,15 @@ function removeVersion(section, version) { function printUsage() { console.log(` Usage: - node scripts/manage-versions.js add
+ node scripts/manage-versions.js add
[--skip-generate] node scripts/manage-versions.js remove
Where: - - section: 'docs', 'developer_docs', or 'components' + - section: 'docs', 'developer_docs', 'admin_docs', or 'components' - version: version string (e.g., '1.2.0', '2.0.0') + - --skip-generate: skip refreshing auto-generated docs before snapshotting + (use when you've already placed a fresh databases.json + from CI and want to preserve it) Examples: node scripts/manage-versions.js add docs 2.0.0