Development Guide
July 14, 2026 ยท View on GitHub
For project overview, prerequisites, and build instructions, see the README. This guide covers architecture, testing, contributing guidelines, and CI/CD details.
Architecture
For a detailed description of the firmware architecture, source code structure, modules, build system, and linker scripts, see the Architecture document.
Testing
See unittests/README.md for details on running and adding tests.
Contributing
Code Style
C code is formatted with Artistic Style (astyle) version 3.4.7, configured in .astyle-rules.yml. Python code follows ruff formatting and linting rules defined in pyproject.toml.
Pre-commit Hooks
Install and activate the pre-commit hooks:
source venv/bin/activate
pip install pre-commit
pre-commit install -t pre-commit -t commit-msg
Run all checks manually:
pre-commit run --all-files
The hooks enforce:
- C code formatting (astyle)
- Python linting and formatting (ruff, mypy)
- Copyright header validation (Apache-2.0 OR MIT)
- Trailing whitespace, line endings, and YAML formatting
- Conventional Commits message format
Copyright Headers
All source files must include an SPDX copyright header. The copyright year range is automatically managed by the check-copyright tool.
C files:
/*
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
Python files:
# SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0 OR MIT
Commit Messages
This project uses Conventional Commits. Releases are managed with commitizen.
Pull Request Checklist
Before submitting a pull request:
-
Run host tests:
cd unittests/host && ./run-tests.sh && cd ../.. -
Build firmware for at least one chip:
source venv/bin/activate source ./tools/export_toolchains.sh cmake . -B build -G Ninja -DTARGET_CHIP=esp32s2 --fresh ninja -C build -
Run pre-commit hooks:
pre-commit run --all-files -
Verify the JSON output was generated:
ls -la build/*.json
CI/CD
GitHub Actions Workflows
| Workflow | Trigger | Purpose |
|---|---|---|
| Build and Release | Push, PR, tag | Build firmware for all chips; generate the stub size report on PRs; create a draft GitHub release on tags |
| Publish npm package | GitHub release published | Package stub JSON files and publish to npm (triggered when a draft release is manually published) |
| Post stub size report | workflow_run after Build and Release | Post/update the size report comment on the PR (runs with a write token so it also works for fork PRs) |
| Host Tests | Push | Run native unit tests |
| DangerJS | PR | Validate PR style and conventions |
| Jira | PR | Sync with Jira issue tracker |
Pre-commit.ci also runs automatically on pull requests to verify code style.
Releasing (Maintainers Only)
python -m venv venv
source venv/bin/activate
pip install commitizen czespressif
git fetch
git checkout -b update/release_v<version>
git reset --hard origin/master
cz bump
git push -u
git push --tags
Create a pull request and edit the automatically created draft release on the releases page.
Publishing the release automatically triggers the Publish npm package workflow, which downloads the stub JSON files attached to the release and publishes the esp-flasher-stub npm package.
Utilities
| Script | Description |
|---|---|
tools/build_all_chips.sh | Build firmware for all supported chips |
tools/setup_toolchains.sh | Download and extract cross-compilation toolchains |
tools/export_toolchains.sh | Add toolchain directories to PATH (must be sourced) |
tools/elf2json.py | Convert ELF binary to JSON format for esptool; embeds plugin data when --plugin is specified |
tools/compare_sizes.py | Compare stub segment sizes between two builds; used by CI to post size reports on PRs |
tools/compute_plugin_addrs.py | Emit a linker fragment with plugin load addresses computed from the base stub ELF |
tools/install_all_chips.sh | Copy built JSON files into an esptool installation |
tools/generate_npm_package.mjs | Assemble the esp-flasher-stub npm package from stub JSON files; used by the Publish npm package workflow |