Skip to content

Merge branch 'main' of https://github.com/limengdu/Seeed-Homeassistan… #20

Merge branch 'main' of https://github.com/limengdu/Seeed-Homeassistan…

Merge branch 'main' of https://github.com/limengdu/Seeed-Homeassistan… #20

# GitHub Actions workflow for compiling Arduino firmware
# 用于编译 Arduino 固件的 GitHub Actions 工作流
#
# Firmware Categories | 固件分类:
# 1. Seeed-specific: Only works on specific Seeed hardware
# Seeed 专用:仅适用于特定 Seeed 硬件
# 2. Universal: Works on any ESP32 (auto chip detection)
# 通用固件:适用于任意 ESP32(自动芯片检测)
name: Build Firmware
on:
push:
branches: [main, master]
paths:
- 'arduino/**'
- '.github/workflows/build-firmware.yml'
pull_request:
paths:
- 'arduino/**'
workflow_dispatch:
inputs:
build_all:
description: 'Build all firmware'
required: false
default: 'true'
type: boolean
env:
ESP32_CORE_VERSION: "3.3.4"
ARDUINOJSON_VERSION: "7.4.2"
WEBSOCKETS_VERSION: "2.7.1"
NEOPIXEL_VERSION: "1.15.2"
jobs:
# ============================================================================
# DETECT CHANGES | 检测文件变化
# ============================================================================
detect-changes:
runs-on: ubuntu-latest
outputs:
library: ${{ steps.filter.outputs.library }}
iot-button: ${{ steps.filter.outputs.iot-button }}
camera-stream: ${{ steps.filter.outputs.camera-stream }}
reterminal-e1001: ${{ steps.filter.outputs.reterminal-e1001 }}
reterminal-e1002: ${{ steps.filter.outputs.reterminal-e1002 }}
wifi-provisioning: ${{ steps.filter.outputs.wifi-provisioning }}
button-switch: ${{ steps.filter.outputs.button-switch }}
led-switch: ${{ steps.filter.outputs.led-switch }}
ha-state-subscribe: ${{ steps.filter.outputs.ha-state-subscribe }}
temp-humidity: ${{ steps.filter.outputs.temp-humidity }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
library:
- 'arduino/SeeedHADiscovery/src/**'
- 'arduino/SeeedHADiscovery/library.*'
- '.github/workflows/build-firmware.yml'
iot-button:
- 'arduino/SeeedHADiscovery/examples/IoTButtonV2_DeepSleep/**'
camera-stream:
- 'arduino/SeeedHADiscovery/examples/CameraStream/**'
reterminal-e1001:
- 'arduino/SeeedHADiscovery/examples/reTerminal_E1001_HASubscribe_Display/**'
reterminal-e1002:
- 'arduino/SeeedHADiscovery/examples/reTerminal_E1002_HASubscribe_Display/**'
wifi-provisioning:
- 'arduino/SeeedHADiscovery/examples/WiFiProvisioning/**'
button-switch:
- 'arduino/SeeedHADiscovery/examples/ButtonSwitch/**'
led-switch:
- 'arduino/SeeedHADiscovery/examples/LEDSwitch/**'
ha-state-subscribe:
- 'arduino/SeeedHADiscovery/examples/HAStateSubscribe/**'
temp-humidity:
- 'arduino/SeeedHADiscovery/examples/TemperatureHumidity/**'
# ============================================================================
# SEEED-SPECIFIC FIRMWARE | SEEED 专用固件
# ============================================================================
# IoT Button V2 - XIAO ESP32-C6 only
build-iot-button:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.iot-button == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Arduino CLI
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
- name: Install dependencies
run: |
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
# Install libraries with retry mechanism for network issues
for i in 1 2 3; do arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}" && break || sleep 10; done
for i in 1 2 3; do arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}" && break || sleep 10; done
for i in 1 2 3; do arduino-cli lib install "Adafruit NeoPixel@${{ env.NEOPIXEL_VERSION }}" && break || sleep 10; done
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
- name: Compile
run: |
mkdir -p build/IoTButtonV2_DeepSleep
arduino-cli compile --fqbn "esp32:esp32:XIAO_ESP32C6:CDCOnBoot=cdc,PartitionScheme=huge_app,FlashMode=qio,FlashSize=4M" \
--output-dir "build/IoTButtonV2_DeepSleep" --export-binaries \
"arduino/SeeedHADiscovery/examples/IoTButtonV2_DeepSleep/IoTButtonV2_DeepSleep.ino"
- name: Prepare firmware
run: |
cd build/IoTButtonV2_DeepSleep
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin
cat > manifest.json << 'EOF'
{"name":"IoT Button V2 (XIAO ESP32-C6)","version":"1.0.0","new_install_prompt_erase":true,"builds":[{"chipFamily":"ESP32-C6","parts":[{"path":"bootloader.bin","offset":0},{"path":"partitions.bin","offset":32768},{"path":"boot_app0.bin","offset":57344},{"path":"firmware.bin","offset":65536}]}]}
EOF
- uses: actions/upload-artifact@v4
with:
name: firmware-IoTButtonV2_DeepSleep
path: build/IoTButtonV2_DeepSleep/
# Camera Stream - XIAO ESP32-S3 Sense only
build-camera-stream:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.camera-stream == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Arduino CLI
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
- name: Install dependencies
run: |
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
- name: Compile
run: |
mkdir -p build/CameraStream
arduino-cli compile --fqbn "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,PSRAM=opi,FlashMode=qio,FlashSize=8M" \
--output-dir "build/CameraStream" --export-binaries \
"arduino/SeeedHADiscovery/examples/CameraStream/CameraStream.ino"
- name: Prepare firmware
run: |
cd build/CameraStream
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin
cat > manifest.json << 'EOF'
{"name":"Camera Stream (XIAO ESP32-S3 Sense)","version":"1.0.0","new_install_prompt_erase":true,"builds":[{"chipFamily":"ESP32-S3","parts":[{"path":"bootloader.bin","offset":0},{"path":"partitions.bin","offset":32768},{"path":"boot_app0.bin","offset":57344},{"path":"firmware.bin","offset":65536}]}]}
EOF
- uses: actions/upload-artifact@v4
with:
name: firmware-CameraStream
path: build/CameraStream/
# reTerminal E1001 - ESP32-S3 based
build-reterminal-e1001:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.reterminal-e1001 == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Arduino CLI
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
- name: Install dependencies
run: |
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
git clone https://github.com/Seeed-Studio/Seeed_GFX.git ~/Arduino/libraries/Seeed_GFX
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
- name: Compile
run: |
mkdir -p build/reTerminal_E1001
arduino-cli compile --fqbn "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,PSRAM=opi,FlashMode=qio,FlashSize=8M" \
--output-dir "build/reTerminal_E1001" --export-binaries \
"arduino/SeeedHADiscovery/examples/reTerminal_E1001_HASubscribe_Display/reTerminal_E1001_HASubscribe_Display.ino"
- name: Prepare firmware
run: |
cd build/reTerminal_E1001
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin 2>/dev/null || true
cat > manifest.json << 'EOF'
{"name":"reTerminal E1001 Dashboard","version":"1.0.0","new_install_prompt_erase":true,"builds":[{"chipFamily":"ESP32-S3","parts":[{"path":"bootloader.bin","offset":0},{"path":"partitions.bin","offset":32768},{"path":"boot_app0.bin","offset":57344},{"path":"firmware.bin","offset":65536}]}]}
EOF
continue-on-error: true
- uses: actions/upload-artifact@v4
with:
name: firmware-reTerminal_E1001
path: build/reTerminal_E1001/
continue-on-error: true
# reTerminal E1002 - ESP32-S3 based
build-reterminal-e1002:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.reterminal-e1002 == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Arduino CLI
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
- name: Install dependencies
run: |
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
git clone https://github.com/Seeed-Studio/Seeed_GFX.git ~/Arduino/libraries/Seeed_GFX
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
- name: Compile
run: |
mkdir -p build/reTerminal_E1002
arduino-cli compile --fqbn "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,PSRAM=opi,FlashMode=qio,FlashSize=8M" \
--output-dir "build/reTerminal_E1002" --export-binaries \
"arduino/SeeedHADiscovery/examples/reTerminal_E1002_HASubscribe_Display/reTerminal_E1002_HASubscribe_Display.ino"
- name: Prepare firmware
run: |
cd build/reTerminal_E1002
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin 2>/dev/null || true
cat > manifest.json << 'EOF'
{"name":"reTerminal E1002 Dashboard","version":"1.0.0","new_install_prompt_erase":true,"builds":[{"chipFamily":"ESP32-S3","parts":[{"path":"bootloader.bin","offset":0},{"path":"partitions.bin","offset":32768},{"path":"boot_app0.bin","offset":57344},{"path":"firmware.bin","offset":65536}]}]}
EOF
continue-on-error: true
- uses: actions/upload-artifact@v4
with:
name: firmware-reTerminal_E1002
path: build/reTerminal_E1002/
continue-on-error: true
# ============================================================================
# UNIVERSAL FIRMWARE (Multi-chip) | 通用固件(多芯片)
# ============================================================================
# WiFi Provisioning - Universal (using XIAO boards for D-pin compatibility)
build-wifi-provisioning:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.wifi-provisioning == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- chip: C3
fqbn: "esp32:esp32:XIAO_ESP32C3:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C3"
- chip: C5
fqbn: "esp32:esp32:XIAO_ESP32C5:CDCOnBoot=cdc,PartitionScheme=default_8MB,FlashMode=qio,FlashSize=8M"
family: "ESP32-C5"
- chip: C6
fqbn: "esp32:esp32:XIAO_ESP32C6:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C6"
- chip: S3
fqbn: "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,FlashMode=qio,FlashSize=8M,PSRAM=opi"
family: "ESP32-S3"
steps:
- uses: actions/checkout@v4
- name: Setup and compile
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
mkdir -p build/WiFiProvisioning/${{ matrix.chip }}
arduino-cli compile --fqbn "${{ matrix.fqbn }}" --output-dir "build/WiFiProvisioning/${{ matrix.chip }}" --export-binaries \
"arduino/SeeedHADiscovery/examples/WiFiProvisioning/WiFiProvisioning.ino"
- name: Prepare firmware
run: |
cd build/WiFiProvisioning/${{ matrix.chip }}
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin
- uses: actions/upload-artifact@v4
with:
name: firmware-WiFiProvisioning-${{ matrix.chip }}
path: build/WiFiProvisioning/${{ matrix.chip }}/
# Button Switch - Universal (using XIAO boards for D-pin compatibility)
build-button-switch:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.button-switch == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- chip: C3
fqbn: "esp32:esp32:XIAO_ESP32C3:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C3"
- chip: C5
fqbn: "esp32:esp32:XIAO_ESP32C5:CDCOnBoot=cdc,PartitionScheme=default_8MB,FlashMode=qio,FlashSize=8M"
family: "ESP32-C5"
- chip: C6
fqbn: "esp32:esp32:XIAO_ESP32C6:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C6"
- chip: S3
fqbn: "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,FlashMode=qio,FlashSize=8M,PSRAM=opi"
family: "ESP32-S3"
steps:
- uses: actions/checkout@v4
- name: Setup and compile
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
mkdir -p build/ButtonSwitch/${{ matrix.chip }}
arduino-cli compile --fqbn "${{ matrix.fqbn }}" --output-dir "build/ButtonSwitch/${{ matrix.chip }}" --export-binaries \
"arduino/SeeedHADiscovery/examples/ButtonSwitch/ButtonSwitch.ino"
- name: Prepare firmware
run: |
cd build/ButtonSwitch/${{ matrix.chip }}
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin
- uses: actions/upload-artifact@v4
with:
name: firmware-ButtonSwitch-${{ matrix.chip }}
path: build/ButtonSwitch/${{ matrix.chip }}/
# LED Switch - Universal (using XIAO boards for LED_BUILTIN compatibility)
# Note: XIAO ESP32-C3 has no user LED, so C3 is excluded
build-led-switch:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.led-switch == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- chip: C5
fqbn: "esp32:esp32:XIAO_ESP32C5:CDCOnBoot=cdc,PartitionScheme=default_8MB,FlashMode=qio,FlashSize=8M"
family: "ESP32-C5"
- chip: C6
fqbn: "esp32:esp32:XIAO_ESP32C6:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C6"
- chip: S3
fqbn: "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,FlashMode=qio,FlashSize=8M,PSRAM=opi"
family: "ESP32-S3"
steps:
- uses: actions/checkout@v4
- name: Setup and compile
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
mkdir -p build/LEDSwitch/${{ matrix.chip }}
arduino-cli compile --fqbn "${{ matrix.fqbn }}" --output-dir "build/LEDSwitch/${{ matrix.chip }}" --export-binaries \
"arduino/SeeedHADiscovery/examples/LEDSwitch/LEDSwitch.ino"
- name: Prepare firmware
run: |
cd build/LEDSwitch/${{ matrix.chip }}
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin
- uses: actions/upload-artifact@v4
with:
name: firmware-LEDSwitch-${{ matrix.chip }}
path: build/LEDSwitch/${{ matrix.chip }}/
# HA State Subscribe - Universal (using XIAO boards)
build-ha-state-subscribe:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.ha-state-subscribe == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- chip: C3
fqbn: "esp32:esp32:XIAO_ESP32C3:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C3"
- chip: C5
fqbn: "esp32:esp32:XIAO_ESP32C5:CDCOnBoot=cdc,PartitionScheme=default_8MB,FlashMode=qio,FlashSize=8M"
family: "ESP32-C5"
- chip: C6
fqbn: "esp32:esp32:XIAO_ESP32C6:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C6"
- chip: S3
fqbn: "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,FlashMode=qio,FlashSize=8M,PSRAM=opi"
family: "ESP32-S3"
steps:
- uses: actions/checkout@v4
- name: Setup and compile
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
mkdir -p build/HAStateSubscribe/${{ matrix.chip }}
arduino-cli compile --fqbn "${{ matrix.fqbn }}" --output-dir "build/HAStateSubscribe/${{ matrix.chip }}" --export-binaries \
"arduino/SeeedHADiscovery/examples/HAStateSubscribe/HAStateSubscribe.ino"
- name: Prepare firmware
run: |
cd build/HAStateSubscribe/${{ matrix.chip }}
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin
- uses: actions/upload-artifact@v4
with:
name: firmware-HAStateSubscribe-${{ matrix.chip }}
path: build/HAStateSubscribe/${{ matrix.chip }}/
# Temperature Humidity - Universal (using XIAO boards)
build-temp-humidity:
needs: detect-changes
if: ${{ github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.library == 'true' || needs.detect-changes.outputs.temp-humidity == 'true' }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- chip: C3
fqbn: "esp32:esp32:XIAO_ESP32C3:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C3"
- chip: C5
fqbn: "esp32:esp32:XIAO_ESP32C5:CDCOnBoot=cdc,PartitionScheme=default_8MB,FlashMode=qio,FlashSize=8M"
family: "ESP32-C5"
- chip: C6
fqbn: "esp32:esp32:XIAO_ESP32C6:CDCOnBoot=cdc,PartitionScheme=default,FlashMode=qio,FlashSize=4M"
family: "ESP32-C6"
- chip: S3
fqbn: "esp32:esp32:XIAO_ESP32S3:CDCOnBoot=cdc,PartitionScheme=default_8MB,USBMode=hwcdc,FlashMode=qio,FlashSize=8M,PSRAM=opi"
family: "ESP32-S3"
steps:
- uses: actions/checkout@v4
- name: Setup and compile
run: |
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=/usr/local/bin sh
arduino-cli config init
arduino-cli config add board_manager.additional_urls "https://espressif.github.io/arduino-esp32/package_esp32_index.json"
arduino-cli core update-index
arduino-cli core install esp32:esp32@${{ env.ESP32_CORE_VERSION }}
arduino-cli lib install "ArduinoJson@${{ env.ARDUINOJSON_VERSION }}"
arduino-cli lib install "WebSockets@${{ env.WEBSOCKETS_VERSION }}"
mkdir -p ~/Arduino/libraries && cp -r arduino/SeeedHADiscovery ~/Arduino/libraries/
mkdir -p build/TemperatureHumidity/${{ matrix.chip }}
arduino-cli compile --fqbn "${{ matrix.fqbn }}" --output-dir "build/TemperatureHumidity/${{ matrix.chip }}" --export-binaries \
"arduino/SeeedHADiscovery/examples/TemperatureHumidity/TemperatureHumidity.ino"
- name: Prepare firmware
run: |
cd build/TemperatureHumidity/${{ matrix.chip }}
for f in *.bin; do
[[ "$f" == *".ino.bin" ]] && mv "$f" "firmware.bin"
[[ "$f" == *".bootloader.bin" ]] && mv "$f" "bootloader.bin"
[[ "$f" == *".partitions.bin" ]] && mv "$f" "partitions.bin"
done
cp $(find ~/.arduino15/packages/esp32 -name "boot_app0.bin" -type f | head -1) ./boot_app0.bin
- uses: actions/upload-artifact@v4
with:
name: firmware-TemperatureHumidity-${{ matrix.chip }}
path: build/TemperatureHumidity/${{ matrix.chip }}/
# ============================================================================
# COMBINE & RELEASE | 合并与发布
# ============================================================================
combine:
needs: [detect-changes, build-iot-button, build-camera-stream, build-reterminal-e1001, build-reterminal-e1002, build-wifi-provisioning, build-button-switch, build-led-switch, build-ha-state-subscribe, build-temp-humidity]
if: always() && !cancelled()
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: all-firmware/
pattern: firmware-*
continue-on-error: true
- name: Organize firmware
run: |
mkdir -p combined-firmware
# Single-chip firmware (Seeed-specific)
for fw in IoTButtonV2_DeepSleep CameraStream reTerminal_E1001 reTerminal_E1002; do
if [ -d "all-firmware/firmware-${fw}" ]; then
cp -r "all-firmware/firmware-${fw}" "combined-firmware/${fw}"
echo "Added: ${fw}"
fi
done
# Multi-chip firmware (Universal) - create manifest with all chips
for fw in WiFiProvisioning ButtonSwitch LEDSwitch HAStateSubscribe TemperatureHumidity; do
mkdir -p "combined-firmware/${fw}"
for chip in C3 C5 C6 S3; do
if [ -d "all-firmware/firmware-${fw}-${chip}" ]; then
mkdir -p "combined-firmware/${fw}/${chip}"
cp -r "all-firmware/firmware-${fw}-${chip}/"* "combined-firmware/${fw}/${chip}/"
echo "Added: ${fw}/${chip}"
fi
done
# Create multi-chip manifest
if [ -d "combined-firmware/${fw}/C3" ] || [ -d "combined-firmware/${fw}/C5" ] || [ -d "combined-firmware/${fw}/C6" ] || [ -d "combined-firmware/${fw}/S3" ]; then
echo '{"name":"'"${fw}"'","version":"1.0.0","new_install_prompt_erase":true,"builds":[' > "combined-firmware/${fw}/manifest.json"
FIRST=true
for chip in C3 C5 C6 S3; do
if [ -d "combined-firmware/${fw}/${chip}" ]; then
[ "$FIRST" = false ] && echo ',' >> "combined-firmware/${fw}/manifest.json"
FIRST=false
FAMILY="ESP32-${chip}"
echo '{"chipFamily":"'"${FAMILY}"'","parts":[{"path":"'"${chip}"'/bootloader.bin","offset":0},{"path":"'"${chip}"'/partitions.bin","offset":32768},{"path":"'"${chip}"'/boot_app0.bin","offset":57344},{"path":"'"${chip}"'/firmware.bin","offset":65536}]}' >> "combined-firmware/${fw}/manifest.json"
fi
done
echo ']}' >> "combined-firmware/${fw}/manifest.json"
echo "Created manifest for ${fw}"
fi
done
echo ""
echo "Final structure:"
find combined-firmware -type f | head -50
- uses: actions/upload-artifact@v4
with:
name: all-firmware
path: combined-firmware/
retention-days: 90
release:
needs: combine
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
name: all-firmware
path: firmware/
continue-on-error: true
- name: Package and release
run: |
if [ ! -d "firmware" ] || [ -z "$(ls -A firmware 2>/dev/null)" ]; then
echo "No firmware to release"
exit 0
fi
VERSION=$(date +'%Y.%m.%d')-$(git rev-parse --short HEAD)
cd firmware
for dir in */; do
name="${dir%/}"
zip -r "${name}.zip" "$dir"
done
cd ..
zip -r "all-firmware.zip" firmware/
mv all-firmware.zip firmware/
CHANGELOG=$(git log $(git describe --tags --abbrev=0 2>/dev/null || echo "")..HEAD --pretty=format:"- %s" --no-merges 2>/dev/null | head -20 || echo "- Initial release")
cat > release_body.md << EOF
## 🚀 Firmware Release
### 📦 Seeed-Specific Firmware
| Firmware | Hardware | Description |
|----------|----------|-------------|
| IoTButtonV2_DeepSleep | XIAO ESP32-C6 | Low-power IoT button |
| CameraStream | XIAO ESP32-S3 Sense | Camera streaming |
| reTerminal_E1001 | reTerminal E1001 | E-Paper dashboard |
| reTerminal_E1002 | reTerminal E1002 | Color E-Paper dashboard |
### 📦 Universal Firmware (Auto Chip Detection)
| Firmware | Supported Chips | Description |
|----------|-----------------|-------------|
| WiFiProvisioning | C3/C5/C6/S3 | WiFi setup demo |
| ButtonSwitch | C3/C5/C6/S3 | Button control |
| LEDSwitch | C3/C5/C6/S3 | LED control |
| HAStateSubscribe | C3/C5/C6/S3 | HA state display |
| TemperatureHumidity | C3/C5/C6/S3 | Sensor demo |
### 📝 Changelog
${CHANGELOG}
---
**Build Info:** ESP32 Core ${{ env.ESP32_CORE_VERSION }} | $(date -u '+%Y-%m-%d %H:%M UTC')
EOF
echo "version=${VERSION}" >> $GITHUB_OUTPUT
id: prep
- uses: softprops/action-gh-release@v1
with:
tag_name: firmware-${{ steps.prep.outputs.version }}
name: Firmware ${{ steps.prep.outputs.version }}
body_path: release_body.md
files: firmware/*.zip
if: steps.prep.outputs.version != ''
# Deploy firmware to GitHub Pages (docs/flasher/firmware/)
deploy-flasher:
needs: combine
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: all-firmware
path: firmware-temp/
continue-on-error: true
- name: Deploy to docs/flasher/firmware
run: |
if [ ! -d "firmware-temp" ] || [ -z "$(ls -A firmware-temp 2>/dev/null)" ]; then
echo "No firmware to deploy"
exit 0
fi
# Clear existing firmware (but keep the directory structure)
rm -rf docs/flasher/firmware/*
mkdir -p docs/flasher/firmware
# Copy all firmware to docs folder
cp -r firmware-temp/* docs/flasher/firmware/
echo "Deployed firmware:"
find docs/flasher/firmware -type f | head -50
- name: Commit and push firmware
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
# Check if there are changes to commit
if git diff --quiet docs/flasher/firmware/; then
echo "No changes to commit"
exit 0
fi
git add docs/flasher/firmware/
git commit -m "chore: deploy firmware to web flasher [skip ci]"
git push