[ci] Skip the bootloader in the component batch build jobs (#19931)

This commit is contained in:
J. Nick Koston
2026-10-01 14:05:15 -05:00
committed by GitHub
parent bfb7e76b2e
commit 7962b52d2a
3 changed files with 116 additions and 1 deletions
+8 -1
View File
@@ -1225,7 +1225,14 @@ jobs:
if [ -n "$compile_csv" ]; then
# Run compilation with grouping and isolation
python3 script/test_build_components.py -e compile -c "$compile_csv" -f --isolate "$directly_changed_csv"
# The bootloader has no ESPHome code and these builds never
# flash; the check_idf_py batch keeps the full build so the
# native sub-build and the equivalence check stay covered.
skip_flag="--skip-bootloader"
if [[ "${{ matrix.batch.check_idf_py }}" == "true" ]]; then
skip_flag=""
fi
python3 script/test_build_components.py -e compile -c "$compile_csv" -f --isolate "$directly_changed_csv" $skip_flag
if [[ "${{ matrix.batch.check_idf_py }}" == "true" ]]; then
# The real idf.py must find nothing to configure or build in a
# tree built above; catches drift on ESP-IDF bumps.
+27
View File
@@ -333,6 +333,12 @@ def extract_platform_with_version(base_file: Path) -> str:
return base_file.stem.replace("build_components_base.", "")
def _wants_skip_bootloader(skip: bool, command: str, platform: str) -> bool:
"""Every esp32 target: idf variants, and esp32-ard, whose Arduino
core builds as an ESP-IDF component under the native toolchain."""
return skip and command == "compile" and platform.startswith("esp32")
def run_esphome_test(
component: str,
test_file: Path,
@@ -344,6 +350,7 @@ def run_esphome_test(
continue_on_fail: bool,
use_testing_mode: bool = False,
toolchain: str | None = None,
skip_bootloader: bool = False,
) -> TestResult:
"""Run esphome test for a single component.
@@ -408,6 +415,8 @@ def run_esphome_test(
# Add command
cmd.append(esphome_command)
if _wants_skip_bootloader(skip_bootloader, esphome_command, platform):
cmd.append("--skip-bootloader")
# Add config file
cmd.append(str(output_file))
@@ -469,6 +478,7 @@ def run_grouped_test(
esphome_command: str,
continue_on_fail: bool,
toolchain: str | None = None,
skip_bootloader: bool = False,
) -> TestResult:
"""Run esphome test for a group of components with shared bus configs.
@@ -554,6 +564,8 @@ def run_grouped_test(
# Add command
cmd.append(esphome_command)
if _wants_skip_bootloader(skip_bootloader, esphome_command, platform):
cmd.append("--skip-bootloader")
cmd.append(str(output_file))
@@ -614,6 +626,7 @@ def run_grouped_component_tests(
continue_on_fail: bool,
additional_isolated: set[str] | None = None,
toolchain: str | None = None,
skip_bootloader: bool = False,
) -> tuple[set[tuple[str, str]], list[TestResult]]:
"""Run grouped component tests.
@@ -956,6 +969,7 @@ def run_grouped_component_tests(
esphome_command=esphome_command,
continue_on_fail=continue_on_fail,
toolchain=toolchain,
skip_bootloader=skip_bootloader,
)
# Mark all components as tested
@@ -980,6 +994,7 @@ def run_individual_component_test(
tested_components: set[tuple[str, str]],
test_results: list[TestResult],
toolchain: str | None = None,
skip_bootloader: bool = False,
) -> None:
"""Run an individual component test if not already tested in a group.
@@ -1014,6 +1029,7 @@ def run_individual_component_test(
esphome_command=esphome_command,
continue_on_fail=continue_on_fail,
toolchain=toolchain,
skip_bootloader=skip_bootloader,
)
test_results.append(test_result)
@@ -1027,6 +1043,7 @@ def test_components(
isolated_components: set[str] | None = None,
base_only: bool = False,
toolchain: str | None = None,
skip_bootloader: bool = False,
fail_on_no_tests: bool = False,
) -> int:
"""Test components with optional intelligent grouping.
@@ -1127,6 +1144,7 @@ def test_components(
continue_on_fail=continue_on_fail,
additional_isolated=isolated_components,
toolchain=toolchain,
skip_bootloader=skip_bootloader,
)
test_results.extend(grouped_results)
@@ -1156,6 +1174,7 @@ def test_components(
tested_components=tested_components,
test_results=test_results,
toolchain=toolchain,
skip_bootloader=skip_bootloader,
)
else:
# Platform-specific test
@@ -1189,6 +1208,7 @@ def test_components(
tested_components=tested_components,
test_results=test_results,
toolchain=toolchain,
skip_bootloader=skip_bootloader,
)
silent: list[str] = []
@@ -1294,6 +1314,12 @@ def main() -> int:
"--toolchain",
help="Select toolchain for compiling.",
)
parser.add_argument(
"--skip-bootloader",
action="store_true",
help="Pass --skip-bootloader to esphome compile; component builds "
"never flash, and the bootloader is covered by the toolchain jobs",
)
parser.add_argument(
"--fail-on-no-tests",
action="store_true",
@@ -1321,6 +1347,7 @@ def main() -> int:
fail_on_no_tests=args.fail_on_no_tests,
base_only=args.base_only,
toolchain=args.toolchain,
skip_bootloader=args.skip_bootloader,
)
@@ -94,6 +94,87 @@ def test_run_esphome_test_wraps_output_in_group(
assert out.index("::group::") < out.index("> [foo]") < out.index("::endgroup::")
@pytest.mark.parametrize(
("platform", "command", "skip", "expects_flag"),
[
("esp32-idf", "compile", True, True),
("esp32-s3-idf", "compile", True, True),
("esp32-ard", "compile", True, True),
("esp32-idf", "compile", False, False),
("esp32-idf", "config", True, False),
("esp8266-ard", "compile", True, False),
],
ids=[
"idf-skip",
"idf-variant",
"arduino-as-idf-component",
"idf-off",
"config",
"esp8266",
],
)
def test_run_esphome_test_skip_bootloader_argv(
_ci: None,
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
platform: str,
command: str,
skip: bool,
expects_flag: bool,
) -> None:
"""The flag lands on esp32 family compiles only."""
seen: list[list[str]] = []
def fake_run(cmd: list[str], **kwargs: object) -> _FakeCompleted:
seen.append(cmd)
return _FakeCompleted(0)
monkeypatch.setattr(tbc.subprocess, "run", fake_run)
repo_root = Path(tbc.__file__).parent.parent
test_file = repo_root / "tests" / "components" / "foo" / f"test.{platform}.yaml"
tbc.run_esphome_test(
component="foo",
test_file=test_file,
platform=platform,
platform_with_version=platform,
base_file=_make_base_file(tmp_path),
build_dir=tmp_path,
esphome_command=command,
continue_on_fail=True,
skip_bootloader=skip,
)
assert ("--skip-bootloader" in seen[0]) is expects_flag
def test_run_grouped_test_skip_bootloader_argv(
_ci: None,
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
) -> None:
"""The grouped command site adds the flag the same way."""
seen: list[list[str]] = []
def fake_run(cmd: list[str], **kwargs: object) -> _FakeCompleted:
seen.append(cmd)
return _FakeCompleted(0)
monkeypatch.setattr(tbc.subprocess, "run", fake_run)
repo_root = Path(tbc.__file__).parent.parent
tests_dir = repo_root / "tests" / "components"
tbc.run_grouped_test(
components=["gpio"],
platform="esp32-idf",
platform_with_version="esp32-idf",
base_file=_make_base_file(tmp_path),
build_dir=tmp_path,
tests_dir=tests_dir,
esphome_command="compile",
continue_on_fail=True,
skip_bootloader=True,
)
assert "--skip-bootloader" in seen[0]
def test_run_esphome_test_closes_group_before_failure_report(
_ci: None,
monkeypatch: pytest.MonkeyPatch,