Appearance
Promotion
Promotion means moving an already-published version from one channel (dist-tag) to another. It does not produce a new tarball; only the dist-tag pointers change.
Today
The publish pipeline currently writes only the latest dist-tag. Therefore promotion is not exercised today: every publish goes straight to latest.
For pre-launch testing of a candidate before it becomes default, the current workaround is to either:
- Publish to a separate package name (e.g.
@open-matrix/chat-rc), or - Pin the candidate version explicitly in dependents and avoid touching
latestuntil validated.
Both are awkward. Real channel-based promotion is target state.
Target state
Once next and beta channels are in active use, the promotion flow looks like:
1. Publish version 0.3.0-rc.1 with dist-tag = next
2. Internal smoke-test against `npm install @open-matrix/chat@next`
3. After validation, promote to latest:
npm dist-tag add @open-matrix/chat@0.3.0-rc.1 latest
4. Consumers using `@open-matrix/chat@latest` pick up 0.3.0-rc.1 on next installThe npm dist-tag command is npm-canonical; Gitea supports it through the standard npm packages API.
Promotion mechanics
bash
# Add a tag to an existing version (does not unset other tags)
npm dist-tag add @open-matrix/chat@0.3.0-rc.1 latest
# Remove a tag from a version
npm dist-tag rm @open-matrix/chat next
# List current tags
npm dist-tag ls @open-matrix/chatA single version can hold multiple tags simultaneously. Promotion is adding the new tag; demotion is adding the same tag to a different version (the tag re-points).
Atomic promotion is not guaranteed
npm dist-tag add updates one tag at a time. If you want "latest→0.3.0-rc.1, next→0.3.0" simultaneously, you must run two commands. There is a window where one tag is updated and the other is stale. For most purposes that is harmless; for tightly coupled releases, coordinate.
Catalog implications
discovery-index.json is not aware of dist-tags. The catalog reads only literal versions. A dist-tag change does not require a catalog re-index.
A consumer who searches the catalog sees the latest known version per package (per readLatestMetadata in SystemPackageRegistryActor). The catalog's "latest" is the highest version key in discovery-index.json, not the artifact registry's latest dist-tag. These usually match; they can drift if operators retag without re-indexing.
See also
Source: Current publish pipeline writes only
latest. Multi-channel promotion is target state in the publishing workstream.