Repository navigation
feat(docs): publish versioned Fern docs for releases #1296
Copy link
Copy link
Closed
Labels
area:buildRelated to CI/CD and buildsRelated to CI/CD and buildsarea:docsDocumentation and examplesDocumentation and examplesstate:acceptedA maintainer decided OpenShell should pursue this issueA maintainer decided OpenShell should pursue this issuestate:in-progressWork is currently in progressWork is currently in progress
Description
Problem Statement
OpenShell docs are currently published through Fern with a single latest version. That makes older release behavior hard to inspect after breaking changes land, because users following an older installed OpenShell version only see the newest docs at docs.nvidia.com/openshell/latest/....
This mattered during the v0.0.37 gateway lifecycle break: users needed docs that matched v0.0.36 behavior while the current docs described the new package-managed gateway model.
Proposed Design
Publish Fern documentation as versioned docs for each tagged OpenShell release.
Expected user-facing behavior:
https://docs.nvidia.com/openshell/latest/...continues to point at the current release or current published default.- Each release gets a stable Fern docs version, for example
https://docs.nvidia.com/openshell/v0.0.37/.... - The Fern version selector lists
Latestplus recent tagged releases. - Release notes and installation pages can link directly to the docs version that matches the release being described.
Implementation shape:
- Extend
fern/docs.ymlbeyond the current singleLatestentry underversions:so release-specific slugs can be published. - Update
.github/workflows/release-tag.ymlpublish-fern-docsto publish a release-specific docs version when a tag is released, using the release tag as the Fern slug/display name. - Preserve existing
/openshell/latest/...redirects and canonical links. - Decide whether version entries are generated during release publish or maintained through a committed versions manifest that Fern consumes.
- Add a small docs/publish note explaining how a release docs version is created and how to preview it.
Alternatives Considered
- Keep only
latestand rely on GitHub release notes for historical behavior. This is too thin for breaking changes because users need full installation, CLI, and Kubernetes docs for their installed version. - Link users to raw docs in GitHub tags. That preserves history but loses the Fern navigation, search, styling, and version selector.
- Maintain separate static docs sites per release manually. This would work, but it creates avoidable release overhead and drift; Fern's versioning support should own this.
Agent Investigation
- Loaded the
create-github-issueskill and followed the feature request template. - Checked for duplicates with
gh issue list --repo NVIDIA/OpenShell --search "fern docs versioned release documentation" --state all --limit 20; no matching issues were returned. - Inspected
fern/docs.yml; it currently has only:display-name: Latestpath: ../docs/index.ymlslug: latest
- Inspected
.github/workflows/release-tag.yml; thepublish-fern-docsjob checks out the release tag and runsfern generate --docs, but does not create or publish a release-specific Fern version.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:buildRelated to CI/CD and buildsRelated to CI/CD and buildsarea:docsDocumentation and examplesDocumentation and examplesstate:acceptedA maintainer decided OpenShell should pursue this issueA maintainer decided OpenShell should pursue this issuestate:in-progressWork is currently in progressWork is currently in progress
Activity
pimlock commentedon May 26, 2026
I propose we use a CI-managed
docs-websitebranch, similar to Dynamo (with some others new pages following this pattern as well).High-level model:
mainremains the source of truth for authored docs indocs/and Fern config infern/.docs-websitestores the generated Fern publish layout and frozen version snapshots.latestis a stable URL alias for one concrete release snapshot, not its own mutable docs copy.devtracks docs frommain, aligned with the dev release stream.For example, after publishing the current release and one historical version, the generated branch would contain:
The published URLs would behave like:
/openshell/latest/...-> same content as/openshell/v0.0.48/.../openshell/dev/...-> current docs frommain/openshell/v0.0.36/...-> frozen historical docs from before the gateway lifecycle refactorAlternatives considered, roughly best to worst:
Separate docs repository.
This gives the cleanest separation between source code and accumulated docs snapshots, but code and docs changes would land in separate repos, release automation would need cross-repo credentials, and it would be harder to keep a release tag, docs snapshot, and publish status atomic.
Publish all versions from
main.This keeps automation simple, but every old docs snapshot would live on
main, bloating the branch, adding irrelevant search/grep hits, and increasing the chance that normal docs edits accidentally touch frozen versions.Regenerate historical versions from tags on every publish.
This avoids storing generated snapshots, but publishes become slower and less deterministic. Old tags may fail under newer tooling or Fern config, and it becomes harder to curate exactly which old versions we keep.
Link users to docs in GitHub tags.
This preserves history with no new automation, but users lose Fern navigation, search, styling, redirects, version selector, and canonical docs URLs.
Publish a separate static docs site per release.
This isolates versions, but creates the most operational overhead, increases config drift, and makes navigation between versions worse than Fern's built-in version selector.
Recommended next step if this direction sounds right:
Run a spike that creates the
docs-websitebranch and proves the branch layout with three versions:devfrommainlatestpointing atv0.0.48v0.0.36as a historical snapshot from before the gateway lifecycle refactorThe spike should validate that Fern accepts the generated layout, that
/latest,/dev, and/v0.0.36resolve correctly, and that PR previews remain unchanged.References:
moezdil commentedon May 26, 2026
thx for the detailed writeup @pimlock,
the docs-website branch model makes sense.
a few things i want to make sure we have covered before the spike:
nr1) url behavior for latest: fern docs say the first version in the list gets unversioned paths (e.g. /getting-started not /latest/getting-started). how do we preserve the existing /openshell/latest/... URLs?
nr2) fern plan limits: fern caps versions at 3 (hobby), 10 (team), or unlimited (enterprise). worth confirming which plan we're on before deciding how many versions to keep.
nr3) ci workflow: the branch layout is clear but the automation is not. when a release tag is pushed, what updates docs-website? and does dev update on every merge to main?
nr4) snapshot drift: frozen version files in docs-website may break over time if the fern cli or config changes. is there a plan for that?
pimlock commentedon Jun 5, 2026
Replying to @mesutoezdil's checklist in #1296 (comment):
Thanks, these are exactly the right failure modes to cover. Here is how I think the spike/first automation pass should handle each one:
latestURL behavior: keeplatestas an explicit generated version/alias indocs-website, and keep redirects for/openshell/latest/.... In the first pass,latestis a moving release alias, not a dedicated historical version route like/openshell/v0.0.57/....Fern plan limits: confirmed we are good.
CI workflow: add a dedicated
sync-docsworkflow that updates one docs snapshot from a source ref. Manual first; laterrelease-devcan dispatchdevwith the built commit SHA, andrelease-tagcan dispatchlatestwith the release tag/SHA.Snapshot drift: store snapshots intentionally on
docs-websiteso old versions are not regenerated unless explicitly requested. Every sync/publish path should run Fern validation before publishing, and historical versions should only be touched when the workflow is asked to sync that slug.pimlock commentedon Jun 5, 2026
Docs website automation follow-up
Proposed first automation pass:
docs-websiteas the generated-only branch containing Fern config, shared assets/components, and frozenpages-{slug}snapshots.sync-docs.yml, manual first, with inputs forchannel,source_ref, optionalversion_slug, and optionaldisplay_name.sync-docs.ymlchecks out the requested source ref, checks outdocs-website, copies only the requested docs snapshot intofern/pages-{slug}/, regeneratesfern/versions/{slug}.yml, updates the version entry infern/docs.yml, validates, and commits only when there is a diff.concurrency.group: docs-website,cancel-in-progress: false, so only one sync/publish operation mutates or publishes at a time.publish-docs-website.yml, also manual first. It checks outdocs-website, runsfern check, and defaults to a Fern preview. Production publish requires explicitly selecting production mode.Once the manual path proves stable, the next step is wiring release automation:
release-devdispatchessync-docs.ymlwithchannel=devand the commit SHA that was built.release-tagdispatchessync-docs.ymlwithchannel=latestand the release tag/SHA.github-actions commentedon Aug 30, 2026
This issue has had no activity for 14 days and is now marked stale. It may be closed in 7 days if there is no further activity. Comment or remove the state:stale label to keep it open.