feat(update): stable/beta update channel; stable follows release tags (#684)

Adds auto_update.channel: stable follows the newest vX.Y.Z release tag
(detached HEAD; pre-releases and other tags ignored), beta follows main as
before. Nothing ever moves a device backwards: a checkout newer than the
newest release keeps following main (or stays put when detached) until a
release contains its commit. Legacy configs migrate to stable when they
reach a release. Update Code, the weekly updater's preflight, and the
verifier's rollback (back to old_ref: branch or detached release) all
honour the channel. General tab Update Channel select, GET/POST
/api/v3/system/update-channel, release-aware Overview banner and Tools git
panel. New installs default to stable.

Rig fix (ledpi): /system/check-update reports update_available: false when
the channel's action is none (a detached HEAD newer than the newest
release), matching Update Code; the Tools panel no longer calls every
detached HEAD "a release".

Merged with main through #687 (heartbeat verifier, #683 login, #688
plugin_catalog, #685 Tailwind build).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-09-30 15:35:26 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 64c7289593
commit 7804ea8f69
21 changed files with 1499 additions and 50 deletions
+24
View File
@@ -19,6 +19,30 @@ accepts both, but the store flags the old spelling as deprecated
## Unreleased
### Update channels
- Devices no longer pick up every merge to `main`. A new setting,
`auto_update.channel`, picks what Update Code and the weekly automatic
update install: `stable` follows the newest release tag (`vX.Y.Z` by
semantic version; pre-releases and other tags are ignored) and checks it
out with a detached HEAD, and `beta` follows `main` as every device did
before. New installs default to `stable` (config template and installer).
- Nobody is moved backwards. A device running code newer than the newest
release, which is any device that pulled `main` since that release, keeps
following `main` until a release contains its commit, then moves to it and
follows releases. A config written before channels existed behaves the
same way and is saved as `stable` when that move happens. Switching from
beta to stable says so instead of installing an older version.
- Switch channels on the General tab (Update Channel, under Automatic
Updates) or with `GET`/`POST /api/v3/system/update-channel`. The Overview
update banner compares release tags on stable ("LEDMatrix v3.8.0 is
available") rather than commits on `main`. A detached checkout newer
than the newest release gets no banner: Update Code leaves it where it
is until a release includes it.
- A move between `main` and a release tag carries local edits across as the
pull's `--autostash` does, and the automatic update's health check rolls
it back to where HEAD was: the branch, or the detached release.
### Frozen-panel detection
A render loop stuck inside a plugin's `display()` left `ledmatrix.service`