Release
TopoViewer is licensed under Apache-2.0. The monorepo root is marked private to prevent accidental workspace publication. The packages/topoviewer package is publish-shaped so release candidates can be inspected with npm pack --dry-run and published intentionally to an approved npm registry.
The release goal is package quality and intentional distribution: the core renderer should remain installable, testable, embeddable, and generic, with private/customer-specific material kept out of the public packages.
Local Validation
npm ci
npm run docs:screenshots
npm run docs:screenshots:check
npm run sync:content
npm run sync:docs
npm run validate:schemas
npm run validate:semantics
npm run api:check
npm run build
npm test
npm run package:contract
npm run studio:packed-core:check
npm run studio:benchmark:bundle
npm run pack:check
npm run sync:mkdocs-assets
npm run wheel:mkdocs
npm run inspect:wheel
mkdocs build --strict
The gate captures every raster screenshot used by the documentation, builds the library and embed bundle, validates YAML schemas, runs semantic lint, runs Playwright tests against Studio and the MkDocs embed behavior, inspects npm package contents, builds the MkDocs plugin wheel, and builds the documentation site in strict mode.
Run npm run docs:screenshots only after setting the final release version. It
rebuilds Studio, MkDocs, Zensical, and the Grafana panel; starts an isolated,
pinned Grafana container; captures every surface from the canonical st-clos
bundle; generates the promotional collage; and verifies the result. Docker must
be running, but no manually supplied screenshot is accepted.
The generated docs/assets/readme/manifest.json binds all documentation raster
assets to the release version, canonical source hashes, deterministic capture
scenarios, dimensions, surfaces, and image digests. npm run ci:generated
rejects missing or unowned documentation images. The npm and PyPI publish
workflows additionally run npm run release:screenshots:verify; publication is
blocked when manifest provenance changes or regenerated media exceeds the
reviewed visual-diff budget. The comparison allows bounded operating-system
font rasterization differences while still rejecting meaningful pixel drift,
and the workflow uploads failed captures for review.
npm run pack:check runs npm pack --dry-run. Confirm the tarball includes:
dist/topoviewer.mjsdist/topoviewer.cjsdist/authoring.mjsanddist/authoring.cjsdist/export.mjsanddist/export.cjsdist/integration.mjsanddist/integration.cjsdist/security.mjsanddist/security.cjsdist/topoviewer.css- matching
dist/types/*.d.mtsanddist/types/*.d.ctsdeclarations dist/embed/topoviewer-embed.iife.jsdist/embed/topoviewer-embed.cssschemas/topoviewer.schema.jsonschemas/topoviewer-topology.schema.jsonschemas/topoviewer-stylesheet.schema.jsonschemas/topoviewer-mkdocs-block.schema.jsonschemas/topoviewer-examples-catalog.schema.jsonschemas/topoviewer-examples-manifest.schema.jsonschemas/topoviewer-test-expected.schema.jsonREADME.mdLICENSEpackage.json
The npm tarball deliberately excludes documentation pages and example source.
npm run package:contract also runs publint, Are The Types Wrong, packed ESM
and CommonJS consumers, SSR import, CSS/schema resolution, tree-shaking, and
artifact size/file-count checks. npm run studio:packed-core:check proves the
largest repository-owned application consumes only published entries.
Dependency Boundary
Runtime dependencies should stay small:
d3-forcehtml-to-imagejspdfzod
Peer dependencies:
reactreact-dom@xyflow/react
The workbench dependencies, including MUI and Monaco, must remain development dependencies. Do not export TopoViewerWorkbench from src/index.ts; that would pull the demo/editor stack into the public library bundle.
MkDocs Asset Validation
When the embed bundle changes:
npm run build
npm run sync:mkdocs
Then validate the MkDocs site from your MkDocs validation workspace. For example, if a validation site is checked out next to this repository and its Makefile builds a wheel from the local mkdocs-topoviewer package:
cd ../my-mkdocs-site
make docs MKDOCS_BUILD_FLAGS=--clean
Run the root Playwright MkDocs embed test if the local server is available:
npx playwright test tests/mkdocs-embed.spec.js
Release Channels
Do not publish directly from this development workspace.
Before any external distribution:
- Confirm the channel: public release, internal preview, or customer-specific private package.
- Confirm package ownership, final npm package name, repository URL, issue tracker, and support channel.
- Keep the public package generic. Do not mix customer-owned diagrams, proprietary icon sets, credentials, or lab-only data into the package.
- Use
TopoViewerExtensionpackages for private customer integrations, custom node/edge types, importers, policy checks, or enterprise-only workflows. - Bump
versionaccording to semver. - Run
npm run test:all. - Run
npm run pack:checkand inspect tarball contents. - Publish only to the approved channel.
Recommended future distribution shape:
topoviewer: public generic React renderer, schemas, compiler, and embed bundle.mkdocs-topoviewer: public Python MkDocs wrapper that vendors the approved browser bundle.- Internal preview packages or a private registry equivalent: pre-release validation builds.
- Private customer packages: customer-owned templates, proprietary icon libraries, policy checks, and deployment-specific import/export workflows.
Do not publish generated test artifacts, local videos, screenshots, or MkDocs build output.
Desktop Release Candidates
Desktop Studio is not an npm package. The manual
Desktop release candidates workflow builds native artifacts on their target
runners:
| Target | Artifact rule |
|---|---|
| Linux amd64 | Build and smoke-test on Ubuntu with GTK 3 and WebKitGTK 4.1; document the required runtime ABI. |
| Windows amd64 | Build the executable and user-scoped NSIS installer; sign every executable before public distribution. |
| macOS arm64 and amd64 | Build both application bundles, combine the native executable into one universal bundle, sign, notarize, staple, and assess it. |
Run the local native gate on the current platform first:
npm run desktop:prerequisites
npm run desktop:check
npm run desktop:test:golden
npm run desktop:smoke
Trigger the workflow with the exact repository version and sign: false for
internal validation. Those outputs must retain the internal-unsigned status
and must not be attached to a public release. Use sign: true only through the
protected desktop-release environment with configured Apple and Windows
credentials.
Review the generated artifact manifest for version, operating system, architecture, Wails version, byte size, checksum, and support status. Desktop promotion requires repeated green evidence on all four native runners. A Linux success does not prove Windows or macOS packaging, and one platform artifact must never be presented as a cross-platform executable.
Manual npm Publishing
The public npm package name is topoviewer. The 0.x line is installable
early-adopter software: useful, documented, and CI-gated, but not an API-freeze
claim. Reserve 1.0.0 for the later stable-core release.
The public npm install snippet is:
npm install topoviewer @xyflow/react react react-dom
For local release preflight, maintainers can validate the source tarball workflow. Replace the filename with the version under review:
npm --workspace topoviewer pack --pack-destination /tmp/topoviewer-pack
npm install /tmp/topoviewer-pack/topoviewer-<version>.tgz @xyflow/react react react-dom
npm run install:check validates documented install commands.
npm run package:contract owns the deeper packed npm contract, including ESM,
CommonJS, declarations, CSS, schemas, SSR, and artifact budgets.
Normal pushes, pull requests, docs deployments, and scheduled workflows must not
publish to npm. Publication is manual through the Manual npm Publish GitHub
Actions workflow, authenticated by npm Trusted Publishing with GitHub OIDC.
- Choose the exact version already committed in
packages/topoviewer/package.json. - Choose the dist-tag. Prefer
nextfor early-adopter0.xvalidation unless maintainers deliberately wantlatestwith clear pre-1.0 wording. Reservelatestwithout caveats for the stable-core1.0.0release. - Keep
dry_runenabled for the first run and review the npm publish output. - Confirm
npm run ci,npm run install:check,npm run api:check,npm run artifact:check:package, andnpm run dependency:advisoriespass. - Confirm the release note or changelog entry exists and describes support status, known limitations, and upgrade notes.
- Confirm package ownership, npm organization/user access, and maintainer approval.
- Confirm npm Trusted Publishing is configured for the package with:
- provider: GitHub Actions;
- owner/repository:
asadarafat/topoviewer; - workflow filename:
npm-publish.yml; - environment:
npm-publish; - allowed action:
npm publish. - Confirm the workflow has GitHub
id-token: write, runs on a GitHub-hosted runner, and uses npm>=11.5.1. The workflow must not referenceNPM_TOKEN,NODE_AUTH_TOKEN, or repository secrets for publishing. Trusted Publishing generates provenance automatically. - Run the workflow with
dry_run: falseonly after the dry-run artifact and validation logs are reviewed.
When the requested version is already published, npm rejects
npm publish --dry-run because package versions are immutable even in dry-run
mode. In that case the workflow still runs all release gates, verifies the
registry state, and uses npm pack --dry-run for artifact validation. A real
publish for an already-published version fails before upload and requires a
version bump.
Maintainers can create or verify the npm-side trust relationship from npmjs.com or with the npm CLI:
npm trust github topoviewer \
--repo asadarafat/topoviewer \
--file npm-publish.yml \
--env npm-publish \
--allow-publish
Manual PyPI Publishing
The public MkDocs package name is mkdocs-topoviewer. It is separate from the
npm package:
| Surface | Package | Release workflow |
|---|---|---|
| React/browser renderer | topoviewer on npm |
npm-publish.yml |
| MkDocs plugin | mkdocs-topoviewer on PyPI |
pypi-publish.yml |
The Python import module is mkdocs_topoviewer, and the MkDocs plugin key is
topoviewer.
Normal pushes, pull requests, docs deployments, and scheduled workflows must not
publish to PyPI. Publication is manual through the Manual PyPI Publish GitHub
Actions workflow, authenticated by PyPI Trusted Publishing with GitHub OIDC.
Before a real PyPI publish:
- Choose the exact version already committed in
packages/mkdocs-topoviewer/pyproject.toml. - Run the workflow with
dry_run: trueand review the built wheel and sdist. - Confirm the PyPI trusted publisher is configured for:
- project:
mkdocs-topoviewer; - owner/repository:
asadarafat/topoviewer; - workflow filename:
pypi-publish.yml; - environment:
pypi-publish. - Confirm the workflow has GitHub
id-token: writeand does not referencePYPI_TOKENor repository secrets for publishing. - Run the workflow with
dry_run: falseonly after the dry-run artifact and validation logs are reviewed. - Verify the published package from a clean environment:
pip install mkdocs-topoviewer
npm run install:check:mkdocs
PyPI package versions are immutable. A real publish for an already-published version fails before upload and requires a version bump.
0.5.0 Minor Release Plan
0.5.0 is a pre-1.0 logical-renderer, YAML-first authoring, and desktop-host
release after 0.4.0. It adds public core capabilities without removing the
canonical 0.2 YAML contract, and it keeps native desktop artifacts explicitly
Experimental until signed distribution is proven.
In Scope
- Publish resilient compile/render diagnostics, typed TVDS themes, normalized status helpers, shared viewport reducers, interaction presets, and the deterministic tree layout through the supported core package.
- Ship the YAML-first Browser Studio workbench with one Monaco source owner, Source/Split/Preview layouts, contextual visual authoring, and preserved recovery, mapper, export, and host contracts.
- Validate the Experimental Wails Desktop Studio host across Linux amd64, Windows amd64, macOS arm64, and macOS amd64 without presenting unsigned candidates as public installers.
- Remove the unpublished experimental VS Code host and keep Browser and Desktop Studio on one shared application and typed host boundary.
- Regenerate every release-owned documentation image from the final
0.5.0candidate and canonicalst-clossource bundle.
Compatibility Gate
- No public YAML field or package export is removed. Tree layout and all new runtime helpers are additive.
compileTopoGraphremains throwing;compileTopoGraphResultis the additive recoverable contract.- Dark mode remains the default. Typed light/system themes affect renderer chrome, while authored stylesheet rules remain graph-appearance owners.
- Browser Studio remains Beta Preview. Desktop Studio and Grafana remain Experimental, and unsigned desktop artifacts remain internal.
Sequential Release Gate
Complete each step against one unchanged candidate before starting the next.
- Set every release-owned JavaScript and Python package, internal workspace
dependency, Wails product version, and lockfile to
0.5.0; finalize the dated changelog and compatibility notes. - Synchronize canonical content and generated docs, regenerate all release screenshots, and review the manifest, source hashes, and six raster assets.
- Run the full local CI and release-specific package, installation, security, screenshot, wheel, strict-documentation, and current-platform desktop gates.
- Commit and push the verified candidate, then require every remote check on that exact commit to pass.
- Run the unsigned Desktop release-candidate workflow for
0.5.0and require Linux amd64, Windows amd64, macOS arm64, and macOS amd64 jobs to pass. - Run npm and PyPI manual workflows with
dry_run: trueand version0.5.0; inspect package contents, provenance inputs, and generated media evidence. - Publish npm with dist-tag
latestand publish PyPI from the unchanged candidate. Verify both packages from clean consumers. - Create and push annotated tag
v0.5.0, create the matching GitHub release, and verify Pages, Studio, MkDocs, Zensical, release media, and registry state.
If a published artifact is defective, deprecate it and prepare 0.5.1; do not
unpublish or mutate version 0.5.0.
0.4.0 Minor Release Plan
0.4.0 is a pre-1.0 compatibility and architecture release after 0.3.2.
It enforces one persistent owner for visual policy, publishes explicit package
entries for modern and CommonJS consumers, and hardens the boundary between the
core renderer and Studio.
In Scope
- Enforce canonical
0.2topology/stylesheet ownership and document the deterministic migration path for legacy names and inline appearance. - Publish explicit ESM and CommonJS artifacts and declarations for every public
entry, including the new
topoviewer/exportentry. - Prove packed consumers under Node.js 22.12, 24, and 26 and React 18.3 and 19.2.
- Keep Studio on public core package entries, narrow feature capabilities, lazy optional workspaces, and ratcheted interaction and bundle budgets.
- Regenerate every release-owned documentation image from the final
0.4.0candidate and canonicalst-clossource bundle.
Migration Gate
Canonical 0.2 topology objects reject generic name, generic label, inline
style, object-level icon, and other persistent appearance fields. Before
publishing, verify that release notes point users of unversioned or 0.1
sources to:
npm run migrate:identity -- --write path/to/topology.yaml
The migration must move appearance to exact-ID stylesheet rules, preserve references, and stop on conflicting aliases instead of choosing silently.
Sequential Release Gate
Complete each step against one unchanged candidate before starting the next.
- Set every release-owned JavaScript and Python package to
0.4.0, update internal workspace dependencies and the lockfile, and finalize the dated changelog entry. - Synchronize canonical content and generated docs, regenerate all release screenshots, and review the manifest, source hashes, and six raster assets.
- Run the full local CI and release-specific package, installation, security, screenshot, wheel, and strict documentation gates.
- Commit and push the verified candidate, then require all remote checks on that exact commit to pass.
- Run npm and PyPI manual workflows with
dry_run: trueand version0.4.0; inspect their package contents and provenance inputs. - Publish npm with dist-tag
latestand publish PyPI from the unchanged candidate. Verify both packages from clean consumers. - Create and push annotated tag
v0.4.0, create the matching GitHub release, and verify Pages, Studio, MkDocs, Zensical, and release-owned images.
If a published artifact is defective, deprecate it and prepare 0.4.1; do not
unpublish or mutate version 0.4.0.
0.3.2 Patch Release Plan
0.3.2 is a focused authoring-hardening patch after the published 0.3.1
line. It adds portable SVG icon authoring, fixes hidden-label and controlled
selection regressions, and establishes the Browser Studio Beta Preview release
gates. It must not add a deliberate breaking change to the supported renderer
API or YAML schemas.
In Scope
- Add trusted built-in SVG icons to Studio's visual authoring workflow while keeping generated stylesheet bundles portable across renderer surfaces.
- Preserve explicit hidden labels, accessible canonical identity, and native React Flow selection across controlled runtime rebuilds.
- Prevent delayed preference hydration from overwriting an immediate viewport interaction.
- Define and enforce the Browser Studio Beta Preview support boundary with production-build, deployed-route, and bounded performance checks.
- Regenerate and verify all release-owned documentation screenshots against the
final
0.3.2version and canonical source hashes.
The patch does not promote Grafana from Experimental, introduce a new integration surface, or expand the supported YAML contract. Unrelated feature work belongs in a later minor release.
Before And After Evidence
| Measure | 0.3.1 baseline |
0.3.2 release requirement |
|---|---|---|
| Icon authoring | Studio exposed only the earlier limited icon path. | Built-in trusted SVG icons can be selected visually, recolored safely, serialized, and rendered from the exported stylesheet. |
| Hidden labels | An explicit empty alias fell back to the canonical ID visually. | Empty labels.name hides the visual label while the accessible name retains canonical identity. |
| Controlled selection | Runtime rebuilds could clear React Flow selection. | Unit and browser tests prove keyboard and pointer selection survive controlled rebuilds. |
| Preference hydration | Delayed stored settings could overwrite the first viewport interaction. | Hydration applies only before a user changes the corresponding preference. |
| Studio support evidence | Browser Studio was described only as Experimental. | Beta Preview scope is explicit and production-build, deployed-route, accessibility, and performance gates pass. |
| Documentation media | The manifest identifies 0.3.1. |
All catalog-owned images and manifest provenance are regenerated for 0.3.2. |
Sequential Release Gate
Complete each step and retain its evidence before starting the next one.
- Freeze scope. Review the diff against
v0.3.0; remove unrelated feature work or move it to a later release. Runnpm run api:check,npm run validate:schemas, andnpm run validate:semanticsto prove the supported contracts remain compatible. - Set one version. Change the root, core, Studio, Grafana, MkDocs, and
lockfile versions to
0.3.2. Confirm no release-owned package remains on0.3.1, and finalize the dated0.3.2changelog entry before generating artifacts. - Regenerate projections. Run
npm run sync:content,npm run sync:docs, andnpm run docs:screenshots. Review all six images at authored resolution and commit the manifest and generated media with their canonical sources. - Prove reproducibility. From that clean committed tree, run
npm run release:screenshots:verify. The command must preserve manifest semantics and keep every regenerated image within the reviewed visual-diff budget. Docker must be available for the pinned Grafana capture. - Pass local release gates. Run
npm ci,npm run ci,npm run install:check,npm run api:check,npm run artifact:check:package,npm run dependency:advisories,npm run dist:mkdocs, andnpm run inspect:mkdocs. Record command results against the exact candidate commit. - Pass remote dry runs. Run the manual npm and PyPI Trusted Publishing
workflows with version
0.3.2anddry_run: true. Review package contents, provenance inputs, generated screenshot evidence, and uploaded drift artifacts before approving publication. - Publish and verify packages. Publish npm and PyPI from the unchanged
candidate commit. Verify
topoviewer@0.3.2andmkdocs-topoviewer==0.3.2from clean consumers; do not tag the release while either verification is outstanding. - Close the release. Create
v0.3.2and the GitHub release, deploy Pages, and verify the Studio route, legacy compatibility redirect, MkDocs and Zensical embeds, and all published documentation images. Confirm the GitHub release notes match the dated changelog entry on the tagged commit.
If a published artifact is defective, deprecate it and prepare 0.3.3; do not
unpublish or mutate an existing package version.
0.3.0 Early-Adopter Gate
topoviewer@0.3.0 must not be published until these gates are satisfied:
- The package builds, type output, CSS, schemas, examples, and README are
present in
npm pack --dry-runoutput. npm run ci,npm run install:check,npm run api:check,npm run artifact:check:package, andnpm run dependency:advisoriespass.npm run dist:mkdocsandnpm run inspect:mkdocspass whenmkdocs-topoviewer==0.3.0is part of the release train.- The changelog has a
0.3.0entry with support status, notable changes, known limitations, and migration notes. npm run docs:screenshotshas captured every documentation surface from the final build andnpm run docs:screenshots:checkpasses for version0.3.0.- TopoViewer Studio remains labeled Experimental and is not represented as a separately published npm package.
- The npm and PyPI Trusted Publishing dry-run workflows pass against the exact commit selected for publication.
- The published npm and PyPI versions are verified from clean consumers before
the GitHub release and
v0.3.0tag are created.
0.2.0 Early-Adopter Gate
topoviewer@0.2.0 must not be published until these gates are satisfied:
- The package builds, type output, CSS, schemas, examples, and README are
present in
npm pack --dry-runoutput. npm run ci,npm run install:check,npm run api:check,npm run artifact:check:package, andnpm run dependency:advisoriespass.npm run wheel:mkdocsandnpm run inspect:wheelpass whenmkdocs-topoviewer==0.2.0is part of the release train.- The changelog has a
0.2.0entry with support status, notable changes, known limitations, and migration notes. - The README and docs keep React, MkDocs, TopoViewer Studio, Zensical, Grafana, NetBox, and Infrahub support status accurate.
- Experimental integrations remain clearly labeled and do not expand the package compatibility promise.
- The npm and PyPI Trusted Publishing dry-run workflows are reviewed before any real publish.
0.1.0 Early-Adopter Gate
topoviewer@0.1.0 was published only after these gates were satisfied:
- The package builds, type output, CSS, schemas, examples, and README are
present in
npm pack --dry-runoutput. npm run ci,npm run install:check,npm run api:check,npm run artifact:check:package, andnpm run dependency:advisoriespass.- The changelog has a
0.1.0entry with support status, known limitations, and migration notes. - The README first run no longer points users at a missing npm package after the package is published.
- The README and docs clearly state that this is pre-1.0 early-adopter software and that APIs may change with migration notes.
- Experimental integrations remain clearly labeled and do not expand the package compatibility promise.
1.0.0 Stable-Core Gate
Do not publish topoviewer@1.0.0 until these are true:
TopoViewer, documented React props/events, validation/lint helpers, topology schemas, stylesheet schemas, style keys, curated examples, and the MkDocs embed path are treated as Supported.- The public API report is intentionally frozen enough for SemVer.
- Compatibility fixtures cover previously documented public YAML.
- The changelog has a
1.0.0entry with support status, known limitations, and migration notes from0.x. - Experimental integrations remain clearly labeled and do not expand the stable-core SemVer promise.
Rollback and deprecation expectations:
- Prefer publishing a fixed patch version over unpublishing.
- If a bad version is already public, deprecate it with a clear message and publish a replacement version.
- Move a dist-tag only after the replacement artifact has passed the same gates.
- Record first-install feedback with the package release feedback issue template.
Grafana Plugin Artifact Gate
The Grafana panel is Experimental. Local labs may load unsigned plugin builds, but an installable shared artifact needs a separate review before distribution:
- Build the plugin from a committed version.
- Record the exact Grafana version or version range validated for the artifact.
- Generate SHA-256 checksums for the plugin zip and backend binaries.
- Generate an SBOM or equivalent dependency inventory.
- Run
npm run grafana:panel:test,npm run grafana:panel:build, and the relevant Grafana smoke for the intended source mode. - Document whether the artifact is unsigned or signed. Unsigned artifacts are local/lab-only unless the receiving Grafana instance has an explicit policy exception.
- Include support status, known limitations, migration notes, and rollback instructions in the release notes.
Public Readiness Rule
A generic feature should be included in a public release when it has:
- A stable YAML model and schema coverage.
- Documentation with at least one focused example.
- Playwright coverage for the important UI behavior.
- No customer-specific dependencies or private assets.
- A supportable migration path if the authored syntax changes.