Skip to content

ci: build both esp32 targets per tag, and shorten release asset names… #17

ci: build both esp32 targets per tag, and shorten release asset names…

ci: build both esp32 targets per tag, and shorten release asset names… #17

Workflow file for this run

name: ESP32 firmware release
# On an `esp32-vX.Y.Z` tag: build BOTH supported targets and attach them to the one GitHub Release.
# Runs on the same self-hosted `sdk-builder` runner as the AmebaZ2 build, reusing its installed
# ESP-IDF + esp-matter (a cold esp-matter bootstrap in a hosted container is slow and fragile). The
# runner must export two paths so none leak into this workflow:
# IDF_EXPORT = <esp-idf>/export.sh (the IDF matching versions.env IDF_PIN)
# ESP_MATTER_EXPORT = <esp-matter>/export.sh
# Tag-push only, so fork PRs can't reach the runner. stage/flash stay manual.
on:
push:
tags: ['esp32-v[0-9]+.[0-9]+.[0-9]+']
permissions:
contents: write
jobs:
build:
# GitHub-only: Gitea auto-reads .github/workflows but its runner is labeled `sdk-builder`
# (not `self-hosted`), so this runs-on would never match there. Skip on Gitea.
if: ${{ github.server_url == 'https://github.com' }}
runs-on: [self-hosted, sdk-builder]
strategy:
# One release, two architectures. Serialised on purpose: both jobs attach to the SAME
# release, and running them in parallel races on creating it. The builds are minutes, not
# hours, so sequential is the cheap way to keep the upload deterministic.
max-parallel: 1
fail-fast: false
matrix:
# esp32 = classic Xtensa dev board
# esp32c3 = ESP32-C3 SuperMini (the deployed module). Images are NOT interchangeable:
# different architectures entirely, so publishing only one silently ships the wrong
# binary for half the fleet. The per-target sdkconfig.defaults.<target> overlay is
# picked up automatically by IDF.
target: [esp32, esp32c3]
defaults:
run:
shell: bash # ESP-IDF export.sh + esp-matter export.sh are bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Tag must match CMake PROJECT_VER
run: |
tag_ver="${GITHUB_REF_NAME#esp32-v}"
cmake_ver=$(sed -n 's/^set(PROJECT_VER "\(.*\)").*/\1/p' firmware/esp32-matter/CMakeLists.txt)
[ "$tag_ver" = "$cmake_ver" ] || { echo "::error::tag esp32-v$tag_ver != PROJECT_VER $cmake_ver"; exit 1; }
# Both flavours are published (#22). Separate build dirs so neither clobbers the other, and
# RELEASE is built last so build/ ends up holding the image users should deploy. The version
# int is identical for both by design; the flavour lives in the FILENAME.
- name: Build both flavours for ${{ matrix.target }}
run: |
: "${IDF_EXPORT:?set IDF_EXPORT on the runner to the esp-idf export.sh path}"
: "${ESP_MATTER_EXPORT:?set ESP_MATTER_EXPORT on the runner to the esp-matter export.sh path}"
# shellcheck disable=SC1090
. "$IDF_EXPORT"
# shellcheck disable=SC1090
. "$ESP_MATTER_EXPORT"
cd firmware/esp32-matter
idf.py set-target "${{ matrix.target }}"
idf.py -B build.debug -DSDKCONFIG=sdkconfig.ci.debug \
-DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.debug" build
idf.py build
- name: Collect artifacts + checksums
run: |
# #89: ESP-IDF builds are not byte-reproducible, so these are NOT the deployed images.
# Critically, delta OTA verifies the BASE image's hash, so a patch built against these
# files is rejected by the device. The valid delta base is uploaded under the canonical
# name by `esp32-release.sh publish` from the box that flashed the node. That warning
# used to live in a "-CI-REBUILD" filename; it now lives in the release body, so the
# asset names can stay short without losing the caveat.
cd firmware/esp32-matter
t='${{ matrix.target }}'
v="${GITHUB_REF_NAME#esp32-v}"
out=release-assets
rm -rf "$out"; mkdir -p "$out"
cp build.debug/hisense_ac_matter.bin "$out/$t-v$v-debug.bin"
cp build/hisense_ac_matter.bin "$out/$t-v$v.bin"
cp build/bootloader/bootloader.bin "$out/$t-bootloader.bin"
cp build/partition_table/partition-table.bin "$out/$t-partition-table.bin"
cp build/ota_data_initial.bin "$out/$t-ota-data.bin"
cp build/flasher_args.json "$out/$t-flasher-args.json"
# Checksum the payload only -- globbing after the sums file exists would try to hash it
# while it is being written.
cd "$out"
sha256sum "$t-v$v.bin" "$t-v$v-debug.bin" "$t-bootloader.bin" \
"$t-partition-table.bin" "$t-ota-data.bin" "$t-flasher-args.json" \
> "$t-SHA256SUMS.txt"
- name: Attach ${{ matrix.target }} to the GitHub Release
uses: softprops/action-gh-release@3d0d9888cb7fd7b750713d6e236d1fcb99157228 # v3.0.2
with:
generate_release_notes: true # auto "What's Changed" from commits/PRs since the last tag
append_body: true
body: |
**Targets:** `esp32` (classic Xtensa dev board) and `esp32c3` (SuperMini).
The images are architecture-specific and **not interchangeable** -- flash the set
matching your board.
Each target ships a `release` and a `-debug` flavour. The debug flavour adds the
unauthenticated `:2323` diagnostic console and is for bench units only.
> These binaries are **CI rebuilds, not the deployed images**. ESP-IDF builds are not
> byte-reproducible and delta OTA verifies the base image's hash, so a patch generated
> against these files will be rejected by the device. The canonical delta base is
> published separately by `esp32-release.sh publish` from the machine that flashed the
> node (#89).
files: firmware/esp32-matter/release-assets/*