OT-2 external releases

Customer-facing OT-2 releases. The app uses calendar semver (vYY.M.N) in opentrons-ot2. Robot OS uses an independent traditional semver line (for example v1.19.9) in buildroot.

Calendar semver (external app)

Versions use US Eastern calendar components:

PartMeaningExample
YYTwo-digit year26 for 2026
MMonth, no leading zero6 for June
NMonthly build counter, 0–90 = first external build that month

External app tags use a v prefix: v26.6.0, v26.6.1, …

Stack repos

RepoRoleTag pattern
opentrons-ot2App (taggable)vYY.M.N (+ alpha/beta prereleases)
buildrootOT-2 robot OSvX.Y.Z independent line (for example v1.19.9)

Robot-stack tooling

just go, just track-builds, and just invalidate-cloudfront are advisory: they sync local clones under this workspace, print tables and analysis, and emit copy-paste commands. A human (or agent) runs git tag -a, git push, and aws cloudfront create-invalidation elsewhere. Nothing here pushes tags, triggers CI, or invalidates CloudFront by itself.

robot-stack-infra is always cloned for reference; it is not included in release tagging tables.

Plan a release non-interactively, for example:

just go --non-interactive --skip-assumptions --path flex --release-type external --stability stable

Release branch

OT-2 external tags default-branch HEAD. No chore_release branch is used.

RepoDefault branch
opentrons-ot2edge
buildrootopentrons-develop

When does just go say a new tag is needed?

For each repo, automation/go.py uses the release branch described above, finds the newest annotated tag for the selected channel on that branch (sorted by creator date, merged into the branch), and compares the branch tip commit.

New tag needed when the branch tip commit is not the same commit as that latest channel tag.

No new tag needed when branch HEAD already matches the latest channel tag.

Tags must be annotated (git tag -a … -m 'chore(release): …') so git tag -l --sort=-creatordate reflects real release order. Stack repo tag messages often reference the monorepo release version.

Pushing a tag triggers CI builds in the tagged repo. The app monorepo tag drives app artifacts; stack repo tags drive robot OS and firmware builds.

How the next tag is chosen

In just go, OT-2 uses Stability: stable, alpha, or beta.

go infers the next calendar base from existing app tags on the release branch (defaults to the current month in Eastern time when no tags exist yet).

App stable

Find all external calendar tags (vYY.M.N, including alpha/beta) for the same year and month. Increment N. More than 10 external releases in one month (N > 9) is treated as an error.

App alpha / beta

Each new build in the month gets the next N slot. Prerelease numbers increment on that base: v26.5.0 (stable) then v26.5.1-alpha.0, v26.5.1-alpha.1, or v26.5.1-beta.0, etc.

buildroot stable

Patch-bump from the latest merged traditional v* tag on opentrons-develop (for example v1.19.9v1.19.10). Calendar app tags such as v26.6.0 are ignored when choosing the next buildroot tag.

buildroot only receives a new tag when its branch is ahead of the latest traditional external tag.

Tag push order

Push annotated tags in this order. Dependent stack repos first, app monorepo last. just go prints this reminder at the end of a release run.

StepRepoNotes
1buildrootRobot OS, if a new tag is needed
2opentrons-ot2App monorepo, always last

OT-2 stack repos only get a new tag when their release branch tip is ahead of the latest channel tag on that branch.

Track release builds

After pushing the app tag, run (non-interactive form):

just track-builds --non-interactive --path ot2 --tag v26.6.0 --wait

automation/track_builds.py locates GitHub Actions runs for:

  1. App workflow on the monorepo (App test, build, and deploy)
  2. Kickoff cross-repo dispatch (Start OT-2 build)
  3. Robot OS build in buildroot

The Rich table lists key jobs (deploy, desktop builds, dispatch spawn, robot image build). The Slack copy block includes only two links:

OT-2 release `v26.6.0`

- app: <app workflow run URL>
- ot2: <robot OS workflow run URL>

--wait polls every 15 seconds until app, kickoff, and robot OS workflow runs all appear (default timeout 900 seconds). Polling checks workflow runs only; job details are fetched afterward with retries for transient GitHub 404s. Exit code 2 if a run is still missing after the timeout.

CloudFront invalidation

CI does not invalidate CloudFront automatically. After builds finish, print a copy-paste command (it does not run invalidation):

just invalidate-cloudfront --non-interactive --path ot2 --tag v26.6.0

Invalidates /app/* and /ot2-br/* on the channel host. Uses AWS profile robotics_robot_stack_prod-admin when credentials allow distribution lookup; otherwise the script prints a lookup command and placeholder ID.

Validate published artifacts

Optionally regenerate live manifest inventories:

just assets-pages

Or per-platform reports: just flex-assets / just ot2-assets. Pages: external assets, internal assets.

Where to find published releases

External OT-2 artifacts live on ot2.builds.opentrons.com.

ArtifactURL
App releases.json https://ot2.builds.opentrons.com/app/releases.json
Robot releases.json (source of truth) https://ot2.builds.opentrons.com/ot2-br/releases.json

Robot releases.json is the source of truth for on-robot updates. Desktop app updates use channel YAMLs (latest.yml, prerelease YAMLs) via electron-updater; those YAMLs are authoritative. App releases.json is parsed by a CloudFront edge function to pick the latest stable semver from production and route latest* requests accordingly.

Electron-updater channel YAMLs:

See also: OT-2 external assets.

Alpha and beta on OT-2 external

In just go, choose Release type: external and Stability: alpha or beta.

StabilityTag exampleNotes
Stablev26.6.0, v26.6.2 (app)Monthly counter N bumps for each external build; buildroot patch-bumps its own line (for example v1.19.10)
Alphav26.5.1-alpha.0, v26.5.1-alpha.1Next N for a new build; increment prerelease on the same base
Betav26.5.1-beta.0Same monthly N as alpha on that build line; increment -beta.N on the same base

Alpha and beta share the monthly build counter N with stable releases. After v26.5.0 stable, the next alpha is v26.5.1-alpha.0, not v26.5.0-alpha.0. QA cycles on the same base increment the prerelease number only.