Skip to main content
Version: Latest

Documentation Versioning Strategy

This page is the official governance policy for how the Developer Portal's Docusaurus versioning is configured and maintained. It exists because the portal's previous configuration caused a real, confirmed production incident: two fully-written, fully-published framework guides (WhatsApp Integration and the E-Invoicing Framework) were invisible on https://docs.shumoul.com even though they existed in the repository, were built successfully, and were deployed correctly by the CI pipeline.

Why the Previous Behavior Caused Confusion

Docusaurus's versioned-docs model treats the docs/ folder as the "current" (in-progress) version, and versioned_docs/version-X/ folders as frozen snapshots taken at release time. By default, whichever version is listed first in versions.json becomes the lastVersion — the one served at the site's bare /docs/... path, with no version prefix. Every other version, including current, gets its own path prefix (/docs/1.1/..., /docs/next/...).

This portal's versions.json was ["1.2", "1.1", "1.0"] with no lastVersion override, so version 1.2 was the implicit default served at the bare path, and the continuously-edited docs/ folder was pushed to /docs/next/..., labeled "Next," and decorated with Docusaurus's default banner: "This is unreleased documentation..."

That model is correct for projects that only add new documentation alongside a tagged software release. It is not how this platform's documentation actually gets written: new framework guides (Notification, Background Jobs, WhatsApp Integration, E-Invoicing) are authored and published straight into docs/ as each framework's discovery/architecture work completes, independent of when the portal itself last cut a version. WhatsApp Integration and E-Invoicing Framework were both completed and published into docs/ after version 1.2 was cut. Under the old configuration, that made them permanently invisible at the default URL until someone manually cut a new version — an easy step to forget, with no build error or broken link to signal it. Two Priority-0 investigations (a deployment-pipeline audit and a Git-history audit) were required before this was correctly diagnosed as a configuration problem rather than a broken build or a lost commit.

Why "Latest" Is Now Production

The portal's real editorial workflow is continuous publishing, not dated releases: docs/ is the production documentation, updated the moment a new or revised framework guide is ready, not held back for a version cut. Treating it as "unreleased" was a mismatch between the tool's default assumption and this platform's actual process, not a statement about content quality or reviewedness.

The fix, applied in docusaurus.config.js:

docs: {
lastVersion: 'current',
versions: {
current: {
label: 'Latest',
banner: 'none',
},
},
},
  • lastVersion: 'current' makes the docs/ folder the version served at the bare /docs/... path — the homepage, the Frameworks page, the sidebar, and search all resolve to it by default, with no /next/ segment required anywhere.
  • label: 'Latest' replaces the "Next" wording everywhere Docusaurus displays a version name (version dropdown, version badge), because "Next" reads as "not released yet," which is not true of this content.
  • banner: 'none' removes the "unreleased documentation" banner from every page under the default version, because it is not unreleased — it is the production documentation.

Version 1.2 (and 1.1, 1.0) automatically move to their own explicit paths (/docs/1.2/..., etc.) once they are no longer the lastVersion, and remain reachable from the version dropdown exactly as before — this is a routing change, not a content change. Nothing was deleted, moved, or duplicated to make this work.

When a Frozen Version Should Be Created

Cutting a new version (npm run docusaurus docs:version {n}) freezes the entire current state of docs/ into versioned_docs/version-{n}/. Do this only when there is a real reason to let readers pin to an exact historical snapshot — for example:

  • A major platform release where prior documentation genuinely no longer matches the shipped behavior, and some users are known to still be on the older release.
  • A compliance or contractual requirement to preserve exactly what a specific document said at a specific point in time.

Do not cut a version just because a framework reached Golden Reference certification, just because a security fix shipped, or on any fixed calendar cadence — "Latest" already carries that content continuously, and cutting a version has a real cost (see below).

Release Workflow

  1. Write or update the framework guide directly in docs/, following the existing chapter-file convention for that module (see the Notification Framework, Background Jobs Framework, WhatsApp Integration, or E-Invoicing Framework directories for the pattern).
  2. Run npm ci && npm run build locally and confirm zero errors, zero broken links (onBrokenLinks: 'throw' will fail the build on any bad internal link).
  3. Commit and push to main. The self-hosted runner's Deploy Docs workflow checks out that commit, builds, and mirrors the build output to the IIS folder — this part of the pipeline was independently audited and confirmed correct; it was never the source of the visibility problem this page documents.
  4. The new or updated content is live at the production URL immediately, with no separate "release" or "publish" step — publishing to docs/ is the release.

Archive Workflow

When a frozen version genuinely needs to be created:

  1. Confirm docs/ is in the exact state you want frozen — a version cut is a point-in-time copy, not a live mirror.
  2. Run npm run docusaurus docs:version {n} (e.g. 1.3). This creates versioned_docs/version-{n}/ and versioned_sidebars/version-{n}-sidebars.json, and prepends {n} to versions.json.
  3. Do not change lastVersion away from 'current' as part of this — the newly frozen version joins the archive list in the dropdown; docs/ (labeled "Latest") remains the default production experience.
  4. Verify the new archived version renders correctly at its own path (/docs/{n}/...) and that the default /docs/... path still resolves to the live docs/ content, unaffected.

Future Maintenance

  • Never re-introduce a lastVersion override that points at a frozen version number — that is exactly the configuration that caused this incident. lastVersion: 'current' is a permanent choice for this portal's workflow, not a temporary fix.
  • Never assume a new framework's documentation is visible on production just because it was committed — after this fix, it is, by construction (it lands in docs/, which is always what's served by default); but if a future contributor ever needs to reintroduce any form of version-gating, they must re-read this document first and understand why "current = production" was chosen deliberately.
  • When auditing "why isn't my documentation showing up," check docusaurus.config.js's lastVersion and versions config before suspecting the CI/deployment pipeline. This platform already spent two full investigation passes ruling out the pipeline before finding the actual cause here.
  • Historical versions are archival only. Do not edit versioned_docs/version-*/ content to "fix" anything found there after the fact — if a historical version's content was wrong at the time it was frozen, note that fact in Latest, not by silently editing the archive.