Skip to content
OpenSmartRoute
Documentation
Releases

Versions, channels and releases

One version for every artifact, stable releases and developer previews, and how to read the build a deployment runs.

Releases 6 min read

One version number names everything OpenSmartRoute ships - the Python package, the osr command line, the npm client, the platform API and web images, the Helm chart, the Compose bundle, the Azure Marketplace package, the browser extension and the desktop app - and every deployment tells you which build it runs. This page says what the numbers mean, how to read them on each surface, and how a release is made.

One version

The release version is X.Y.Z (Semantic Versioning). Every artifact of a release - the packages, images, chart, extension and installers - is stamped from one source, and a consistency check fails any build where a version drifts. There is no separate extension version, desktop version, SDK version or platform version: pip install opensmartroute==1.3.0, npm install @opensmartroute/sdk@1.3.0, osr-platform-api:1.3.0, chart 1.3.0, the extension 1.3.0 and OpenSmartRoute-1.3.0-win-x64.exe were all built from the tag v1.3.0.

  • A minor release (1.3.0 -> 1.4.0) adds; the public Python API only grows.
  • A patch release (1.3.0 -> 1.3.1) fixes; nothing new is announced.
  • A major release may remove what was deprecated two minors earlier.
  • SECURITY.md lists the supported versions: the current minor gets every fix; an earlier minor of the same major gets security fixes for 90 days after the minor that superseded it shipped (the table names the date); earlier majors get nothing. The table is computed from the changelog's release dates, so the window never depends on how quickly minors follow each other.

Cadence

Minor releases are cut when the [Unreleased] section carries something users need, at most once a week unless a security fix or a broken release forces a patch; patch releases ship whenever a fix is ready. Every release soaks as a developer preview on the hosted platform first (below). A minor that ships faster than that is not wrong, but the 90-day window above is what protects the people who installed the one before it.

Two channels

Every build is either a stable release or a developer preview, decided from the git tags alone - no one types a build number:

ChannelBuilt fromVersionWhere it goes
stablethe tag vX.Y.ZX.Y.ZPyPI, npm, the image tags X.Y.Z / X.Y / latest, the release downloads, extension/latest.json, desktop/latest.json + latest*.yml, the browser stores
developer previewany other commit on main<next>-preview.<N>the hosted platform (opensmartroute.ai), extension/preview.json, desktop/preview.json + preview*.yml

<next> is the release the preview leads up to: the pyproject version while its tag does not exist yet (a merged release pull request, about to be tagged), otherwise the next patch after the last release. N counts the commits since the last release tag, so previews sort and read in order: 1.3.0 -> 1.3.1-preview.1 ... 1.3.1-preview.89 -> 1.4.0-preview.3 (release PR merged) -> 1.4.0.

The hosted platform deploys every merge to main by default, so what you use at opensmartroute.ai is the developer preview of the next release - the [Unreleased] section of the changelog is what it carries beyond the last stable release. Every release also redeploys the platform from its tag, so the deployment moves to the stamped stable build (channel: stable, footer without the preview badge) once the release is cut. An operator can pin production to releases only by setting OSR_DEPLOY_PREVIEWS=false in the deployment's configuration: main keeps building and testing its images, the preview is reported but not rolled out, and production changes only when a release is tagged. Self-hosted installations pull stable images and stay on releases either way.

Browser manifests take up to four integers, so a preview extension carries X.Y.Z.N (1.3.1.89) in manifest.json; Chrome and Edge show the readable label (1.3.1-preview.89) as version_name. A release carries X.Y.Z. Previews are never submitted to the browser stores. The desktop installers carry the label in their file names (OpenSmartRoute-1.3.1-preview.89-win-x64.exe) and a preview build's updater follows the preview*.yml feed, so an installed release only ever updates to the next release.

Reading the version

SurfaceWhat it shows
osr --version, opensmartroute.__version__the package release, 1.3.0
GET /api/v1/info -> build, GET /healthz -> build{"version": "1.3.1-preview.89", "release": "1.3.0", "channel": "preview", "commit": "4ced2b2..."} on a published image; channel is null for a checkout or a hand-built image, which report the release alone
the website footerv<build version>; a developer preview badge when the deployment runs main ahead of the next release
GET /api/v1/releasesevery release's notes, the running build, and unreleased - what has landed since the last release (GET /api/v1/releases/{version} with unreleased as the version returns that section alone)
GET /extension/release.jsonthe extension build offered for download with its channel; ?channel=preview for the preview, ?channel=stable for the release only
GET /desktop/release.jsonthe same for the desktop app's installers
the dashboard's What's new card and the release mailthe stable release notes, sent once per release version - previews never announce
image labelsorg.opencontainers.image.version and .revision on osr-platform-api and osr-platform-web (docker inspect)

The build stamp reaches the images as build arguments (OSR_BUILD_VERSION, OSR_BUILD_CHANNEL, OSR_BUILD_COMMIT) and the API as the settings OSR_PLATFORM_BUILD_VERSION, OSR_PLATFORM_BUILD_CHANNEL and OSR_PLATFORM_BUILD_COMMIT. Anyone building the image by hand can pass the same arguments (docker build --build-arg OSR_BUILD_VERSION=... ); without them the image is honest about not knowing its channel.

Downloads

opensmartroute.ai/downloads always resolves to the current stable release: /download/<artifact> redirects to the versioned file and /download/latest.json lists them with SHA-256 checksums. Versioned files never change once published (cached for a year); the latest.json pointers move with each release.

The browser extension follows the same rule with two pointers: /extension/download/<browser> offers the stable release and /extension/download/<browser>?channel=preview the developer preview. While no stable release of the extension has been published yet, the preview stands in and the page says so (Browser extension, Where the packages come from). The desktop app is served the same way from /desktop (/desktop/release.json?channel=preview, installers and update feeds under /desktop/download/).

Unreleased changes

Every user-visible change lands as a bullet under ## [Unreleased] in the changelog the moment it merges - that section is the developer preview's release notes and the draft of the next release's. The website renders it on the changelog page, GET /api/v1/releases returns it as unreleased, and it becomes the dated ## [X.Y.Z] section when the release is cut. Nothing is announced to users until then: the release mail and the What's new card key off the stable release version.

How a release is made

Releases are cut in two steps from the main branch; nobody edits a version or a tag by hand.

  1. Prepare: the version is bumped everywhere at once, [Unreleased] rolls into [X.Y.Z] - date, the compare links and the supported-versions table are refreshed, and the change is reviewed like any other. From the moment it merges, main-branch builds are X.Y.Z-preview.N - release candidates of X.Y.Z.
  2. Release: the consistency check and the full test and routing gates run, the packages are built, the annotated tag vX.Y.Z is created (its message is the changelog section), PyPI and npm are published, the images are stamped stable, the Compose bundle, Helm chart and Marketplace zip land on the downloads page, and the extension and desktop builds follow on the tag (stable packages behind latest.json, store submissions). Everything is then fetched back the way a user would: the PyPI files must match the built checksums, the image must report the version and answer /readyz, and the extension and desktop pointers the website serves and the platform's /api/v1/info (build, platform package, SDK) must all answer X.Y.Z - a channel left behind fails the release by name instead of staying on the previous version unnoticed. Firefox signing by Mozilla cannot hold a release back: when its review outlasts the wait, the other browsers ship and the signed .xpi completes the manifest as soon as Mozilla returns it.
  3. Announce. The next deploy of the hosted platform runs the new version; its release-news job mails the digest of the changelog section to opted-in users once and the dashboard shows the What's new card (Platform guide, Campaigns).

A red verification stage means the release is not usable as published: fix forward with a patch release, never by moving a tag.