name: Firmware CI on: push: paths: - 'firmware/**' - '.github/workflows/firmware-ci.yml' pull_request: paths: - 'firmware/**' - '.github/workflows/firmware-ci.yml' jobs: build: name: Build ESP32-S3 Firmware runs-on: ubuntu-latest container: image: espressif/idf:v5.2 steps: - uses: actions/checkout@v4 - name: Build firmware working-directory: firmware/esp32-csi-node run: | . $IDF_PATH/export.sh idf.py set-target esp32s3 idf.py build - name: Verify binary size (< 950 KB gate) working-directory: firmware/esp32-csi-node run: | BIN=build/esp32-csi-node.bin SIZE=$(stat -c%s "$BIN") MAX=$((950 * 1024)) echo "Binary size: $SIZE bytes ($(( SIZE / 1024 )) KB)" echo "Size limit: $MAX bytes (950 KB — includes Tier 3 WASM runtime)" if [ "$SIZE" -gt "$MAX" ]; then echo "::error::Firmware binary exceeds 950 KB size gate ($SIZE > $MAX)" exit 1 fi echo "Binary size OK: $SIZE <= $MAX" - name: Verify flash image integrity working-directory: firmware/esp32-csi-node run: | ERRORS=0 BIN=build/esp32-csi-node.bin # Check binary exists and is non-empty. if [ ! -s "$BIN" ]; then echo "::error::Binary not found or empty" exit 1 fi # Check partition table magic (0xAA50 at offset 0). PT=build/partition_table/partition-table.bin if [ -f "$PT" ]; then MAGIC=$(xxd -l2 -p "$PT") if [ "$MAGIC" != "aa50" ]; then echo "::warning::Partition table magic mismatch: $MAGIC (expected aa50)" ERRORS=$((ERRORS + 1)) fi fi # Check bootloader exists. BL=build/bootloader/bootloader.bin if [ ! -s "$BL" ]; then echo "::warning::Bootloader binary missing or empty" ERRORS=$((ERRORS + 1)) fi # Verify non-zero data in binary (not all 0xFF padding). NONZERO=$(xxd -l 1024 -p "$BIN" | tr -d 'f' | wc -c) if [ "$NONZERO" -lt 100 ]; then echo "::error::Binary appears to be mostly padding (non-zero chars: $NONZERO)" ERRORS=$((ERRORS + 1)) fi if [ "$ERRORS" -gt 0 ]; then echo "::warning::Flash image verification completed with $ERRORS warning(s)" else echo "Flash image integrity verified" fi - name: Check QEMU ESP32-S3 support status run: | echo "::notice::ESP32-S3 QEMU support is experimental in ESP-IDF v5.4. " echo "Full smoke testing requires QEMU 8.2+ with xtensa-esp32s3 target." echo "See: https://github.com/espressif/qemu/wiki" - name: Upload firmware artifact uses: actions/upload-artifact@v4 with: name: esp32-csi-node-firmware path: | firmware/esp32-csi-node/build/esp32-csi-node.bin firmware/esp32-csi-node/build/bootloader/bootloader.bin firmware/esp32-csi-node/build/partition_table/partition-table.bin retention-days: 30