Merge branch 'main' of https://github.com/limengdu/Seeed-Homeassistan… #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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 |