Releases and updates
Ship a stable release that deploys app-host artifacts and verifies client packages.
Stable GitHub Releases are the production deployment interface. Publishing a
non-draft, non-prerelease tag named vX.Y.Z runs the unified release workflow
against that exact commit. One release deploys the API, portal, admin console,
multi-chat, Typography, browser broadcaster, OBS Remote web app, and this
documentation site. When relay files changed since the previous release it also
deploys those relay components, and when plugin files changed it attaches new
OBS plugin packages to the same GitHub Release. Native store builds are not
part of the release: a push to main that touches apps/native or
apps/obs-remote builds that app and submits it to Google Play and TestFlight
through mobile.yml.
Before tagging
Set the same X.Y.Z (no leading v) in:
apps/native/app.jsonapps/native/package.json- every
MARKETING_VERSIONentry in the committed iOS project apps/obs-plugin/buildspec.jsonapps/obs-remote/app.jsonapps/obs-remote/package.json
Tag a commit on main and publish the
release; the workflow checks that the commit is on main and that every
version matches the tag. Draft and prerelease
publications are ignored, and concurrent releases are serialized.
What the workflow does
- Runs the repository tests, type checks, and every production build first — a red check stops the release before anything deploys.
- Connects to the app host over an ephemeral Tailscale identity and runs the
root-owned
visp-releasebootstrap with the tag and its 40-character commit SHA. - Builds OBS Remote for web and retains the output as a workflow artifact.
- If
mediamtx,srtla_rec,visp-bond, or relay Caddy files changed since the previous release, deploys only those components to each relay in turn throughvisp-relay-releaseand checks the relay's/ping. - If the OBS plugin or its control-plane code changed (or this is the first
release), builds, signs, and notarizes the OBS packages and attaches them
with
SHA256SUMS.txt— uploads use overwrite semantics, so rerunning a failed job is safe.
How the server update stays safe
The bootstrap verifies the tag and SHA, takes a host lock, refuses to run over
tracked local changes, checks out the exact release, and then executes that
release's own helper from /usr/local/libexec — so helper fixes take effect in
the same release that ships them.
The helper installs frozen dependencies, migrates the database, and builds
every app-host artifact before restarting anything. It validates the Caddy
configuration before installing it, restarts visp-server, visp-web, and
visp-typography-worker,
reloads Caddy, and runs local smoke checks. An install, migration, or build
failure therefore leaves the currently running services untouched.
Two rules follow from this design:
- Migrations must stay backward-compatible; database rollback is manual.
- A relay restart ends active streams, and a release restarts relay services whenever their files changed. Publish releases that touch relay components in a maintenance window. API and portal restarts do not end streams.
After the release
- Portal and API healthy; the admin console shares the main login, permits an admin, and denies an ordinary user.
- A deep browser-app route and OAuth return work at
stream.visp-stream.com; WebRTC publishes through the relay. - OBS Remote signs in and receives live OBS state at
remote.visp-stream.com. - Docs respond at
docs.visp-stream.com:/docs,/api/search,/llms.txt,/llms-full.txt. - If the release rebuilt the plugin, the GitHub Release carries all three OBS
packages, the macOS package is notarized, and every file matches
SHA256SUMS.txt.
Native store promotion beyond TestFlight and Play submission, OBS plugin
installation on broadcaster machines, and automatic database rollback are
intentionally outside the workflow. A merge to main publishes
compatible VISP native OTA updates to XPRem's staging branch through
native-update.yml.