Skip to content

Add ESP32 flash geometry CI guard - #11343

Open
caveman99 wants to merge 3 commits into
developfrom
esp32-flash-geometry-check
Open

Add ESP32 flash geometry CI guard#11343
caveman99 wants to merge 3 commits into
developfrom
esp32-flash-geometry-check

Conversation

@caveman99

@caveman99 caveman99 commented Aug 3, 2026

Copy link
Copy Markdown
Member

Cross-checks, per ESP32 environment, three declarations of the same flash geometry that nothing currently reconciles:

  • upload.maximum_size from the resolved board (including board_upload.maximum_size overrides),
  • the end of the last partition in the selected CSV,
  • custom_meshtastic_partition_scheme, published in the .mt.json manifest.

The espressif32 builder overwrites upload.maximum_size with 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 wrong partition_scheme just ships in the manifest.

Runs as a step in the setup job 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:

Environment Problem
meshnology_w10, meshnology_w12, visualizer-hub75, t-energy-s3_e22, m5stack-unitc6l set board_upload.flash_size = 16MB on an 8MB stock board id; flash_size does not carry over to maximum_size, so the resolved board config contradicts itself
wiphone boards/wiphone.json declares maximum_size 6553600, the app0 size of default_16MB.csv, against its own flash_size: "16MB"
t-watch-s3 custom_meshtastic_partition_scheme = 8MB on a 16MB board using default_16MB.csv

The first five need board_upload.maximum_size = 16777216. t-watch-s3 is 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-manifests extracts it from the platform archive as data. It is deliberately not pio pkg install: that calls PlatformFactory.new(), which exec_module()s the downloaded platform.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.

  • archive URL allowlisted by scheme, host and owner
  • only members whose parent directory is boards/ and which end in .json
  • each written under its basename alone, never extractall
  • 128 MB archive cap, 1 MB per manifest, 120 s timeout

The job holds no secrets and its token is read-only (permissions: read-all).

Also bumps actions/setup-python to v7 (latest major; its only removal, the pip-install input, is unused here) and sets persist-credentials: false on the setup checkout, which runs no git after checkout.

Summary by CodeRabbit

  • New Features

    • Added ESP32 flash-geometry and partition-layout validation.
    • Supports checking individual environments or all applicable environments.
    • Provides clear reporting for invalid configurations, missing board information, fetch failures, and size mismatches.
    • Supports validating board configurations using local, installed, or securely retrieved board data.
  • CI Improvements

    • Automated setup now validates flash geometry before completing.
    • Improved credential handling and updated the Python setup action.

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.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

⚡ Try this PR in the Web Flasher

Note

Building this pull request… the flash button, badges and supported-board
list will appear here automatically once CI finishes.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: afd8472b-4599-4298-bc6f-c173e1e09d1e

📥 Commits

Reviewing files that changed from the base of the PR and between fa3c262 and 7321f89.

📒 Files selected for processing (1)
  • bin/check_partition_sizes.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • bin/check_partition_sizes.py

📝 Walkthrough

Walkthrough

The PR adds a static ESP32 flash-geometry validator. The CI setup job fetches board manifests and runs the validator before producing setup outputs.

Changes

ESP32 flash geometry validation

Layer / File(s) Summary
Parsing and manifest resolution
bin/check_partition_sizes.py
Adds partition-size, flash-tier, scheme, and board-manifest parsing. Secure fetching enforces HTTPS host and owner allowlists and size limits.
Environment validation
bin/check_partition_sizes.py
Discovers ESP32 environments and validates board limits, partition geometry, selected schemes, CLI options, and exit reporting.
CI integration
.github/workflows/main_matrix.yml
Updates setup actions and runs the validator after fetching required board manifests.

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
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely identifies the main change: adding an ESP32 flash geometry guard to CI.
Description check ✅ Passed The description clearly explains the guard, CI integration, security controls, known failures, and related workflow changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch esp32-flash-geometry-check

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5792e87 and 72def23.

📒 Files selected for processing (2)
  • .github/workflows/main_matrix.yml
  • bin/check_partition_sizes.py

Comment thread bin/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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 72def23 and fa3c262.

📒 Files selected for processing (2)
  • .github/workflows/main_matrix.yml
  • bin/check_partition_sizes.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/main_matrix.yml

Comment thread bin/check_partition_sizes.py Outdated
Comment thread bin/check_partition_sizes.py Outdated
@caveman99 caveman99 added the enhancement New feature or request label Aug 3, 2026
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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.py to reconcile (a) resolved board upload.maximum_size, (b) partition CSV end address, and (c) custom_meshtastic_partition_scheme.
  • Wires the check into the setup job in main_matrix.yml and 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-python to v7.

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.

Comment thread .github/workflows/main_matrix.yml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants