build: make OTA_MANIFEST_BASE a build.sh-injected release channel

The observer fetches its manifest from <OTA_MANIFEST_BASE>/<OTA_VARIANT>.json,
so that URL IS the release channel. It was hardcoded to the production channel
in 28 identical places across variants/*/platformio.ini, which made a parallel
(e.g. beta) channel impossible: both channels build the same env names, so beta
devices would read the production manifest and silently flash themselves onto
production firmware.

Inject it from build.sh instead, symmetric with OTA_VARIANT (which no .ini
declares), defaulting to the production URL. Set OTA_MANIFEST_BASE_URL to
publish a parallel channel.

Removed from the .ini files rather than overridden: PLATFORMIO_BUILD_FLAGS
cannot reliably override a -D from build_flags, because SCons reorders -U/-D
and the -U can land after both -Ds, leaving the macro undefined. Verified
empirically before choosing this approach.

A default in a header was deliberately NOT added: leaving both macros undefined
on a plain 'pio run' is what keeps ESP32Board.cpp's 'ERR: OTA not configured
(build via build.sh)' guard firing, so locally built firmware is never OTA-armed.

Verified on Heltec_v3_repeater_observer_mqtt:
- plain 'pio run'      -> OTA disarmed, no manifest URL in the binary
- build.sh (default)   -> https://observer.gessaman.com/v
- OTA_MANIFEST_BASE_URL set -> beta URL only, production URL absent
This commit is contained in:
agessaman
2026-07-19 14:37:06 -07:00
parent 38066a5676
commit 36831271fe
13 changed files with 17 additions and 29 deletions
+17 -1
View File
@@ -162,10 +162,26 @@ build_firmware() {
fi
EMBEDDED_VERSION_STRING="${FIRMWARE_VERSION}${BUILD_NUMBER_SUFFIX}${VARIANT_TAG}-${COMMIT_HASH}"
# Release channel. The observer pull-OTA fetches its slim per-variant manifest
# from <OTA_MANIFEST_BASE>/<OTA_VARIANT>.json, so this URL IS the channel: a
# device only ever sees updates published under the base it was built with.
# Override OTA_MANIFEST_BASE_URL to publish a parallel channel (e.g. beta);
# unset gives the production channel.
#
# Deliberately injected here rather than declared in variants/*/platformio.ini
# (where it used to be duplicated 28 times), for symmetry with OTA_VARIANT and
# so a plain `pio run` leaves BOTH macros undefined — which is what makes
# ESP32Board.cpp's "ERR: OTA not configured (build via build.sh)" guard fire on
# dev builds. Do not add a default in a header: that would silently arm OTA on
# locally built firmware. Note that PLATFORMIO_BUILD_FLAGS cannot reliably
# override a -D coming from build_flags (SCons reorders -U/-D), which is why
# the .ini declarations were removed rather than overridden.
OTA_MANIFEST_BASE_URL="${OTA_MANIFEST_BASE_URL:-https://observer.gessaman.com/v}"
# add firmware version info to end of existing platformio build flags in environment vars.
# OTA_VARIANT is the env name ($1) — it selects this build's slim per-variant manifest
# (<OTA_MANIFEST_BASE>/<OTA_VARIANT>.json) that the observer pull-OTA fetches.
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFIRMWARE_BUILD_DATE='\"${FIRMWARE_BUILD_DATE}\"' -DFIRMWARE_VERSION='\"${EMBEDDED_VERSION_STRING}\"' -DOTA_VARIANT='\"$1\"'"
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFIRMWARE_BUILD_DATE='\"${FIRMWARE_BUILD_DATE}\"' -DFIRMWARE_VERSION='\"${EMBEDDED_VERSION_STRING}\"' -DOTA_VARIANT='\"$1\"' -DOTA_MANIFEST_BASE='\"${OTA_MANIFEST_BASE_URL}\"'"
# disable debug flags if requested
disable_debug_flags
-2
View File
@@ -112,7 +112,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -205,7 +204,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
-4
View File
@@ -123,7 +123,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -204,7 +203,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -493,7 +491,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -543,7 +540,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
-4
View File
@@ -162,7 +162,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -214,7 +213,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -317,7 +315,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -357,7 +354,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
-2
View File
@@ -116,7 +116,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
; -D MQTT_DEBUG=1
@@ -162,7 +161,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
-2
View File
@@ -209,7 +209,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D PERSISTANT_GPS=1
@@ -256,7 +255,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D PERSISTANT_GPS=1
@@ -161,7 +161,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
; -D MQTT_DEBUG=1
@@ -204,7 +203,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -160,7 +160,6 @@ build_flags =
-D MAX_NEIGHBOURS=50
-D PERSISTANT_GPS=1
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
; -D MQTT_DEBUG=1
@@ -203,7 +202,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -120,7 +120,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -163,7 +162,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -157,7 +157,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_TASK_STACK_SIZE=16384
@@ -203,7 +202,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_TASK_STACK_SIZE=16384
-2
View File
@@ -113,7 +113,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -177,7 +176,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
-2
View File
@@ -187,7 +187,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -306,7 +305,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
-2
View File
@@ -103,7 +103,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D MAX_NEIGHBOURS=50
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1
@@ -147,7 +146,6 @@ build_flags =
-D ADMIN_PASSWORD='"password"'
-D ROOM_PASSWORD='"hello"'
-D WITH_MQTT_BRIDGE=1
-D OTA_MANIFEST_BASE='"https://observer.gessaman.com/v"'
-D MAX_MQTT_BROKERS=3
-D MQTT_MAX_PACKET_SIZE=1024
-D MQTT_DEBUG=1