Skip to content

Releasing [[releasing: __Namespace]]

How each part of the qmdc monorepo is versioned, built, and published, and the rebuild cascade between components. The repo-root RELEASING.md is a pointer to this page — this is the source of truth.

Overview [[release_overview: NarrativeDoc]]NarrativeDoc

qmdc is one logical tool with three implementations (Python Parser, TypeScript Parser, Rust Parser), kept behaviour-identical by the shared data-driven test corpus (see Testing). The fast CLI is the native Rust binary; it is bundled into the npm qmdc, PyPI qmdc, and VS Code Extension packages.

Components [[release_components: text]]text

Package Dir Registry User installs with
qmdc (parser + CLI) qmdc-py, qmdc-ts, qmdc-rs PyPI, npm, crates.io uvx qmdc, npx qmdc, cargo install qmdc
qmdc-semantic qmdc-semantic PyPI uvx qmdc-semantic
qmdc-mkdocs qmdc-mkdocs PyPI uvx qmdc-mkdocs
qmdc-vscode qmdc-vscode VS Code Marketplace from the Marketplace

Versioning [[release_versioning: text]]text

Each package versions independently — there is no lockstep. A bug in one parser is fixed and released on its own; parity is enforced by tests, not by equal version numbers.

Rebuild Cascade [[release_cascade: text]]text

What you must (re)publish for a given change:

Changed Publish Why
qmdc-py/** PyPI qmdc Python lib lives only in the PyPI package
qmdc-ts/** npm qmdc TS lib lives only in the npm package
qmdc-rs/** (the binary) crates qmdc + npm qmdc + PyPI qmdc + qmdc-vscode all four embed the binary
qmdc-vscode/** qmdc-vscode leaf
qmdc-semantic/** PyPI qmdc-semantic leaf
qmdc-mkdocs/** PyPI qmdc-mkdocs leaf

A binary change is the only one that fans out — every package that embeds the native binary must rebuild. A change to Rust Parser therefore cascades to the npm/PyPI qmdc packages and the VS Code Extension. Use the cascade target rather than bumping the four by hand:

make binary-bump          # patch-bump crates + PyPI qmdc + npm qmdc + vscode together
make binary-bump-minor    # same cascade at minor
make binary-bump-major    # same cascade at major

qmdc-semantic / qmdc-mkdocs depend on qmdc at runtime (qmdc>=1.0.0), resolved from PyPI at install time, so the cascade deliberately leaves them untouched.

Releasing a Component [[release_steps: text]]text

Each package has scripts/publish.sh (dry-run by default; --publish to go live) and a bump script. Tokens come from environment variables only — never commit them.

  1. Bump (independently per package): make rs-bump / py-bump / ts-bump / mkdocs-bump / ext-bump (or *-bump-minor / *-bump-major). Use make binary-bump whenever the Rust binary itself changed.
  2. Tag with a package-prefixed tag, e.g. qmdc-rs-v1.0.1, and push with git push --follow-tags.
  3. Publish (until release CI exists, run locally):
Package Dry-run Publish Token
crates qmdc make rs-publish make rs-publish PUBLISH_ARGS=--publish CARGO_REGISTRY_TOKEN
PyPI qmdc make py-publish make py-publish PUBLISH_ARGS=--publish UV_PUBLISH_TOKEN
npm qmdc make ts-publish make ts-publish PUBLISH_ARGS=--publish NODE_AUTH_TOKEN
PyPI qmdc-semantic make semantic-publish make semantic-publish PUBLISH_ARGS=--publish UV_PUBLISH_TOKEN
PyPI qmdc-mkdocs make mkdocs-publish make mkdocs-publish PUBLISH_ARGS=--publish UV_PUBLISH_TOKEN
qmdc-vscode make ext-publish VSCE_PAT

Build Matrix [[release_matrix: text]]text

make dist cross-builds every artifact into dist-release/ (no publishing): 7 native qmdc binaries (darwin, linux gnu+musl, windows; via cargo / cargo-zigbuild), 7 npm @qmdc/cli-<platform> packages + the main tarball, 7 PyPI platform wheels for qmdc plus qmdc-semantic / qmdc-mkdocs sdist+wheel, and 6 qmdc-vscode VSIX. cargo install qmdc is the universal fallback for any target not in the matrix.

Semantic Artifacts [[release_semantic: text]]text

The semantic embeddings DB and hints are committed artifacts (precomputed before release), so the docs site (built by Static Site Generator — Documentation Website Builder) needs no embedding provider. Refresh and commit them before a release with make semantic-refresh WS=./docs (embeddings.db via Git LFS, hints.json plain).