Compare commits

...

1 Commits

Author SHA1 Message Date
Stefan Agner
5212cf147f Always pass BUILD_FROM build arg for app builds
Apps without build.yaml/build.json that use `ARG BUILD_FROM` without a
default value in their Dockerfile failed to build because BUILD_FROM was
not passed as a build arg. Restore the pre-existing behavior of always
passing BUILD_FROM, defaulting to the architecture-specific base image
when no build config file is present.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 00:46:38 +02:00
2 changed files with 26 additions and 15 deletions

View File

@@ -121,11 +121,11 @@ class AppBuild(CoreSysAttributes):
return self.sys_arch.match([self.app.arch])
@property
def base_image(self) -> str | None:
"""Return base image for this app, or None to use Dockerfile default."""
# No build config (otherwise default is coerced when reading the config)
def base_image(self) -> str:
"""Return base image for this app."""
# No build config - use default base image for the architecture
if not self._build_config.get(ATTR_BUILD_FROM):
return None
return f"ghcr.io/home-assistant/{self.arch!s}-base:latest"
# Single base image in build config
if isinstance(self._build_config[ATTR_BUILD_FROM], str):
@@ -249,14 +249,12 @@ class AppBuild(CoreSysAttributes):
build_cmd.extend(["--label", f"{key}={value}"])
build_args = {
"BUILD_FROM": self.base_image,
"BUILD_VERSION": version,
"BUILD_ARCH": self.arch,
**self.additional_args,
}
if self.base_image is not None:
build_args["BUILD_FROM"] = self.base_image
for key, value in build_args.items():
build_cmd.extend(["--build-arg", f"{key}={value}"])

View File

@@ -23,6 +23,16 @@ def _is_build_arg_in_command(command: list[str], arg_name: str) -> bool:
return f"--build-arg {arg_name}=" in " ".join(command)
def _get_build_arg_value(command: list[str], arg_name: str) -> str | None:
"""Get the value of a build arg from docker command."""
prefix = f"{arg_name}="
for i, part in enumerate(command):
if part == "--build-arg" and i + 1 < len(command):
if command[i + 1].startswith(prefix):
return command[i + 1][len(prefix) :]
return None
def _is_label_in_command(
command: list[str], label_name: str, label_value: str = ""
) -> bool:
@@ -284,12 +294,12 @@ async def test_no_build_file_no_deprecation_warning(
assert "uses build.yaml which is deprecated" not in caplog.text
async def test_no_build_yaml_base_image_none(
async def test_no_build_yaml_base_image_default(
coresys: CoreSys, install_app_ssh: App, tmp_path: Path
):
"""Test base_image is None when no build file exists."""
"""Test base_image returns default when no build file exists."""
dockerfile = tmp_path / "Dockerfile"
dockerfile.write_text("ARG BUILD_FROM=ghcr.io/home-assistant/base:latest\n")
dockerfile.write_text("ARG BUILD_FROM\nFROM ${BUILD_FROM}\n")
with patch.object(
type(install_app_ssh),
@@ -297,15 +307,15 @@ async def test_no_build_yaml_base_image_none(
new=PropertyMock(return_value=tmp_path),
):
build = await AppBuild.create(coresys, install_app_ssh)
assert build.base_image is None
assert build.base_image == "ghcr.io/home-assistant/amd64-base:latest"
async def test_no_build_yaml_no_build_from_arg(
async def test_no_build_yaml_default_build_from_arg(
coresys: CoreSys, install_app_ssh: App, tmp_path: Path
):
"""Test BUILD_FROM is not in docker args when no build file exists."""
"""Test BUILD_FROM uses default base image when no build file exists."""
dockerfile = tmp_path / "Dockerfile"
dockerfile.write_text("ARG BUILD_FROM=ghcr.io/home-assistant/base:latest\n")
dockerfile.write_text("ARG BUILD_FROM\nFROM ${BUILD_FROM}\n")
with (
patch.object(
@@ -330,7 +340,10 @@ async def test_no_build_yaml_no_build_from_arg(
build.get_docker_args, AwesomeVersion("1.0.0"), "test-image:1.0.0", None
)
assert not _is_build_arg_in_command(args["command"], "BUILD_FROM")
assert _is_build_arg_in_command(args["command"], "BUILD_FROM")
assert _get_build_arg_value(args["command"], "BUILD_FROM") == (
"ghcr.io/home-assistant/amd64-base:latest"
)
assert _is_build_arg_in_command(args["command"], "BUILD_VERSION")
assert _is_build_arg_in_command(args["command"], "BUILD_ARCH")