Roll out watcher releases
Publish watcher versions to PyPI, advertise them per environment, force mandatory updates, and roll the fleet back.
Lab PCs upgrade themselves toward the version you advertise per environment. You control that from Settings → Watchers. How an individual PC installs or runs self-update is in Install and update the watcher.
How fleet upgrades reach a PC
The in-process updater runs from the heartbeat tick on every platform (not only Windows services). Roughly once an hour the watcher:
- Asks the server for the latest version and compares it to its own
- Upgrades only if a newer version is available, no files have uploaded for several heartbeats, and no run was reported recently (the activity-window guard). Releases flagged mandatory skip this guard
- Installs the new wheel and restarts into it (Windows services restart via failure-actions policy)
- Emits
update_started, thenupdate_succeededorupdate_failed, visible on the dashboard
Auto-update is disabled in the preview environment so pull-request preview deployments cannot push code to lab PCs.
Cut a new release
Releases are tag-driven and publish from a production commit.
Bump the version in watcher/pyproject.toml and merge through staging to production.
Tag and push from production:
git checkout production && git pull
git tag watcher-v0.3.0 && git push origin watcher-v0.3.0Approve the pypi deployment under Actions → Publish watcher in GitHub.
In Settings → Watchers, set Latest version to the new tag. Each environment has its own database, so bump staging and production separately to roll the fleet gradually.
Always tag → publish → verify on PyPI → save. Saving Latest version before the wheel is live triggers a wave of update_failed events across the fleet.
Release-config fields
| Field | Purpose |
|---|---|
| Latest version | Required. Blank means “no update info available”. |
| Minimum supported version | Reserved; not enforced server-side yet. |
| Release channel | Defaults to stable. Surfaced in self-update output. |
| Mandatory update | Skips the activity-window guard; see below. |
Mandatory updates
Toggling Mandatory update skips the activity-window guard and fires the upgrade on the next hourly check. The server still compares the running version to Latest version, so a correctly pinned PC is not forced past its pin.
Use sparingly: a forced upgrade mid-acquisition can lose data. Reserve it for security fixes, wire-protocol breaks, or cases where leaving the bad version running is worse than restarting in flight.
Roll back
Rollback is another release: set Latest version back to the older tag for the affected environment(s), turn Mandatory update on if you need to bypass the activity-window guard, and wait for the next hourly tick. Turn Mandatory update off once the fleet converges. The older wheel remains on PyPI; it is no longer advertised.
Operator-side failures
If update_started is followed by update_failed, or auto-update never fires, point operators at Troubleshoot a watcher and Install and update the watcher.