Skip to content

esp32: default to native espflash with esptool fallback#197

Merged
zackees merged 2 commits intomainfrom
codex/issue-66-default-espflash-native
Apr 24, 2026
Merged

esp32: default to native espflash with esptool fallback#197
zackees merged 2 commits intomainfrom
codex/issue-66-default-espflash-native

Conversation

@zackees
Copy link
Copy Markdown
Member

@zackees zackees commented Apr 24, 2026

Summary

  • enable espflash-native by default in fbuild-deploy and fbuild-daemon
  • make ESP32 native verify/write opt-out via FBUILD_USE_ESPFLASH_VERIFY=0 and FBUILD_USE_ESPFLASH_WRITE=0
  • fall back to esptool automatically when native verify or write fails, and update docs/tests accordingly

Testing

  • cargo test -p fbuild-daemon espflash_env_tests
  • cargo test -p fbuild-deploy

Summary by CodeRabbit

  • New Features

    • ESP32 deployment now automatically falls back to esptool if native deployment fails, improving reliability without requiring manual intervention.
  • Changes

    • Native espflash is now enabled by default for ESP32 deployments. Users can disable it by setting environment variables to 0/false/no/off to prefer esptool.
  • Documentation

    • Updated deployment documentation to reflect new default native espflash behavior and automatic fallback mechanism.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 24, 2026

Warning

Rate limit exceeded

@zackees has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 27 minutes and 58 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 27 minutes and 58 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6cab0f4e-5a14-46aa-9e03-bfbdb003b24d

📥 Commits

Reviewing files that changed from the base of the PR and between 0a1c7ae and 94c446c.

📒 Files selected for processing (2)
  • crates/fbuild-daemon/src/handlers/operations.rs
  • crates/fbuild-deploy/src/esp32.rs
📝 Walkthrough

Walkthrough

This PR shifts native espflash features from opt-in to default-enabled with automatic fallback to esptool. It enables espflash-native by default in Cargo manifests, changes environment variable parsing to opt-out semantics, and adds fallback logic so native operations retry via esptool subprocess on failure.

Changes

Cohort / File(s) Summary
Feature Configuration
crates/fbuild-daemon/Cargo.toml, crates/fbuild-deploy/Cargo.toml
Default feature set changed from empty to include espflash-native, making native espflash support compiled in by default instead of opt-in.
Environment Variable Parsing
crates/fbuild-daemon/src/handlers/operations.rs
Introduces env_default_enabled() helper to centralize parsing of FBUILD_USE_ESPFLASH_VERIFY and FBUILD_USE_ESPFLASH_WRITE as opt-out (default enabled, only 0/false/no/off disables). Adds tests to verify default-on and explicit opt-out behavior.
Fallback Logic
crates/fbuild-deploy/src/esp32.rs
Native espflash verify and write operations now fall back to esptool subprocess on failure. Adds try_verify_deployment_esptool() helper and wraps native calls with error logging and fallback invocation.
Documentation
crates/fbuild-deploy/README.md
Updates narrative to reflect native espflash as default path (when compiled in) with automatic esptool fallback, switching from opt-in toggle model to opt-out semantics.

Sequence Diagram(s)

sequenceDiagram
    participant Handler as Deploy Handler
    participant Deployer as Esp32Deployer
    participant Native as Native Espflash
    participant Esptool as Esptool Subprocess
    participant Result as Deployment Result

    Handler->>Deployer: deploy() / verify()
    Deployer->>Native: Attempt native operation
    alt Native succeeds
        Native-->>Deployer: Success
        Deployer-->>Handler: Return result
    else Native fails or error
        Native-->>Deployer: Error / Failure
        Deployer->>Deployer: Log warning
        Deployer->>Esptool: Fallback: run esptool command
        Esptool-->>Deployer: Parse stdout/stderr
        Deployer-->>Handler: Return esptool result
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Native paths by default now run,
With esptool as backup when troubles come!
No more opt-in, just flip the switch—
Features compiled in, a robust mix!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'esp32: default to native espflash with esptool fallback' accurately summarizes the main change: enabling native espflash by default with automatic esptool fallback.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-66-default-espflash-native

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
crates/fbuild-daemon/Cargo.toml (1)

17-22: LGTM — daemon default aligns with deploy crate.

Forwarding espflash-native to fbuild-deploy/espflash-native and enabling it by default keeps the daemon's feature set consistent with the deploy crate. Runtime env-var opt-out plus automatic esptool fallback on native failure makes this a safe default flip.

Note for release comms: this pulls the espflash crate (and its serialport transitive deps) into the default daemon build. If you track binary size or cold-compile time deltas, worth calling out in the changelog so downstream packagers know to expect the bump.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/fbuild-daemon/Cargo.toml` around lines 17 - 22, No code change
required: the Cargo.toml feature table correctly forwards espflash-native to
fbuild-deploy/espflash-native and enables it in default; just keep the existing
default = ["espflash-native"] and espflash-native =
["fbuild-deploy/espflash-native"] entries as-is and consider calling out the
transitive espflash/serialport deps in release notes for size/compile-time
impact.
crates/fbuild-deploy/src/esp32.rs (1)

1145-1163: Optional: factor out the "native → esptool fallback" match into a helper.

The two call sites (deploy_regions at 1145-1163 and deploy at 1232-1250) have essentially identical match/log shape. If this grows (e.g., metrics, structured fallback reasons), a small helper like:

#[cfg(feature = "espflash-native")]
fn native_write_or_fallback<F>(port: &str, label: &str, native: F) -> Option<DeploymentResult>
where
    F: FnOnce() -> Result<DeploymentResult>,
{
    match native() {
        Ok(result) if result.success => Some(result),
        Ok(result) => {
            tracing::warn!(port, "native {} failed ({}); falling back to esptool", label, result.message);
            None
        }
        Err(e) => {
            tracing::warn!(port, "native {} failed ({}); falling back to esptool", label, e);
            None
        }
    }
}

…would keep both sites to a single line. Not essential — readable as-is.

Also applies to: 1232-1250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/fbuild-deploy/src/esp32.rs` around lines 1145 - 1163, Factor out the
duplicated "native → esptool fallback" match into a helper (e.g.,
native_write_or_fallback) and call it from both deploy_regions and deploy:
extract the match over try_deploy_regions_native/try_deploy_native into a small
#[cfg(feature = "espflash-native")] function that accepts port, a label (like
"selective write-flash" or "write-flash") and a closure returning
Result<DeploymentResult>, returns Option<DeploymentResult> (Some on success
where result.success is true, None on any fallback) and emits the same
tracing::warn messages including result.message or the error; then replace the
inline match blocks in deploy_regions and deploy with a single call to this
helper and act on the Option result.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/fbuild-daemon/src/handlers/operations.rs`:
- Around line 2239-2275: Replace the plain .unwrap() on ENV_LOCK.lock() in the
espflash_env_tests module with .unwrap_or_else(|e| e.into_inner()) to survive
mutex poisoning (reference ENV_LOCK and the test functions
native_verify_defaults_on_and_allows_opt_out /
native_write_defaults_on_and_allows_opt_out which call native_verify_enabled and
native_write_enabled). Also add a brief comment above the tests noting that the
mutex only serializes these unit tests and does not protect production callers
of native_verify_enabled() and native_write_enabled(), warning future
maintainers that other tests or integration tests reading those env vars could
still race.

---

Nitpick comments:
In `@crates/fbuild-daemon/Cargo.toml`:
- Around line 17-22: No code change required: the Cargo.toml feature table
correctly forwards espflash-native to fbuild-deploy/espflash-native and enables
it in default; just keep the existing default = ["espflash-native"] and
espflash-native = ["fbuild-deploy/espflash-native"] entries as-is and consider
calling out the transitive espflash/serialport deps in release notes for
size/compile-time impact.

In `@crates/fbuild-deploy/src/esp32.rs`:
- Around line 1145-1163: Factor out the duplicated "native → esptool fallback"
match into a helper (e.g., native_write_or_fallback) and call it from both
deploy_regions and deploy: extract the match over
try_deploy_regions_native/try_deploy_native into a small #[cfg(feature =
"espflash-native")] function that accepts port, a label (like "selective
write-flash" or "write-flash") and a closure returning Result<DeploymentResult>,
returns Option<DeploymentResult> (Some on success where result.success is true,
None on any fallback) and emits the same tracing::warn messages including
result.message or the error; then replace the inline match blocks in
deploy_regions and deploy with a single call to this helper and act on the
Option result.
🪄 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

Run ID: ef8cd214-d28a-4ae4-8fe4-df1a81b6d636

📥 Commits

Reviewing files that changed from the base of the PR and between 3cc09b8 and 0a1c7ae.

📒 Files selected for processing (5)
  • crates/fbuild-daemon/Cargo.toml
  • crates/fbuild-daemon/src/handlers/operations.rs
  • crates/fbuild-deploy/Cargo.toml
  • crates/fbuild-deploy/README.md
  • crates/fbuild-deploy/src/esp32.rs

Comment thread crates/fbuild-daemon/src/handlers/operations.rs
@zackees
Copy link
Copy Markdown
Member Author

zackees commented Apr 24, 2026

Addressed the CodeRabbit feedback in 94c446c3.

  • hardened the env-var tests against mutex poisoning with unwrap_or_else(|e| e.into_inner())
  • documented that ENV_LOCK only serializes these unit tests
  • factored the duplicated native write fallback path into native_write_or_fallback() and reused it from both write call sites

Validation:

  • cargo test -p fbuild-daemon espflash_env_tests
  • cargo test -p fbuild-deploy

@zackees zackees merged commit 5c90af0 into main Apr 24, 2026
73 of 76 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant