diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index beb41b30f4..d2dc979966 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -470,21 +470,20 @@ def set_core_data(config): framework_ver = cv.Version.parse(config[CONF_FRAMEWORK][CONF_VERSION]) CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] = framework_ver - # Store the underlying IDF version for framework-agnostic checks + # Store the underlying IDF version for framework-agnostic checks. if conf[CONF_TYPE] == FRAMEWORK_ESP_IDF: - CORE.data[KEY_ESP32][KEY_IDF_VERSION] = framework_ver - elif (idf_ver := ARDUINO_IDF_VERSION_LOOKUP.get(framework_ver)) is not None: - if CORE.using_toolchain_esp_idf: - # Official ESP-IDF frameworks don't use extra - idf_ver = cv.Version(idf_ver.major, idf_ver.minor, idf_ver.patch) - CORE.data[KEY_ESP32][KEY_IDF_VERSION] = idf_ver - else: + idf_ver = framework_ver + elif (idf_ver := ARDUINO_IDF_VERSION_LOOKUP.get(framework_ver)) is None: raise cv.Invalid( f"Arduino version {framework_ver} has no known ESP-IDF version mapping. " "Please update ARDUINO_IDF_VERSION_LOOKUP.", path=[CONF_FRAMEWORK, CONF_VERSION], ) + # The esp-idf toolchain doesn't use pioarduino's packaging revision; PIO does. + if CORE.using_toolchain_esp_idf: + idf_ver = _strip_pioarduino_revision(idf_ver) + CORE.data[KEY_ESP32][KEY_IDF_VERSION] = idf_ver CORE.data[KEY_ESP32][KEY_BOARD] = config[CONF_BOARD] CORE.data[KEY_ESP32][KEY_FLASH_SIZE] = config[CONF_FLASH_SIZE] CORE.data[KEY_ESP32][KEY_VARIANT] = variant @@ -721,6 +720,9 @@ ARDUINO_FRAMEWORK_VERSION_LOOKUP = { "dev": cv.Version(3, 3, 8), } ARDUINO_PLATFORM_VERSION_LOOKUP = { + cv.Version( + 4, 0, 0, "alpha1" + ): "https://github.com/pioarduino/platform-espressif32.git#prep_IDF6", cv.Version(3, 3, 8): cv.Version(55, 3, 38, "1"), cv.Version(3, 3, 7): cv.Version(55, 3, 37), cv.Version(3, 3, 6): cv.Version(55, 3, 36), @@ -741,6 +743,7 @@ ARDUINO_PLATFORM_VERSION_LOOKUP = { # These versions correspond to pioarduino/esp-idf releases # See: https://github.com/pioarduino/esp-idf/releases ARDUINO_IDF_VERSION_LOOKUP = { + cv.Version(4, 0, 0, "alpha1"): cv.Version(6, 0, 1), cv.Version(3, 3, 8): cv.Version(5, 5, 4), cv.Version(3, 3, 7): cv.Version(5, 5, 3, "1"), cv.Version(3, 3, 6): cv.Version(5, 5, 2), @@ -835,6 +838,16 @@ def _resolve_framework_version(value: ConfigType) -> cv.Version: return version +def _strip_pioarduino_revision(ver: cv.Version) -> cv.Version: + """Drop a numeric 'extra' (pioarduino packaging revision, e.g. "5.5.3-1"). + + Alphanumeric prerelease extras (e.g. "6.0.0-rc1") are kept. + """ + if ver.extra.isdigit(): + return cv.Version(ver.major, ver.minor, ver.patch) + return ver + + def _check_pio_versions(config: ConfigType) -> ConfigType: config = config.copy() value = config[CONF_FRAMEWORK] @@ -903,8 +916,10 @@ def _check_esp_idf_versions(config: ConfigType) -> ConfigType: "If there are connectivity or build issues please remove the manual source." ) - # Official ESP-IDF frameworks don't use the 'extra' semver component. - value[CONF_VERSION] = str(cv.Version(version.major, version.minor, version.patch)) + # esp-idf framework only: drop pioarduino's packaging revision (config + download). + # Arduino keeps its extra (it's the arduino-esp32 release tag / lookup key). + if value[CONF_TYPE] == FRAMEWORK_ESP_IDF: + value[CONF_VERSION] = str(_strip_pioarduino_revision(version)) return config diff --git a/esphome/espidf/framework.py b/esphome/espidf/framework.py index b2251d00d8..6ef73a2199 100644 --- a/esphome/espidf/framework.py +++ b/esphome/espidf/framework.py @@ -74,7 +74,7 @@ ESPHOME_IDF_FRAMEWORK_MIRRORS = _str_to_lst_of_str( os.environ.get("ESPHOME_IDF_FRAMEWORK_MIRRORS") or [ "https://github.com/esphome-libs/esp-idf/releases/download/v{VERSION}/esp-idf-v{VERSION}.tar.xz", - "https://github.com/esphome-libs/esp-idf/releases/download/v{MAJOR}.{MINOR}/esp-idf-v{MAJOR}.{MINOR}.tar.xz", + "https://github.com/esphome-libs/esp-idf/releases/download/v{MAJOR}.{MINOR}{EXTRA}/esp-idf-v{MAJOR}.{MINOR}{EXTRA}.tar.xz", ] ) @@ -979,8 +979,9 @@ def _check_esphome_idf_framework_install( env: Optional dictionary of environment variables to set source_url: Optional override URL for the framework tarball. Supports the same ``{VERSION}`` / ``{MAJOR}`` / ``{MINOR}`` / ``{PATCH}`` / - ``{EXTRA}`` substitutions as ESPHOME_IDF_FRAMEWORK_MIRRORS. When - set, it replaces the default mirror list — no implicit fallback, + ``{EXTRA}`` substitutions as ESPHOME_IDF_FRAMEWORK_MIRRORS + (``{EXTRA}`` includes its leading ``-``, e.g. ``-rc1``, or is empty). + When set, it replaces the default mirror list — no implicit fallback, so a misspelled URL fails loudly. Returns: @@ -1035,7 +1036,7 @@ def _check_esphome_idf_framework_install( substitutions["MAJOR"] = str(ver.major) substitutions["MINOR"] = str(ver.minor) substitutions["PATCH"] = str(ver.patch) - substitutions["EXTRA"] = ver.extra + substitutions["EXTRA"] = f"-{ver.extra}" if ver.extra else "" except ValueError: pass