This script injects a git-based firmware version into PlatformIO ESP32 firmware
This is a Python script that you can use in your PlatformIO build process to inject a firmware version string based on the current Git tag and commit into your ESP32 firmware binary. This is useful for tracking which version of the firmware is running on your device.
An example for a version it could inject is v1.0.0-123-gabc1234@2025-08-27T02:06:15
.
#!/usr/bin/env python3
import subprocess
from datetime import datetime
import argparse
import sys
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--environment", help="The build environment to use")
parser.add_argument("--chip", default="esp32", help="The chip to use (for esptool.py elf2image)")
parser.add_argument("--flash_freq", default="40m", help="The flash frequency (for esptool.py elf2image)")
parser.add_argument("--flash_mode", default="dio", help="The flash mode (for esptool.py elf2image)")
args = parser.parse_args()
# Determine git version & build date
version = subprocess.check_output("git describe --long --tags --dirty", shell=True).strip().decode("utf-8")
date = datetime.utcnow().isoformat()
# Join version & date
full_version_string = f"{version}@{date}".encode("utf-8")
firmware_version_template = b"================================================================================"
# If no environment is specified, just print the version and exit
if not args.environment:
print(f"Version: {version}")
print("No --environment specified, exiting...")
sys.exit(1)
with open(f".pio/build/{args.environment}/firmware.elf", "rb") as infile:
firmware_binary = infile.read()
# The replacement strings must have exactly the right length!
version_replacement = full_version_string.ljust(len(firmware_version_template), b'\0')
# Replace!
firmware_binary = firmware_binary.replace(firmware_version_template, version_replacement, 1)
# Write back to file
with open(f".pio/build/{args.environment}/firmware-versioned.elf", "wb") as outfile:
outfile.write(firmware_binary)
# Write version to file
with open(f".pio/build/{args.environment}/version.txt", "w", encoding="utf-8") as outfile:
outfile.write(version)
# Convert to ELF
subprocess.check_output(f"esptool.py --chip {args.chip} elf2image --flash_freq {args.flash_freq} --flash_mode {args.flash_mode} .pio/build/{args.environment}/firmware-versioned.elf", shell=True)
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow