diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3dfe9b209..488059ad42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -182,10 +182,11 @@ jobs: runs-on: ubuntu-24.04 needs: - common - # PR-branch cache saves are invisible to other PRs, so pushes seed the - # shared entry test-esp8266-native restores (same pattern as - # seed-apt-cache / cache-esp-idf). - if: github.event_name == 'push' + # PR-branch cache saves are invisible to other PRs, so dev pushes seed + # the shared entry test-esp8266-native restores. Only dev: the composite + # action saves nowhere else, so a beta/release push would download the + # toolchain and discard it. + if: github.event_name == 'push' && github.ref == 'refs/heads/dev' timeout-minutes: 15 env: # The composite action and the install below agree on this path by diff --git a/esphome/arduino8266/toolchain.py b/esphome/arduino8266/toolchain.py index d7d228d74f..988210b949 100644 --- a/esphome/arduino8266/toolchain.py +++ b/esphome/arduino8266/toolchain.py @@ -159,9 +159,11 @@ def run_compile(config: ConfigType, verbose: bool) -> int: return 1 _print_size_summary(build_dir, paths) + from esphome.build_helpers.idedata import IDEDATA_BEST_EFFORT_ERRORS + try: idedata = get_idedata(ccache) - except (EsphomeError, LookupError, OSError, RuntimeError, ValueError) as err: + except IDEDATA_BEST_EFFORT_ERRORS as err: # Broad on purpose: idedata is a bonus artifact; nothing here may # fail a successful build. _LOGGER.warning( diff --git a/esphome/core/config.py b/esphome/core/config.py index 472ca64c9a..a0c5022379 100644 --- a/esphome/core/config.py +++ b/esphome/core/config.py @@ -564,7 +564,12 @@ NATIVE_ARDUINO_PIO_OPTIONS = frozenset({"board_build.f_cpu", "board_build.ldscri # that is stored rather than translated away. Consumed by the esp8266 native # backend (later in this chain) for its ignored-option warning; defined here # so it stays adjacent to the routing. -NATIVE_ARDUINO_CONSUMED_PIO_OPTIONS = NATIVE_ARDUINO_PIO_OPTIONS | {"lib_ignore"} +# build_src_flags: set unconditionally by esp8266/__init__ (throw_stubs) and +# read by the native generator; not user-routable, so not in the set above +NATIVE_ARDUINO_CONSUMED_PIO_OPTIONS = NATIVE_ARDUINO_PIO_OPTIONS | { + "lib_ignore", + "build_src_flags", +} @coroutine_with_priority(CoroPriority.FINAL) diff --git a/script/test_build_components.py b/script/test_build_components.py index e4911ab1d6..01121a277e 100755 --- a/script/test_build_components.py +++ b/script/test_build_components.py @@ -1075,13 +1075,26 @@ def test_components( ) # Renamed or removed fixtures must shrink coverage loudly, and the - # reference-baseline fallback below must not mask an empty match + # reference-baseline fallback below must not mask an empty match. The + # check is per platform: a component whose fixture exists only for other + # platforms contributes nothing to this leg. + def _has_platform_test(component: str) -> bool: + return any( + not platform_filter or test.stem.split(".")[-1].startswith(platform_filter) + for test in all_tests.get(component, []) + ) + if fail_on_no_tests and ( unmatched := [ - p for p in component_patterns if p and "*" not in p and p not in all_tests + p + for p in component_patterns + if p and "*" not in p and not _has_platform_test(p) ] ): - print(f"No tests found for requested component(s): {', '.join(unmatched)}") + target = f"{platform_filter} " if platform_filter else "" + print( + f"No {target}tests found for requested component(s): {', '.join(unmatched)}" + ) return 1 # If no components found, build a reference configuration for baseline comparison diff --git a/tests/script/test_determine_jobs.py b/tests/script/test_determine_jobs.py index d6bb3f80eb..edd12d8d14 100644 --- a/tests/script/test_determine_jobs.py +++ b/tests/script/test_determine_jobs.py @@ -117,6 +117,7 @@ def clear_determine_jobs_caches() -> None: """Clear all cached functions before each test.""" determine_jobs._is_clang_tidy_full_scan.cache_clear() determine_jobs._component_has_tests.cache_clear() + determine_jobs._cached_components_closure.cache_clear() def test_main_all_tests_should_run( diff --git a/tests/script/test_test_build_components.py b/tests/script/test_test_build_components.py index efd4a9e41d..4773d04b6c 100644 --- a/tests/script/test_test_build_components.py +++ b/tests/script/test_test_build_components.py @@ -248,13 +248,18 @@ def test_components_empty_match_fails_with_flag( ["logger"], "zz-none", "compile", False, fail_on_no_tests=True ) assert rc == 1 - assert "No tests matched" in capsys.readouterr().out + assert "No zz-none tests found" in capsys.readouterr().out def test_components_empty_match_tolerated_without_flag() -> None: """The esp32-ard smoke leg deliberately builds only the subset with a matching fixture; without the flag an empty match stays green.""" - assert tbc.test_components(["logger"], "zz-none", "compile", False) == 0 + assert ( + tbc.test_components( + ["logger"], "zz-none", "compile", False, enable_grouping=False + ) + == 0 + ) def test_components_unknown_component_fails_with_flag( @@ -270,4 +275,7 @@ def test_components_unknown_component_fails_with_flag( fail_on_no_tests=True, ) assert rc == 1 - assert "No tests found for requested component(s)" in capsys.readouterr().out + assert ( + "No esp8266-ard tests found for requested component(s)" + in capsys.readouterr().out + ) diff --git a/tests/unit_tests/test_arduino8266_toolchain.py b/tests/unit_tests/test_arduino8266_toolchain.py index 0cf5962559..44916453c9 100644 --- a/tests/unit_tests/test_arduino8266_toolchain.py +++ b/tests/unit_tests/test_arduino8266_toolchain.py @@ -500,11 +500,13 @@ def test_print_size_summary_missing_section_skips_summary( def test_warn_ignored_platformio_options(caplog: pytest.LogCaptureFixture) -> None: """Component-added options the native build drops are warned by name; - the honored ones (lib_ignore, f_cpu, ldscript) stay quiet.""" + the honored ones (lib_ignore, f_cpu, ldscript, build_src_flags) stay + quiet.""" CORE.platformio_options = { "board_build.ldscript": "eagle.flash.4m2m.ld", "board_build.f_cpu": "160000000L", "board_build.filesystem": "littlefs", + "build_src_flags": "-include throw_stubs.h", "lib_ignore": ["Updater"], "upload_speed": "460800", } @@ -514,6 +516,7 @@ def test_warn_ignored_platformio_options(caplog: pytest.LogCaptureFixture) -> No assert "board_build.ldscript is ignored" not in caplog.text assert "board_build.f_cpu is ignored" not in caplog.text assert "lib_ignore" not in caplog.text + assert "build_src_flags" not in caplog.text # Component-added upload_speed never gets read under the native # toolchain, so it must warn assert "upload_speed" in caplog.text