diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc3003358d..fdd26aaa76 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,9 +76,13 @@ jobs: run: pip install -r requirements.txt - name: Build firmware - run: pio run -e ${{ matrix.environment }} + env: + BUILD_ENV: ${{ matrix.environment }} + run: pio run -e "$BUILD_ENV" - name: Get artifact name from bin filename id: artifact_name + env: + BUILD_ENV: ${{ matrix.environment }} run: | bin=$(ls build_output/release/*.bin 2>/dev/null | head -1) if [ -n "$bin" ]; then @@ -87,7 +91,7 @@ jobs: release_name=$(echo "$base" | sed 's/^[^_]*_[^_]*_//') echo "name=firmware-$release_name" >> $GITHUB_OUTPUT else - echo "name=firmware-${{ matrix.environment }}" >> $GITHUB_OUTPUT + echo "name=firmware-${BUILD_ENV}" >> $GITHUB_OUTPUT fi - uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/usermods.yml b/.github/workflows/usermods.yml index c00064ee77..93305c843d 100644 --- a/.github/workflows/usermods.yml +++ b/.github/workflows/usermods.yml @@ -22,41 +22,53 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Get changed usermod environments + - name: Get changed usermod build matrix id: envs + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} run: | # Usermods whose directories changed in this PR - changed=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD \ + changed=$(git diff --name-only "$BASE_SHA" HEAD \ | grep '^usermods/' | cut -d/ -f2 | sort -u || true) - # All usermods with a library.json (excluding known-incompatible ones) - all=$(find usermods/ -name library.json \ - | xargs dirname | xargs -n 1 basename \ - | grep -v PWM_fan | grep -v BME68X_v2 | grep -v pixels_dice_tray \ - | sort || true) + # Shared override defining the standard build environments + default_ini="usermods/platformio_override.usermods.ini" - if [ -z "$changed" ] || [ -z "$all" ]; then - echo "usermods=[]" >> $GITHUB_OUTPUT - else - usermods=$(comm -12 <(echo "$all") <(echo "$changed") | jq -R | jq --slurp -c) - echo "usermods=$usermods" >> $GITHUB_OUTPUT - fi + matrix='[]' + for mod in $changed; do + # Skip usermods known to be incompatible + case "$mod" in BME68X_v2|pixels_dice_tray) continue ;; esac + # Only build usermods that ship a library.json + [ -f "usermods/$mod/library.json" ] || continue + + # A usermod may provide its own build environments via a sample override; + # otherwise the standard environments from the shared override are used. + # Either way, the env list comes from the ini file rather than being + # duplicated here. + sample="usermods/$mod/platformio_override.ini.sample" + [ -f "$sample" ] && ini="$sample" || ini="$default_ini" + envs=$(grep -oE '^\[env:[^]]+\]' "$ini" | sed 's/^\[env:\(.*\)\]$/\1/') + + for env in $envs; do + matrix=$(echo "$matrix" | jq --arg u "$mod" --arg e "$env" -c '. + [{usermod: $u, env: $e}]') + done + done + echo "matrix=$matrix" >> $GITHUB_OUTPUT outputs: - usermods: ${{ steps.envs.outputs.usermods }} + matrix: ${{ steps.envs.outputs.matrix }} build: # Only run for pull requests from forks (not from branches within wled/WLED) - # Skip when no changed usermods were found (e.g. only non-library changes) - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && needs.get_usermod_envs.outputs.usermods != '[]' - name: Build Enviornments + # Skip when no buildable usermods were found (e.g. only non-library changes) + if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && needs.get_usermod_envs.outputs.matrix != '[]' + name: Build (${{ matrix.usermod }} / ${{ matrix.env }}) runs-on: ubuntu-latest needs: get_usermod_envs strategy: fail-fast: false matrix: - usermod: ${{ fromJSON(needs.get_usermod_envs.outputs.usermods) }} - environment: [usermods_esp32, usermods_esp32c3, usermods_esp32s2, usermods_esp32s3] + include: ${{ fromJSON(needs.get_usermod_envs.outputs.matrix) }} steps: - uses: actions/checkout@v4 - name: Set up Node.js @@ -72,8 +84,8 @@ jobs: ~/.platformio/.cache ~/.buildcache build_output - key: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }} - restore-keys: pio-${{ runner.os }}-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}- + key: pio-${{ runner.os }}-${{ matrix.env }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }} + restore-keys: pio-${{ runner.os }}-${{ matrix.env }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}- - name: Set up Python uses: actions/setup-python@v5 with: @@ -81,93 +93,23 @@ jobs: cache: 'pip' - name: Install PlatformIO run: pip install -r requirements.txt - - name: Add usermods environment + - name: Configure build environment + env: + USERMOD: ${{ matrix.usermod }} run: | - cp -v usermods/platformio_override.usermods.ini platformio_override.ini - echo >> platformio_override.ini - echo "custom_usermods = ${{ matrix.usermod }}" >> platformio_override.ini - cat platformio_override.ini - - - name: Build firmware - run: pio run -e ${{ matrix.environment }} - - - get_custom_build_envs: - name: Gather Custom Build Environments - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Find usermods with custom build environments - id: custom_envs - run: | - # On PRs: only scan usermods whose directories changed. - # On push: scan all usermods (validates the full set on merge). - if [ "${{ github.event_name }}" = "pull_request" ]; then - changed=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD \ - | grep '^usermods/' | cut -d/ -f2 | sort -u || true) - if [ -z "$changed" ]; then - echo "matrix=[]" >> $GITHUB_OUTPUT - exit 0 - fi - samples=$(for mod in $changed; do - f="usermods/$mod/platformio_override.ini.sample" - [ -f "$f" ] && echo "$f" - done | sort) + # Use the usermod's own override when it provides one, otherwise apply + # the shared usermods override with this usermod enabled. + sample="usermods/${USERMOD}/platformio_override.ini.sample" + if [ -f "$sample" ]; then + cp -v "$sample" platformio_override.ini else - samples=$(find usermods/ -name "platformio_override.ini.sample" | sort) + cp -v usermods/platformio_override.usermods.ini platformio_override.ini + echo >> platformio_override.ini + echo "custom_usermods = ${USERMOD}" >> platformio_override.ini fi + cat platformio_override.ini - result='[]' - for sample in $samples; do - usermod=$(dirname "$sample" | xargs basename) - # Skip usermods known to be incompatible (same list as get_usermod_envs) - case "$usermod" in PWM_fan|BME68X_v2|pixels_dice_tray) continue ;; esac - envs=$(grep -E '^\[env:[^]]+\]' "$sample" | sed 's/^\[env:\(.*\)\]$/\1/') - for env in $envs; do - result=$(echo "$result" | jq --arg u "$usermod" --arg e "$env" '. + [{usermod: $u, env: $e}]') - done - done - echo "matrix=$(echo "$result" | jq -c '.')" >> $GITHUB_OUTPUT - outputs: - matrix: ${{ steps.custom_envs.outputs.matrix }} - - - build_custom: - name: Build Custom Env (${{ matrix.usermod }} / ${{ matrix.env }}) - runs-on: ubuntu-latest - needs: get_custom_build_envs - if: needs.get_custom_build_envs.outputs.matrix != '[]' - strategy: - fail-fast: false - matrix: - include: ${{ fromJSON(needs.get_custom_build_envs.outputs.matrix) }} - steps: - - uses: actions/checkout@v4 - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.nvmrc' - cache: 'npm' - - run: npm ci - - name: Cache PlatformIO - uses: actions/cache@v4 - with: - path: | - ~/.platformio/.cache - ~/.buildcache - build_output - key: pio-${{ runner.os }}-${{ matrix.env }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}-${{ hashFiles('wled00/**', 'usermods/**') }} - restore-keys: pio-${{ runner.os }}-${{ matrix.env }}-${{ hashFiles('platformio.ini', 'pio-scripts/output_bins.py') }}- - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.12' - cache: 'pip' - - name: Install PlatformIO - run: pip install -r requirements.txt - - name: Apply custom build environment - run: cp -v "usermods/${{ matrix.usermod }}/platformio_override.ini.sample" platformio_override.ini - name: Build firmware - run: pio run -e ${{ matrix.env }} + env: + BUILD_ENV: ${{ matrix.env }} + run: pio run -e "$BUILD_ENV" diff --git a/platformio.ini b/platformio.ini index 77ca1f855e..0fedc185ae 100644 --- a/platformio.ini +++ b/platformio.ini @@ -714,7 +714,7 @@ build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME= [env:usermods] extends = env:esp32dev build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=\"ESP32_USERMODS\" - -DTOUCH_CS=9 -DWLED_USE_SD_SPI ;; help a few usermods that require special flags to compile + -DTOUCH_CS=9 custom_usermods = * ; Expands to all usermods in usermods folder board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat diff --git a/usermods/PWM_fan/platformio_override.ini.sample b/usermods/PWM_fan/platformio_override.ini.sample new file mode 100644 index 0000000000..864f87d0a2 --- /dev/null +++ b/usermods/PWM_fan/platformio_override.ini.sample @@ -0,0 +1,38 @@ +# CI sample override file: this usermod has dependencies. +# Based on the CI standard but adds the Temperature usermod too. + +[platformio] +default_envs = usermods_esp32, usermods_esp32c3, usermods_esp32s2, usermods_esp32s3 + +[env:usermods_esp32] +extends = env:esp32dev +custom_usermods = ${usermods.custom_usermods} +board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:esp32dev.build_flags} -D WLED_DEBUG + + +[env:usermods_esp32c3] +extends = env:esp32c3dev +board = esp32-c3-devkitm-1 +custom_usermods = ${usermods.custom_usermods} +board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:esp32c3dev.build_flags} -D WLED_DEBUG + + +[env:usermods_esp32s2] +extends = env:lolin_s2_mini +custom_usermods = ${usermods.custom_usermods} +board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:lolin_s2_mini.build_flags} -D WLED_DEBUG + + +[env:usermods_esp32s3] +extends = env:esp32s3dev_16MB_opi +custom_usermods = ${usermods.custom_usermods} +board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:esp32s3dev_16MB_opi.build_flags} -D WLED_DEBUG + + +[usermods] +custom_usermods = PWM_fan + Temperature diff --git a/usermods/platformio_override.usermods.ini b/usermods/platformio_override.usermods.ini index fbcb9d3d0c..ab193520d5 100644 --- a/usermods/platformio_override.usermods.ini +++ b/usermods/platformio_override.usermods.ini @@ -3,36 +3,31 @@ default_envs = usermods_esp32, usermods_esp32c3, usermods_esp32s2, usermods_esp3 [env:usermods_esp32] extends = env:esp32dev -build_flags = ${env:esp32dev.build_flags} - -DTOUCH_CS=9 -D WLED_USE_SD_SPI ;; help a few usermods that require special flags to compile custom_usermods = ${usermods.custom_usermods} board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:esp32dev.build_flags} -D WLED_DEBUG [env:usermods_esp32c3] extends = env:esp32c3dev -build_flags = ${env:esp32c3dev.build_flags} - -DTOUCH_CS=9 -D WLED_USE_SD_SPI ;; help a few usermods that require special flags to compile board = esp32-c3-devkitm-1 custom_usermods = ${usermods.custom_usermods} board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:esp32c3dev.build_flags} -D WLED_DEBUG [env:usermods_esp32s2] extends = env:lolin_s2_mini -build_flags = ${env:lolin_s2_mini.build_flags} - -DTOUCH_CS=9 -D WLED_USE_SD_SPI ;; help a few usermods that require special flags to compile custom_usermods = ${usermods.custom_usermods} board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:lolin_s2_mini.build_flags} -D WLED_DEBUG [env:usermods_esp32s3] extends = env:esp32s3dev_16MB_opi -build_flags = ${env:esp32s3dev_16MB_opi.build_flags} - -DTOUCH_CS=9 -D WLED_USE_SD_SPI ;; help a few usermods that require special flags to compile - -D WLED_DEBUG ;; try to catch broken DEBUG_PRINT statements custom_usermods = ${usermods.custom_usermods} board_build.partitions = ${esp32.extreme_partitions} ; We're gonna need a bigger boat +build_flags = ${env:esp32s3dev_16MB_opi.build_flags} -D WLED_DEBUG