-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
ci: discover and build custom PlatformIO envs from usermods platformi… #5649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
71767b7
badfcfc
2daf17a
af4b39e
d459e6c
e68bd2a
50cd900
fb0c1df
9b4eafa
3007564
83e32ea
818c3cb
76a505f
76b1e0a
a2a2596
1391e46
23c6903
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,9 @@ on: | |
| pull_request: | ||
| paths: | ||
| - usermods/** | ||
| push: | ||
| paths: | ||
| - usermods/** | ||
|
|
||
| env: | ||
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | ||
|
|
@@ -12,28 +15,40 @@ jobs: | |
|
|
||
| get_usermod_envs: | ||
| # Only run for pull requests from forks (not from branches within wled/WLED) | ||
| if: github.event.pull_request.head.repo.full_name != github.repository | ||
| if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository | ||
| name: Gather Usermods | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.12' | ||
| cache: 'pip' | ||
| - name: Install PlatformIO | ||
| run: pip install -r requirements.txt | ||
| - name: Get default environments | ||
| fetch-depth: 0 | ||
| - name: Get changed usermod environments | ||
| id: envs | ||
| run: | | ||
| echo "usermods=$(find usermods/ -name library.json | xargs dirname | xargs -n 1 basename | jq -R | grep -v PWM_fan | grep -v BME68X_v2| grep -v pixels_dice_tray | jq --slurp -c)" >> $GITHUB_OUTPUT | ||
| # Usermods whose directories changed in this PR | ||
| changed=$(git diff --name-only ${{ github.event.pull_request.base.sha }} HEAD \ | ||
| | grep '^usermods/' | cut -d/ -f2 | sort -u || true) | ||
|
Comment on lines
27
to
+30
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pass Both scripts inject Suggested change - name: Get changed usermod environments
id: envs
+ env:
+ PR_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 "$PR_BASE_SHA" HEAD \
| grep '^usermods/' | cut -d/ -f2 | sort -u || true) - name: Find usermods with custom build environments
id: custom_envs
+ env:
+ PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
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 \
+ changed=$(git diff --name-only "$PR_BASE_SHA" HEAD \
| grep '^usermods/' | cut -d/ -f2 | sort -u || true)As per coding guidelines, "Never interpolate github.event.* values directly into run: steps — pass them through an env: variable to prevent script injection." Also applies to: 107-109 🤖 Prompt for AI Agents |
||
|
|
||
| # 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) | ||
|
|
||
| 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 | ||
| outputs: | ||
| usermods: ${{ steps.envs.outputs.usermods }} | ||
|
|
||
|
|
||
| build: | ||
| # Only run for pull requests from forks (not from branches within wled/WLED) | ||
| if: github.event.pull_request.head.repo.full_name != github.repository | ||
| # 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 | ||
| runs-on: ubuntu-latest | ||
| needs: get_usermod_envs | ||
|
|
@@ -74,4 +89,85 @@ jobs: | |
| cat platformio_override.ini | ||
|
|
||
| - name: Build firmware | ||
| run: pio run -e ${{ matrix.environment }} | ||
| 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) | ||
| else | ||
| samples=$(find usermods/ -name "platformio_override.ini.sample" | sort) | ||
| fi | ||
|
|
||
| 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 }} | ||
|
Comment on lines
+95
to
+173
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an explicit These new jobs currently inherit the default Suggested change+permissions:
+ contents: read
+
jobs:As per coding guidelines, "Declare explicit permissions: blocks scoped to least privilege." 🧰 Tools🪛 zizmor (1.25.2)[warning] 99-101: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) [warning] 147-147: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) [warning] 95-134: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block (excessive-permissions) [error] 99-99: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) [error] 147-147: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) [error] 149-149: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) [error] 155-155: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) [error] 164-164: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI Agents |
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # AHT10/AHT15/AHT20 temperature/humidity usermod build environment | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = aht10_example | ||
|
|
||
| [env:aht10_example] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} AHT10_v2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # BME280_v2 usermod build environment | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = usermod_esp8266_2m | ||
|
|
||
| [env:usermod_esp8266_2m] | ||
| extends = env:esp8266_2m | ||
| custom_usermods = ${env:esp8266_2m.custom_usermods} BME280_v2 |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # INA226 power monitor usermod build environments | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = ina226_example | ||
|
|
||
| # Minimal example — enable the usermod with default settings | ||
| [env:ina226_example] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} INA226_v2 | ||
| build_flags = ${env:esp32dev.build_flags} | ||
| ; -D USERMOD_INA226_DEBUG ; uncomment to add debug status to the info modal | ||
|
|
||
| # Custom calibration example — adjust constants to match your hardware | ||
| [env:ina226_custom] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} INA226_v2 | ||
| build_flags = ${env:esp32dev.build_flags} | ||
| -D INA226_ENABLED_DEFAULT=true | ||
| -D INA226_SHUNT_MICRO_OHMS=2888 | ||
| -D INA226_DEFAULT_CURRENT_RANGE=10000 | ||
| -D INA226_CURRENT_OFFSET_MA=-118 | ||
| -D INA226_CHECK_INTERVAL_MS=1000 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # LD2410 presence sensor usermod build environment | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = usermod_LD2410_v2_esp32dev | ||
|
|
||
| [env:usermod_LD2410_v2_esp32dev] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} LD2410_v2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # LDR Dusk/Dawn usermod build environment | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = usermod_LDR_Dusk_Dawn_esp32dev | ||
|
|
||
| [env:usermod_LDR_Dusk_Dawn_esp32dev] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} | ||
| LDR_Dusk_Dawn | ||
|
Comment on lines
+7
to
+10
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
jq -r '.name' usermods/LDR_Dusk_Dawn_v2/library.jsonRepository: wled/WLED Length of output: 70 Fix [env:usermod_LDR_Dusk_Dawn_esp32dev]
extends = env:esp32dev
custom_usermods = ${env:esp32dev.custom_usermods}
LDR_Dusk_Dawn_v2🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # MAX17048 battery fuel gauge usermod build environment | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = usermod_max17048_esp8266_2m | ||
|
|
||
| [env:usermod_max17048_esp8266_2m] | ||
| extends = env:esp8266_2m | ||
| custom_usermods = ${env:esp8266_2m.custom_usermods} MAX17048_v2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,16 @@ | ||
| ; Options | ||
| ; ------- | ||
| ; USERMOD_SN_PHOTORESISTOR - define this to have this user mod included wled00\usermods_list.cpp | ||
| ; USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds | ||
| ; USERMOD_SN_PHOTORESISTOR_FIRST_MEASUREMENT_AT - the number of milliseconds after boot to take first measurement, defaults to 20 seconds | ||
| ; USERMOD_SN_PHOTORESISTOR_REFERENCE_VOLTAGE - the voltage supplied to the sensor, defaults to 5v | ||
| ; USERMOD_SN_PHOTORESISTOR_ADC_PRECISION - the ADC precision is the number of distinguishable ADC inputs, defaults to 1024.0 (10 bits) | ||
| ; USERMOD_SN_PHOTORESISTOR_RESISTOR_VALUE - the resistor size, defaults to 10000.0 (10K hms) | ||
| ; USERMOD_SN_PHOTORESISTOR_OFFSET_VALUE - the offset value to report on, defaults to 25 | ||
| ; | ||
| [env:usermod_sn_photoresistor_d1_mini] | ||
| extends = env:d1_mini | ||
| [env:usermod_sn_photoresistor_esp8266_2m] | ||
| extends = env:esp8266_2m | ||
| custom_usermods = ${env:esp8266_2m.custom_usermods} SN_Photoresistor | ||
| build_flags = | ||
| ${common.build_flags_esp8266} | ||
| -D USERMOD_SN_PHOTORESISTOR | ||
| lib_deps = ${env.lib_deps} | ||
| ${env:esp8266_2m.build_flags} | ||
| -D USERMOD_SN_PHOTORESISTOR_MEASUREMENT_INTERVAL=60 | ||
| lib_deps = ${env:esp8266_2m.lib_deps} |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| ; TTGO-T-Display usermod build example. | ||
| ; Note: this usermod has no library.json so custom_usermods is not available. | ||
| ; The usermod.cpp must be included manually in your build. | ||
|
|
||
| [platformio] | ||
| default_envs = ttgo_t_display_example | ||
|
|
||
| [env:ttgo_t_display_example] | ||
| extends = env:esp32dev | ||
| build_flags = ${env:esp32dev.build_flags} | ||
| ; PIN defines - uncomment and change, if needed: | ||
| ; -D LEDPIN=2 | ||
| -D BTNPIN=35 | ||
| ; -D IRPIN=4 | ||
| ; -D RLYPIN=12 | ||
| ; -D RLYMDE=1 |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Temperature (DS18B20) usermod build environment | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = usermod_temperature_esp32dev | ||
|
|
||
| [env:usermod_temperature_esp32dev] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} | ||
| Temperature |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # MPU-6050 IMU usermod build environment | ||
| # Copy to platformio_override.ini in the WLED root to use. | ||
|
|
||
| [platformio] | ||
| default_envs = usermod_mpu6050_imu_esp32dev | ||
|
|
||
| [env:usermod_mpu6050_imu_esp32dev] | ||
| extends = env:esp32dev | ||
| custom_usermods = ${env:esp32dev.custom_usermods} | ||
| mpu6050_imu |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broaden the path filter to cover the files that define this CI behavior.
Right now this workflow only fires for
usermods/**, so changes to.github/workflows/usermods.ymlorplatformio_override.sample.inican skip the very checks they affect.Suggested change
on: pull_request: paths: - usermods/** + - .github/workflows/usermods.yml + - platformio_override.sample.ini push: paths: - usermods/** + - .github/workflows/usermods.yml + - platformio_override.sample.iniAs per coding guidelines, "Follow the CI/CD conventions documented in docs/cicd.instructions.md."
📝 Committable suggestion
🤖 Prompt for AI Agents