From c71f7875c3120d89a000787cd87a50eb75664e94 Mon Sep 17 00:00:00 2001 From: "peter.marcisovsky" Date: Wed, 26 Nov 2025 18:29:37 +0100 Subject: [PATCH 1/2] feat(ci): Run esp-idf examples on targets - build and run esp-idf device and host examples - conditional run of the workflow --- .github/ci/.idf-build-examples-rules.yml | 6 - ...les.yml => build_and_run_idf_examples.yml} | 112 +++++++++++++++++- 2 files changed, 107 insertions(+), 11 deletions(-) rename .github/workflows/{build_idf_examples.yml => build_and_run_idf_examples.yml} (51%) diff --git a/.github/ci/.idf-build-examples-rules.yml b/.github/ci/.idf-build-examples-rules.yml index d2b09bbc3..ddf49a682 100644 --- a/.github/ci/.idf-build-examples-rules.yml +++ b/.github/ci/.idf-build-examples-rules.yml @@ -1,16 +1,10 @@ # Manifest file for build_idf_examples.yml CI workflow examples/peripherals/usb/device: - enable: - - if: (IDF_VERSION >= "6.0.0") - reason: Device examples have been updated to use esp_tinyusb 2.x only on esp-idf latest for now, TODO IDF-14282 disable: - if: SOC_USB_OTG_SUPPORTED != 1 examples/peripherals/usb/device/tusb_ncm: - enable: - - if: (IDF_VERSION >= "6.0.0") - reason: Device examples have been updated to use esp_tinyusb 2.x only on esp-idf latest for now, TODO IDF-14282 disable: - if: SOC_USB_OTG_SUPPORTED != 1 or SOC_WIFI_SUPPORTED != 1 diff --git a/.github/workflows/build_idf_examples.yml b/.github/workflows/build_and_run_idf_examples.yml similarity index 51% rename from .github/workflows/build_idf_examples.yml rename to .github/workflows/build_and_run_idf_examples.yml index 99777352a..a04aef86b 100644 --- a/.github/workflows/build_idf_examples.yml +++ b/.github/workflows/build_and_run_idf_examples.yml @@ -1,7 +1,8 @@ -# This workflow builds esp-idf examples: +# This workflow builds and runs usb host and usb device esp-idf examples with overridden local components: # +# Build: # - usb device examples: with overridden esp_tinyusb from esp-usb/device/esp_tinyusb -# - Override esp_tinyusb component only for IDF >= 6.0 temporarily +# - Override esp_tinyusb component only for IDF 5.1, IDF 5.3, IDF 5.5, IDF 6.0 and latest temporarily, others have not been backported # # - usb host examples: # - Overridden usb component from esp-usb/host/usb and overridden class drivers from esp-usb/host/class @@ -11,8 +12,19 @@ # # - cherryusb examples are ignored # - usb_host_lib example -> manifest file must be created for IDF < 6.0 to override usb component +# +# Run: +# - usb device examples: Run on usb_device target runners, with matrix of all listed releases +# - usb host examples: Run on usb_host_examples target runners, with matrix of all listed releases, except IDF Latest, IDF 6.0 and IDF 5.1 +# +# +# Temporarily disabled tests and TODOs of this workflow: +# - USB Device examples build: Only for only for IDF 5.1, IDF 5.3, IDF 5.5, IDF 6.0 and latest temporarily, others have not been backported +# - USB Host examples run: IDF latest and IDF 6.0 disabled (ECO4-ECO5 build-runner mismatch) +# - USB Device examples run: IDF latest and IDF 6.0 disabled (ECO4-ECO5 build-runner mismatch) +# - USB Device NCM example: Disabled due to GH Runner configuration (docker needs --net=host to access host network namespace) -name: Build ESP-IDF USB examples +name: Build and Run ESP-IDF USB examples on: pull_request: @@ -20,6 +32,12 @@ on: jobs: build: + # Condition: + # 1. PR title contains "release" (case-sensitive) + # 2. PR labels include "tests esp-idf" + if: | + contains(github.event.pull_request.title, 'release') || + contains(github.event.pull_request.labels.*.name, 'tests esp-idf') strategy: fail-fast: true matrix: @@ -51,8 +69,8 @@ jobs: - name: Setup IDF Examples path run: echo "EXAMPLES_PATH=${IDF_PATH}/examples/peripherals/usb" >> $GITHUB_ENV - name: Override device component - # Override esp_tinyusb component only for IDF >= 6.0 temporarily - if: contains('release-v6.0 latest', matrix.idf_ver) + # Override esp_tinyusb component only for IDF 5.1, IDF 5.3, IDF 5.5, IDF 6.0 and latest temporarily, others have not been backported + if: contains('release-v5.1 release-v5.3 release-v5.5 release-v6.0 latest', matrix.idf_ver) run: | . ${IDF_PATH}/export.sh python .github/ci/override_managed_component.py esp_tinyusb device/esp_tinyusb ${{ env.EXAMPLES_PATH }}/device/* @@ -126,3 +144,87 @@ jobs: idf-build-apps find --config-file ${CONFIG_PATH} --manifest-file ${MANIFEST_PATH} idf-build-apps build --config-file ${CONFIG_PATH} --manifest-file ${MANIFEST_PATH} + + - uses: actions/upload-artifact@v4 + with: + name: usb_examples_bin_${{ matrix.idf_ver }} + path: | + ${{ env.EXAMPLES_PATH }}/**/build_esp*/bootloader/bootloader.bin + ${{ env.EXAMPLES_PATH }}/**/build_esp*/partition_table/partition-table.bin + ${{ env.EXAMPLES_PATH }}/**/build_esp*/*.bin + ${{ env.EXAMPLES_PATH }}/**/build_esp*/*.elf + ${{ env.EXAMPLES_PATH }}/**/build_esp*/flasher_args.json + ${{ env.EXAMPLES_PATH }}/**/build_esp*/config/sdkconfig.json + if-no-files-found: error + + run-target: + name: Run esp-idf examples + if: ${{ github.repository_owner == 'espressif' }} + needs: build + strategy: + fail-fast: true + matrix: + idf_ver: + [ + "release-v5.1", + "release-v5.2", + "release-v5.3", + "release-v5.4", + "release-v5.5", + "release-v6.0", + "latest", + ] + idf_target: ["esp32s2", "esp32p4"] + runner_tag: ["usb_host_flash_disk", "usb_device"] + include: + - runner_tag: usb_host_flash_disk + example: host + - runner_tag: usb_device + example: device + exclude: + # Exclude esp32p4 for releases before IDF 5.3 for all runner tags (esp32p4 support starts in IDF 5.3) + - idf_ver: "release-v5.1" + idf_target: "esp32p4" + - idf_ver: "release-v5.2" + idf_target: "esp32p4" + # Exclude usb host examples run for IDF 5.1 - No pytest for host examples yet used + - idf_ver: "release-v5.1" + runner_tag: usb_host_flash_disk + # Temp exclude esp32p4 usb_host_flash_disk run for IDF Latest and 6.0 (ECO4-ECO5 build-runner mismatch) + - runner_tag: usb_host_flash_disk + idf_ver: "latest" + - runner_tag: usb_host_flash_disk + idf_ver: "release-v6.0" + - runner_tag: usb_device + idf_ver: "latest" + - runner_tag: usb_device + idf_ver: "release-v6.0" + runs-on: [self-hosted, linux, docker, "${{ matrix.idf_target }}", "${{ matrix.runner_tag }}"] + container: + image: espressif/idf:${{ matrix.idf_ver }} + options: --privileged --device-cgroup-rule="c 188:* rmw" --device-cgroup-rule="c 166:* rmw" + env: + EXAMPLES_PATH: ${{ github.workspace }} + steps: + - name: ⚙️ Install System tools + run: | + apt update + apt install net-tools + - name: Setup IDF Examples path + run: echo "EXAMPLES_PATH=${IDF_PATH}/examples/peripherals/usb" >> $GITHUB_ENV + - name: ⚙️ Install Python packages + env: + PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/" + run: | + cd ${IDF_PATH} + . ./export.sh + pip install --no-cache-dir --only-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf pyserial pyusb netifaces idf-ci pytest_ignore_test_results + - uses: actions/download-artifact@v4 + with: + name: usb_examples_bin_${{ matrix.idf_ver }} + path: ${{ env.EXAMPLES_PATH }} + - name: Run USB Test App on target + run: | + cd ${IDF_PATH} + . ./export.sh + pytest ${{ env.EXAMPLES_PATH }}/${{ matrix.example }} --target ${{ matrix.idf_target }} -m ${{ matrix.runner_tag }} --ignore-result-cases=*ncm_example From b3f015dd37ba605961097308d99fe40242d3ae8d Mon Sep 17 00:00:00 2001 From: "peter.marcisovsky" Date: Thu, 11 Dec 2025 17:00:56 +0100 Subject: [PATCH 2/2] fix(ci): Dont use idf container on RPI runners --- .../workflows/build_and_run_idf_examples.yml | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build_and_run_idf_examples.yml b/.github/workflows/build_and_run_idf_examples.yml index a04aef86b..025bdc4f8 100644 --- a/.github/workflows/build_and_run_idf_examples.yml +++ b/.github/workflows/build_and_run_idf_examples.yml @@ -146,6 +146,7 @@ jobs: idf-build-apps build --config-file ${CONFIG_PATH} --manifest-file ${MANIFEST_PATH} - uses: actions/upload-artifact@v4 + # Upload build files, pytest files and sdkconfig files with: name: usb_examples_bin_${{ matrix.idf_ver }} path: | @@ -155,6 +156,8 @@ jobs: ${{ env.EXAMPLES_PATH }}/**/build_esp*/*.elf ${{ env.EXAMPLES_PATH }}/**/build_esp*/flasher_args.json ${{ env.EXAMPLES_PATH }}/**/build_esp*/config/sdkconfig.json + ${{ env.EXAMPLES_PATH }}/**/pytest_*.py + ${{ env.EXAMPLES_PATH }}/**/sdkconfig.* if-no-files-found: error run-target: @@ -166,10 +169,10 @@ jobs: matrix: idf_ver: [ - "release-v5.1", - "release-v5.2", - "release-v5.3", - "release-v5.4", + #"release-v5.1", + #"release-v5.2", + #"release-v5.3", + #"release-v5.4", "release-v5.5", "release-v6.0", "latest", @@ -177,31 +180,36 @@ jobs: idf_target: ["esp32s2", "esp32p4"] runner_tag: ["usb_host_flash_disk", "usb_device"] include: + # Assign a folder structure to a target runner - runner_tag: usb_host_flash_disk example: host - runner_tag: usb_device example: device exclude: - # Exclude esp32p4 for releases before IDF 5.3 for all runner tags (esp32p4 support starts in IDF 5.3) - - idf_ver: "release-v5.1" - idf_target: "esp32p4" - - idf_ver: "release-v5.2" - idf_target: "esp32p4" - # Exclude usb host examples run for IDF 5.1 - No pytest for host examples yet used - - idf_ver: "release-v5.1" - runner_tag: usb_host_flash_disk +# # Exclude esp32p4 for releases before IDF 5.3 for all runner tags (esp32p4 support starts in IDF 5.3) +# - idf_ver: "release-v5.1" +# idf_target: "esp32p4" +# - idf_ver: "release-v5.2" +# idf_target: "esp32p4" +# # Exclude usb host examples run for IDF 5.1 - No pytest for host examples yet used +# - idf_ver: "release-v5.1" +# runner_tag: usb_host_flash_disk # Temp exclude esp32p4 usb_host_flash_disk run for IDF Latest and 6.0 (ECO4-ECO5 build-runner mismatch) - runner_tag: usb_host_flash_disk idf_ver: "latest" + idf_target: "esp32p4" - runner_tag: usb_host_flash_disk idf_ver: "release-v6.0" + idf_target: "esp32p4" - runner_tag: usb_device idf_ver: "latest" + idf_target: "esp32p4" - runner_tag: usb_device idf_ver: "release-v6.0" + idf_target: "esp32p4" runs-on: [self-hosted, linux, docker, "${{ matrix.idf_target }}", "${{ matrix.runner_tag }}"] container: - image: espressif/idf:${{ matrix.idf_ver }} + image: python:3.11-bookworm options: --privileged --device-cgroup-rule="c 188:* rmw" --device-cgroup-rule="c 166:* rmw" env: EXAMPLES_PATH: ${{ github.workspace }} @@ -211,20 +219,16 @@ jobs: apt update apt install net-tools - name: Setup IDF Examples path - run: echo "EXAMPLES_PATH=${IDF_PATH}/examples/peripherals/usb" >> $GITHUB_ENV + run: | + mkdir idf_examples && cd idf_examples && pwd + echo "EXAMPLES_PATH=$(pwd)" >> $GITHUB_ENV - name: ⚙️ Install Python packages env: PIP_EXTRA_INDEX_URL: "https://dl.espressif.com/pypi/" - run: | - cd ${IDF_PATH} - . ./export.sh - pip install --no-cache-dir --only-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf pyserial pyusb netifaces idf-ci pytest_ignore_test_results + run: pip install --only-binary cryptography pytest-embedded pytest-embedded-serial-esp pytest-embedded-idf pyserial pyusb netifaces pytest-ignore-test-results idf-ci - uses: actions/download-artifact@v4 with: name: usb_examples_bin_${{ matrix.idf_ver }} path: ${{ env.EXAMPLES_PATH }} - name: Run USB Test App on target - run: | - cd ${IDF_PATH} - . ./export.sh - pytest ${{ env.EXAMPLES_PATH }}/${{ matrix.example }} --target ${{ matrix.idf_target }} -m ${{ matrix.runner_tag }} --ignore-result-cases=*ncm_example + run: pytest ${{ env.EXAMPLES_PATH }}/${{ matrix.example }} --target ${{ matrix.idf_target }} -m ${{ matrix.runner_tag }} --ignore-result-cases=*ncm_example