@@ -431,6 +431,40 @@ tag_release() { # create the path-prefixed semver tag amebaz2-vX.Y.Z locally (n
431431
432432# ---- top-level -------------------------------------------------------------
433433cmd=" ${1:- } " ; shift || true
434+ # ---- publish the DEPLOYED artifacts to the GitHub release (#89) -------------------------------
435+ # The release workflow REBUILDS at tag time and attaches that output, and neither target is
436+ # byte-reproducible (measured: AmebaZ2 rebuild 6763c8c5 vs deployed 184da838). So the CI asset is
437+ # NOT the image any device booted. Harmless-looking until someone reaches for "the release" as a
438+ # delta base or a recovery image, which is how the ESP32 1.0.3 base was lost (#82). This uploads
439+ # the bytes a device actually booted, under the CANONICAL names, so the plain filename is always
440+ # authoritative and the CI rebuild carries the -CI-REBUILD suffix instead.
441+ int_to_semver () { echo " $(( $1 / 10000 )) .$(( ($1 / 100 ) % 100 )) .$(( $1 % 100 )) " ; }
442+ publish () {
443+ command -v gh > /dev/null || die " gh not on PATH -- needed to upload release assets"
444+ local v tag n=0 f
445+ # Only ever publish what THIS box confirmed booted: `flash` writes the marker after the device
446+ # sustained the new version across three fresh reads. Publishing an image no device ran would
447+ # recreate exactly the problem this fixes.
448+ v=" $( released_version) "
449+ [ " $v " != 0 ] || die " no on-device version recorded -- run 'flash' first"
450+ tag=" amebaz2-v$( int_to_semver " $v " ) "
451+ gh release view " $tag " > /dev/null 2>&1 || die " no release $tag -- push the tag first ('ota-release.sh tag')"
452+ # firmware_is-v<N>*.bin FIRST: on this path the raw firmware_is.bin is what the break-glass HTTP
453+ # OTA actually streams to the device, so the archived copy is the byte-exact deployed payload.
454+ # The clip/.ota are derived and only exist if `package` ran on this box for this build -- and
455+ # regenerating them would mean rebuilding, whose bytes differ (non-reproducible), so they are
456+ # published only when genuinely available rather than manufactured on demand.
457+ for f in " firmware_is-v$v .bin" " firmware_is-v$v -debug.bin" \
458+ " flash_rac-integrated-v$v .bin" " rac-v$v .ota" " rac-v$v .json" \
459+ " flash_rac-integrated-v$v -debug.bin" " rac-v$v -debug.ota" " rac-v$v -debug.json" ; do
460+ [ -f " $REPO /firmware/built-images/$f " ] || continue
461+ gh release upload " $tag " " $REPO /firmware/built-images/$f " --clobber > /dev/null \
462+ && { say " uploaded $f " ; n=$(( n+ 1 )) ; }
463+ done
464+ (( n > 0 )) || die " no artifacts for v$v in built-images/ -- build + package first"
465+ say " published $n deployed artifact(s) to $tag (on-device version $v )"
466+ }
467+
434468case " $cmd " in
435469 lint) lint ;;
436470 build) build " ${1:- } " ;;
@@ -452,5 +486,6 @@ case "$cmd" in
452486 [ " $TAG " = 1 ] && tag_release || true
453487 [ " $FLASH " = 1 ] && flash || say " staged, not flashed. run: ota-release.sh flash"
454488 ;;
455- * ) die " usage: ota-release.sh {lint|build [--bump[-minor|-major]] [--debug]|package|stage|flash|tag|verint [semver]|release [--bump[-minor|-major]] [--tag] [--flash]}" ;;
489+ publish) publish ;;
490+ * ) die " usage: ota-release.sh {lint|build [--bump[-minor|-major]] [--debug]|package|stage|flash|tag|publish|verint [semver]|release [--bump[-minor|-major]] [--tag] [--flash]}" ;;
456491esac
0 commit comments