Skip to content

Commit c559472

Browse files
authored
Merge pull request #30 from AndrewDemsDS/fix/publish-deployed-images
fix(release): publish the deployed image, and mark CI output as a rebuild
2 parents e75ba4a + 2ab305e commit c559472

4 files changed

Lines changed: 91 additions & 12 deletions

File tree

.github/workflows/amebaz2-release.yaml

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,38 @@ jobs:
4545
bash firmware/scripts/ota-release.sh build
4646
bash firmware/scripts/ota-release.sh package
4747
48+
# #89: CI REBUILDS at tag time and neither target is byte-reproducible, so these bytes are
49+
# NOT what any device booted. Rename them so nobody can mistake a rebuild for the deployed
50+
# image (a delta base or recovery image built from one of these would be rejected/wrong).
51+
# The authoritative artifacts are uploaded under the canonical names by `ota-release.sh
52+
# publish`, run from the box that flashed and verified the device.
53+
- name: Mark CI output as a rebuild, not the deployed image
54+
run: |
55+
V=$(bash firmware/scripts/ota-release.sh verint "$(cat firmware/src/version.txt)")
56+
cd firmware/built-images
57+
for f in "flash_rac-integrated-v$V" "rac-v$V"; do
58+
[ -f "$f.bin" ] && mv "$f.bin" "$f-CI-REBUILD.bin"
59+
[ -f "$f.ota" ] && mv "$f.ota" "$f-CI-REBUILD.ota"
60+
[ -f "$f.json" ] && mv "$f.json" "$f-CI-REBUILD.json"
61+
done || true
62+
4863
- name: Collect this version's artifacts + checksums
4964
run: |
5065
# built-images/ accumulates versions on a reused runner: reference exact filenames, not globs.
5166
V=$(bash firmware/scripts/ota-release.sh verint "$(cat firmware/src/version.txt)")
5267
echo "V=$V" >> "$GITHUB_ENV"
5368
cd firmware/built-images
54-
sha256sum "flash_rac-integrated-v$V.bin" "rac-v$V.ota" "rac-v$V.json" \
55-
"flash_rac-integrated-v$V-debug.bin" "rac-v$V-debug.ota" "rac-v$V-debug.json" \
56-
> "SHA256SUMS-v$V.txt"
69+
sha256sum ./*-CI-REBUILD.* "flash_rac-integrated-v$V-debug.bin" "rac-v$V-debug.ota" \
70+
"rac-v$V-debug.json" > "SHA256SUMS-v$V.txt"
5771
5872
- name: Attach to the GitHub Release
5973
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
6074
with:
6175
generate_release_notes: true # auto "What's Changed" from commits/PRs since the last tag
6276
files: |
63-
firmware/built-images/flash_rac-integrated-v${{ env.V }}.bin
64-
firmware/built-images/rac-v${{ env.V }}.ota
65-
firmware/built-images/rac-v${{ env.V }}.json
77+
firmware/built-images/flash_rac-integrated-v${{ env.V }}-CI-REBUILD.bin
78+
firmware/built-images/rac-v${{ env.V }}-CI-REBUILD.ota
79+
firmware/built-images/rac-v${{ env.V }}-CI-REBUILD.json
6680
firmware/built-images/flash_rac-integrated-v${{ env.V }}-debug.bin
6781
firmware/built-images/rac-v${{ env.V }}-debug.ota
6882
firmware/built-images/rac-v${{ env.V }}-debug.json

.github/workflows/esp32-release.yaml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,24 @@ jobs:
5151
5252
- name: Collect artifacts + checksums
5353
run: |
54+
# #89: ESP-IDF builds are not byte-reproducible, so this rebuild is NOT the deployed
55+
# image. Critically, delta OTA verifies the BASE image's hash, so a patch built against
56+
# this file is rejected by the device. The valid delta base is uploaded under the
57+
# canonical name by `esp32-release.sh publish` from the box that flashed the node.
5458
cd firmware/esp32-matter
55-
cp build.debug/hisense_ac_matter.bin build/hisense_ac_matter-debug.bin
59+
cp build.debug/hisense_ac_matter.bin build/hisense_ac_matter-debug-CI-REBUILD.bin
60+
mv build/hisense_ac_matter.bin build/hisense_ac_matter-CI-REBUILD.bin
5661
cd build
57-
sha256sum hisense_ac_matter.bin hisense_ac_matter-debug.bin bootloader/bootloader.bin \
62+
sha256sum hisense_ac_matter-CI-REBUILD.bin hisense_ac_matter-debug-CI-REBUILD.bin bootloader/bootloader.bin \
5863
partition_table/partition-table.bin ota_data_initial.bin flasher_args.json > SHA256SUMS.txt
5964
6065
- name: Attach to the GitHub Release
6166
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
6267
with:
6368
generate_release_notes: true # auto "What's Changed" from commits/PRs since the last tag
6469
files: |
65-
firmware/esp32-matter/build/hisense_ac_matter.bin
66-
firmware/esp32-matter/build/hisense_ac_matter-debug.bin
70+
firmware/esp32-matter/build/hisense_ac_matter-CI-REBUILD.bin
71+
firmware/esp32-matter/build/hisense_ac_matter-debug-CI-REBUILD.bin
6772
firmware/esp32-matter/build/bootloader/bootloader.bin
6873
firmware/esp32-matter/build/partition_table/partition-table.bin
6974
firmware/esp32-matter/build/ota_data_initial.bin

firmware/scripts/esp32-release.sh

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,17 +257,42 @@ tag_release() {
257257

258258
# ---- top-level -----------------------------------------------------------------------------
259259
cmd="${1:-}"; shift || true
260+
# ---- publish the DEPLOYED artifacts to the GitHub release (#89) -------------------------------
261+
# Most acute on this target: delta OTA embeds the BASE image's hash and the device verifies it
262+
# against its running partition, so a patch built against a CI REBUILD is rejected. ESP-IDF builds
263+
# are not byte-reproducible (measured: rebuild c73d1de8 vs deployed 3d003d66), so the release asset
264+
# has to be the archived deployed .bin, not whatever CI produced. Losing that binary once already
265+
# stranded a node on USB-only flashing (#82).
266+
publish() {
267+
command -v gh >/dev/null || die "gh not on PATH -- needed to upload release assets"
268+
local rel semver base n=0
269+
rel="$(released_int)"
270+
[ "$rel" != 0 ] || die "no on-device version recorded -- run 'flash' first"
271+
semver="$(( rel / 10000 )).$(( (rel / 100) % 100 )).$(( rel % 100 ))"
272+
gh release view "esp32-v$semver" >/dev/null 2>&1 || die "no release esp32-v$semver -- push the tag first"
273+
base="$(int_to_semver_bin "$rel")" \
274+
|| die "deployed image (int $rel) not archived in built-images/ (#82) -- nothing trustworthy to publish"
275+
gh release upload "esp32-v$semver" "$base" --clobber >/dev/null && { say " uploaded $(basename "$base")"; n=1; }
276+
local f
277+
for f in "$IMG/esp32-v$rel.ota" "$IMG/esp32-v$rel.json"; do
278+
[ -f "$f" ] || continue
279+
gh release upload "esp32-v$semver" "$f" --clobber >/dev/null && { say " uploaded $(basename "$f")"; n=$((n+1)); }
280+
done
281+
say "published $n deployed artifact(s) to esp32-v$semver -- THIS is the valid delta base for the next release"
282+
}
283+
260284
case "$cmd" in
261285
build) build ;;
262286
package) package "${1:-}" ;;
263287
stage) stage ;;
264288
flash) flash ;;
265289
tag) tag_release ;;
290+
publish) publish ;;
266291
verint) cur_int ;;
267292
release)
268293
FLASH=0; for a in "$@"; do [ "$a" = --flash ] && FLASH=1; done
269294
build; package; stage
270295
[ "$FLASH" = 1 ] && flash || say "staged, not flashed. run: esp32-release.sh flash"
271296
;;
272-
*) die "usage: esp32-release.sh {build|package [--full]|stage|flash|tag|verint|release [--flash]}" ;;
297+
*) die "usage: esp32-release.sh {build|package [--full]|stage|flash|tag|publish|verint|release [--flash]}" ;;
273298
esac

firmware/scripts/ota-release.sh

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,40 @@ tag_release() { # create the path-prefixed semver tag amebaz2-vX.Y.Z locally (n
431431
432432
# ---- top-level -------------------------------------------------------------
433433
cmd="${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+
434468
case "$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]}" ;;
456491
esac

0 commit comments

Comments
 (0)