Repository navigation
feat(ota): ota branch channel switch (prod) - #62
Merged
agessaman merged 16 commits intoOct 4, 2026
Merged
Conversation
(cherry picked from commit 52a4ccc)
(cherry picked from commit db1db5b)
(cherry picked from commit 0bee84c)
(cherry picked from commit 2408049)
(cherry picked from commit 2901195)
Build counters are per channel, so a cross-channel build number is not comparable: a switch to a channel with a lower counter reported up to date and never happened. Off the native channel, update unless the hash matches.
…iases Report the selected channel and the build's own channel, tag each baked-in base for CI, and list ota branch in the CLI docs and portal autocomplete.
Every observer build now carries both channel URLs, so checking for a URL's presence or absence can no longer tell prod from beta (and the old checks would reject every build). Read the ota-base-* tags from every .bin in out/ instead of a single ELF, with URLs shared by build.sh and both workflows.
…mmit Prod and beta are often built from one commit (e.g. after a dev->prod merge), so a hash match does not mean the images are the same: the native base differs. After the flash the target channel is native, so this cannot loop.
The deferred flash re-read the channel preference ~2.5 s after ota update acknowledged its target; capture it when the update is scheduled.
A switch can land on an older build: e.g. prod cannot read dev's /mqtt.json, and prod's M7 image has no Ethernet. Each image carries an ota-compat tag (state generation + transports). A switch is flashed without rebooting, the new image's tag is read (bounded by its length), and boot is pointed back at the running image unless the target keeps this node's state and transports. CI now requires the tag in every published binary.
Every image also holds "ota-compat:" with no value (the search string); finding it first made every channel switch look untagged.
Owner
Author
Bench results: Heltec V3 (2026-10-03)The build was the #63
Not yet tested: a successful channel switch. That needs a tagged image on a channel; it gets tested once #63 publishes to beta, by switching a #62 build prod→beta. |
Owner
Author
Bench results, round 2: successful switch (Heltec V3, 2026-10-03)After #63 merged, beta published v1.17.1.23 ( The board ran a #62
Once #62 merges, prod images will carry |
This was referenced Oct 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
ota branch [prod|beta|default](aliasesstable,dev) so an observer can move between the production and beta OTA channels without a cable flash. Ported from Dutch-MeshCore/MeshCore PR #7 (Elektr0Vodka; the 5 ported commits keep their author), adapted for our channels.The feature lives on
feat/ota-branch-switch, branched from the prod/dev merge base47c80fecfand merged into both channels. The commits are shared history, so the later dev→prod merge picks up no conflicts from this feature (simulated: 0 conflicts).Behaviour
ota branchreports the selected channel, the build's own channel and the manifest base. A new setting is saved in/prefs.json(ota_ch);ota updatethen pulls from that channel.OTA_MANIFEST_BASE_STABLE/_DEV, injected bybuild.shand both workflows).ota updatechecked, so anota branchsent in the meantime cannot retarget it.Safety gate for channel switches
Each image carries an
ota-compat:<gen>[+eth]tag. On a channel switch, the node writes the image without rebooting, then reads the target's tag (bounded by the image length). It points boot back at the running image unless the target's state generation is at least the node's own and the target keeps the node's transports./mqtt_prefs), dev = gen 2 (/mqtt.json). Until dev merges into prod at 1.18, beta→prod is refused and prod→beta works.+eth= MQTT over Ethernet (NETWORK_PREFER_ETHERNET, the M7). A switch that would drop Ethernet is refused.CI
The old strings/grep checks would reject every build now that each binary contains both URLs. They are replaced by
scripts/verify_ota_channel.py --expect prod|beta, which reads theota-base-native|stable|dev:andota-compat:tags from every.bininout/, not just one ELF.Testing
build.shbuilds of Heltec V3 repeater and V4 room server observers on both channels, plus the M7 observer on dev.verify_ota_channel.pypasses for the right channel and fails for the wrong one and for a mixed directory..binfiles, reads prod gen 1, dev gen 2 and M72+eth.native_ota_channel12/12; devnative552/552; serializer round-trip tests forota_ch.Ship to both channels together: a node switched to a channel whose build lacks
ota branchcannot switch back without a cable flash.