Add ESP32 flash geometry CI guard - #11343
Conversation
Cross-checks, per ESP32 environment, the resolved board's upload.maximum_size against the end of the selected partition CSV and against custom_meshtastic_partition_scheme. Added as a step in the CI setup job, next to the existing board_level validation. The espressif32 builder overwrites upload.maximum_size with the app slot size from the partition table, so a variant pointing at an oversized table links clean and only fails when flashed. Board manifests for stock board ids are extracted from the pinned platform archive as data, not installed with pio pkg install, which calls PlatformFactory.new() and executes the downloaded platform.py. Archive URLs are allowlisted by host and owner, members are restricted to boards/*.json, and each is written under its basename alone. Also bumps actions/setup-python to v7 and sets persist-credentials: false on the setup job checkout. Nine pre-existing mismatches across seven environments are left unfixed and fail this check.
⚡ Try this PR in the Web FlasherNote Building this pull request… the flash button, badges and supported-board |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughThe PR adds a static ESP32 flash-geometry validator. The CI setup job fetches board manifests and runs the validator before producing setup outputs. ChangesESP32 flash geometry validation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant SetupJob
participant Validator as check_partition_sizes.py
participant Manifests
participant PartitionCSV
SetupJob->>Manifests: fetch board manifests
SetupJob->>Validator: validate ESP32 environments
Validator->>Manifests: resolve board data
Validator->>PartitionCSV: parse partition geometry
Validator-->>SetupJob: return success or CI errors
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@bin/check_partition_sizes.py`:
- Around line 177-209: Update fetch_board_manifests to add a targeted Semgrep
suppression with justification on the urllib.request.urlopen call, documenting
that check_manifest_url validates the URL. Move the Ruff S310 noqa suppression
from the urlopen line to the urllib.request.Request construction line reported
by Ruff, preserving both targeted suppressions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0fdf8dc7-cdc8-4ed8-9e84-d932fc0bfc3b
📒 Files selected for processing (2)
.github/workflows/main_matrix.ymlbin/check_partition_sizes.py
Semgrep's dynamic-urllib-use-detected rule blocks the differential scan on the urlopen call, and Ruff reports S310 on both the Request construction and the urlopen call. check_manifest_url() rejects any URL that is not https on an allowlisted host and owner and raises before either call. Trims comments to two lines.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@bin/check_partition_sizes.py`:
- Around line 140-141: Update find_board_manifest() and its caller check_env()
so installed manifest lookup is constrained to the resolved platform package
name, preventing matches from other platforms; preserve deterministic version
selection within that platform and use a platform-specific manifest path when
installed manifests are permitted.
- Around line 174-178: Update the manifest-fetch flow around
check_manifest_url() and urllib.request.urlopen() so every HTTP redirect target
is validated with check_manifest_url() before being followed. Use a custom
redirect handler or disable automatic redirects while preserving the existing
HTTPS, host, and owner allowlist checks for the initial and redirected URLs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 6eb570c2-6a13-42d5-9264-0b5c59536395
📒 Files selected for processing (2)
.github/workflows/main_matrix.ymlbin/check_partition_sizes.py
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/main_matrix.yml
urlopen followed redirects through the default opener without re-applying the allowlist, and this fetch does redirect: github.com hands the archive off to codeload.github.com. A redirect could therefore walk the download to any host. Fetch through an opener whose redirect handler runs check_manifest_url() on each target. Constrain the installed-manifest fallback to espressif32* so a same-named board in another installed platform cannot answer. Parenthesize an implicit string concatenation inside a list literal.
There was a problem hiding this comment.
Pull request overview
Adds a new CI guard to detect mismatches between ESP32 board flash geometry and partition-table selection before any builds run, preventing “links fine but fails on flash” configuration errors and ensuring the .mt.json manifest’s custom_meshtastic_partition_scheme stays consistent with the resolved board flash size.
Changes:
- Introduces
bin/check_partition_sizes.pyto reconcile (a) resolved boardupload.maximum_size, (b) partition CSV end address, and (c)custom_meshtastic_partition_scheme. - Wires the check into the
setupjob inmain_matrix.ymland fetches pinned platform board manifests as data-only for environments using stock board IDs. - Hardens the setup checkout by disabling persisted credentials and bumps
actions/setup-pythontov7.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
bin/check_partition_sizes.py |
New script to validate ESP32 flash/partition/manifest geometry and safely fetch board manifests from allowlisted platform archives. |
.github/workflows/main_matrix.yml |
Runs the new flash-geometry check early in CI setup; also disables persisted git credentials and bumps Python setup action. |
Cross-checks, per ESP32 environment, three declarations of the same flash geometry that nothing currently reconciles:
upload.maximum_sizefrom the resolved board (includingboard_upload.maximum_sizeoverrides),custom_meshtastic_partition_scheme, published in the.mt.jsonmanifest.The espressif32 builder overwrites
upload.maximum_sizewith the app slot size from the partition table (_update_max_upload_size), so a variant pointing at an oversized table links clean and only fails when it is flashed. A wrongpartition_schemejust ships in the manifest.Runs as a step in the
setupjob of the CI workflow: no toolchain, no compile, and it covers all 136 ESP32 environments rather than the subset the matrix builds for a given event.This PR fails its own check
Nine pre-existing mismatches across seven environments are left unfixed:
meshnology_w10,meshnology_w12,visualizer-hub75,t-energy-s3_e22,m5stack-unitc6lboard_upload.flash_size = 16MBon an 8MB stock board id;flash_sizedoes not carry over tomaximum_size, so the resolved board config contradicts itselfwiphoneboards/wiphone.jsondeclaresmaximum_size6553600, the app0 size ofdefault_16MB.csv, against its ownflash_size: "16MB"t-watch-s3custom_meshtastic_partition_scheme = 8MBon a 16MB board usingdefault_16MB.csvThe first five need
board_upload.maximum_size = 16777216.t-watch-s3is the only one that changes shipped output: that value lands in the manifest the flasher consumes and has been wrong since #9214.Board manifest lookup
About 20 environments use a stock board id rather than one from
boards/, so the check needs the pinned platform's board JSON.--fetch-board-manifestsextracts it from the platform archive as data. It is deliberately notpio pkg install: that callsPlatformFactory.new(), whichexec_module()s the downloadedplatform.py, and the platform URL is read from the checkout, so on a fork PR it would execute code from whatever archive that PR points at.boards/and which end in.jsonextractallThe job holds no secrets and its token is read-only (
permissions: read-all).Also bumps
actions/setup-pythonto v7 (latest major; its only removal, thepip-installinput, is unused here) and setspersist-credentials: falseon thesetupcheckout, which runs no git after checkout.Summary by CodeRabbit
New Features
CI Improvements