From 86c9dee8d89e4bf6fdea29a6417b4cb7a7a1f1c1 Mon Sep 17 00:00:00 2001 From: Imani Pelton Date: Fri, 1 May 2026 16:39:47 -0400 Subject: [PATCH] fix: correctly get project name for remote builds --- charmcraft/application/commands/remote.py | 4 +- docs/release-notes/charmcraft-4.2.rst | 5 +++ tests/unit/commands/test_remote.py | 48 +++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/unit/commands/test_remote.py diff --git a/charmcraft/application/commands/remote.py b/charmcraft/application/commands/remote.py index fda63b0e3..47f1bd5b7 100644 --- a/charmcraft/application/commands/remote.py +++ b/charmcraft/application/commands/remote.py @@ -29,6 +29,7 @@ from overrides import override # pyright: ignore[reportUnknownVariableType] from charmcraft import models, utils +from charmcraft.services.project import ProjectService OVERVIEW = """\ Command remote-build sends the current project to be built @@ -106,7 +107,8 @@ def _run(self, parsed_args: argparse.Namespace, **kwargs: Any) -> int | None: return 77 # permission denied from sysexits.h builder = self._services.remote_build - project = cast(models.Charm, self._services.project) + project_service = cast("ProjectService", self._services.project) + project = cast("models.Charm", project_service.get()) config = cast(dict[str, Any], self.config) project_dir = ( pathlib.Path(config.get("global_args", {}).get("project_dir") or ".") diff --git a/docs/release-notes/charmcraft-4.2.rst b/docs/release-notes/charmcraft-4.2.rst index 77129c1fd..6024a1b7b 100644 --- a/docs/release-notes/charmcraft-4.2.rst +++ b/docs/release-notes/charmcraft-4.2.rst @@ -121,6 +121,11 @@ The following issues have been resolved in Charmcraft 4.2.1: - `#2620 `__ Multi-base shorthand notation fails on v4.2.0 +The following issues have been resolved in Charmcraft 4.2.2: + +- `#2598 `__ Remote build fails + when getting project name + Contributors ------------ diff --git a/tests/unit/commands/test_remote.py b/tests/unit/commands/test_remote.py new file mode 100644 index 000000000..c90004715 --- /dev/null +++ b/tests/unit/commands/test_remote.py @@ -0,0 +1,48 @@ +# Copyright 2026 Canonical Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# For further info, check https://github.com/canonical/charmcraft + +"""Unit tests for remote-build""" + +import argparse + +from pytest_mock import MockerFixture + +from charmcraft import services +from charmcraft.application import APP_METADATA +from charmcraft.application.commands.remote import RemoteBuild +from charmcraft.services.project import ProjectService + + +def test_remote_build_project_name_attr_regression( + mocker: MockerFixture, service_factory: services.ServiceFactory +) -> None: + """Regression test for https://github.com/canonical/charmcraft/issues/2598 + + The project service was being erroneously cast as the project model, causing + a later access to the `.name` field not be caught by linters. + """ + remote_build_cmd = RemoteBuild({"app": APP_METADATA, "services": service_factory}) + namespace = argparse.Namespace( + launchpad_accept_public_upload=True, + recover=False, + launchpad_timeout=0, + ) + mocker.patch("charmcraft.services.remotebuild.RemoteBuildService") + project_spy = mocker.spy(ProjectService, "get") + + remote_build_cmd.run(namespace) + + project_spy.assert_called_once()