Skip to main content

Automated deployment of ESPHome configuration files to devices

Project description

esphome-deployment

A CLI Tool for managing compilation and deployment of ESPHome Device configurations.

Programming Language Latest Release License

Features

  • 🚀 Batch Deployment: Deploy to multiple devices with a single command.
  • 📦 Smart Caching: Avoids redundant compiles by tracking configuration hashes.
  • 🕵️ Change Detection: Only uploads binaries if the resulting build actually changed.
  • 🔄 VCS State Tracking: Store deployment metadata in Git to sync state across CI/CD or multiple machines.
  • 📋 Detailed Logging: Automatic per-device log capture for easy debugging.

Setup

Prerequisites

  1. ESPHome CLI must be installed in your PATH.
  2. A Git repository for your ESPHome device configurations.

Reproducible Builds

For the caching mechanism of esphome-deployment to work across machines, the firmware images produced by ESPHome need to be made reproducible. This means that given the same input, the build process should always produce the exact same output binary, bit for bit. Unfortunately, ESPHome does not currently guarantee reproducible builds out of the box, but there are a couple of options we can add to our configuration YAML to remedy this:

esphome: Section

packages/esphome.yaml

esphome:
  platformio_options:
    build_flags:
      # 1. Prevent warnings for redefining built-in macros
      - -Wno-builtin-macro-redefined
      # 2. Force a static date and time
      - '-D__DATE__="\"Dec 29 2025\""'
      - '-D__TIME__="\"23:00:00\""'

See: https://esphome.io/components/esphome/

esp32: Section

packages/chip/esp32-esp-idf.yaml

esp32:
  framework:
    type: esp-idf
    sdkconfig_options:
      # options to ensure reproducible builds (exact binary match)
      CONFIG_APP_REPRODUCIBLE_BUILD: y
      CONFIG_APP_COMPILE_TIME_DATE: n
      CONFIG_APP_EXCLUDE_PROJECT_VER_VAR: y
      CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR: y

See: https://esphome.io/components/esp32/

[!NOTE] The esp8266 does not support or require any special options for reproducible builds at this time. Only the general esphome section as shown above is needed.

Docker

If you prefer to use Docker, you can use the published image ghcr.io/markusressel/esphome-deployment from ghcr. Just ensure you mount your ESPHome configurations path into it, and run the CLI commands as shown in the usage section below.

docker run --rm -it \
  -v ~/esphome-configs:/config \
  -u $(id -u):$(id -g) \
  -e ESPHOME_DEPLOYMENT_DEPLOYMENT_COORDINATOR_MAX_WORKERS=1 \ 
  ghcr.io/markusressel/esphome-deployment:latest \
  esphome-deployment --help

Usage

Usage: esphome-deployment [OPTIONS] COMMAND [ARGS]...

Options:
  --version   Show the version and exit.
  -h, --help  Show this message and exit.

Commands:
  clean    Clean
  compile  Compile the given deployment(s)
  config   Print the current configuration
  deploy   Deploy (compile + upload) the given deployment(s)
  upload   Upload the given deployment(s)

Configuration

Main configuration

The main configuration for esphome-deployment can be specified in a file named .esphome_deployment.yaml located next to your ESPHome configurations (within your working directory). See .esphome_deployment.yaml for all available options.

Per-Device configuration

Each ESPHome configuration can optionally contain a .esphome_deployment: section (note the leading dot) to adjust the deployment behavior for that specific device. Example:

.esphome_deployment:
  deploy: true
  tags:
    - bluetooth_proxy

packages:
  esphome: !include packages/esphome.yaml
  chip: !include packages/chip/esp32-esp-idf.yaml

... rest of your esp home config ...

Repository layout, state files and logs

Recommended layout for a repository using esphome-deployment to deploy multiple ESPHome configurations:

<repo-root>/
├── packages/                 # reusable package files (recommended)
│   ├── esphome.yaml
│   └── chip/...
├── .deployment-state/        # (generated) per-deployment JSON state files, commit this to VCS to share state across machines
├── .deployment-logs/         # (generated) CLI logs for compile/upload runs
├── .esphome_deployment.yaml  # global config for esphome-deployment
├── secrets.yaml
├── your-device-1.yaml        # individual deployment yamls (put in repo root)
└── your-device-2.yaml

[!TIP] Commit your state! By committing the .deployment-state/*.json files, esphome-deployment will know exactly which devices are already up-to-date even when running it on a different machine.

Add this to your .gitignore:

# Ignore generated log files from esphome-deployment, but keep the deployment state files for VCS tracking
.deployment-logs/

Deployment State

esphome-deployment remembers the compilation and upload state for each deployment configuration in a JSON file within .deployment-state/.

  • What they are: For every esphome invocation the CLI writes a log into .deployment-logs/ in the same directory as your device YAMLs. Filenames are like <deployment>_<command>_YYYYMMDD_HHMMSS.log and contain merged stdout/stderr from the esphome CLI. These logs are invaluable for debugging compile/upload issues.

Logs

esphome-deployment captures the output of each esphome CLI invocation and saves it to a log file in .deployment-logs/ for later inspection. This includes both stdout and stderr, merged together with timestamps for easier debugging.

# list recent logs
ls -lt .deployment-logs/

# view a specific log
less .deployment-logs/<filename>.log

# follow a log in real time
tail -f .deployment-logs/<filename>.log

[!WARNING] Privacy note: Logs may contain IPs, device identifiers or other runtime information. Treat them as potentially sensitive when sharing.

Contributing

Contributions to esphome-deployment are very welcome! If you have an idea for a new feature, found a bug or want to help out with documentation, please open an issue or submit a pull request.

Local Development

### Installation

1. Clone this repository as a git submodule next to your ESPHome configurations
    * e.g. `git submodule add https://github.com/markusressel/esphome-deployment`
2. Ensure your configurations utilize the reproducible build options as shown above
    * e.g. via packages for both ESPHome and ESP32 devices containing the options above
3. Use `poetry` (or any other method of your choice) to run esphome-deployment (see below)

```bash
python3 -m venv venv
. venv/bin/activate && pip install --upgrade pip poetry
poetry install -P ./esphome-deployment

License

esphome-deployment is licensed under the AGPLv3 License. By using or contributing to this project, you agree to comply with the terms of this license. Please review the LICENSE file for more details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

esphome_deployment-0.1.0.tar.gz (33.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

esphome_deployment-0.1.0-py3-none-any.whl (36.3 kB view details)

Uploaded Python 3

File details

Details for the file esphome_deployment-0.1.0.tar.gz.

File metadata

  • Download URL: esphome_deployment-0.1.0.tar.gz
  • Upload date:
  • Size: 33.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for esphome_deployment-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3e7e350700e06b7ee791322773fbf08c17e841b5ed74fe95b97db32f76537b76
MD5 556e72fb50468b14423b6fab5501d4ac
BLAKE2b-256 cfd11b2764a552b040a881d66d61267fad915f023c37ac7aa4e58fd5db5925b8

See more details on using hashes here.

Provenance

The following attestation bundles were made for esphome_deployment-0.1.0.tar.gz:

Publisher: python_publish.yaml on markusressel/esphome-deployment

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file esphome_deployment-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for esphome_deployment-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 00090d8bcecca8060e8f84e0901a1de7c853d32c0f958cdffbcb934643a9dbc7
MD5 e97294bdb5c95cbcbb34be66d07a6676
BLAKE2b-256 7c8d704b0bf47bdfd902b434268f0a9cf13787c8eb0bfc5799626b6f1ddd0763

See more details on using hashes here.

Provenance

The following attestation bundles were made for esphome_deployment-0.1.0-py3-none-any.whl:

Publisher: python_publish.yaml on markusressel/esphome-deployment

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page