diff --git a/newsfragments/fix-forwarding-exit-code-for-push-command.bugfix b/newsfragments/fix-forwarding-exit-code-for-push-command.bugfix new file mode 100644 index 0000000..0972449 --- /dev/null +++ b/newsfragments/fix-forwarding-exit-code-for-push-command.bugfix @@ -0,0 +1 @@ +Implemented forwarding failure exit code from `push` command. diff --git a/podman_compose.py b/podman_compose.py index 61c0a55..2b33248 100755 --- a/podman_compose.py +++ b/podman_compose.py @@ -2799,14 +2799,18 @@ async def compose_pull(compose: PodmanCompose, args: argparse.Namespace) -> None @cmd_run(podman_compose, "push", "push stack images") -async def compose_push(compose: PodmanCompose, args: argparse.Namespace) -> None: +async def compose_push(compose: PodmanCompose, args: argparse.Namespace) -> int | None: services = set(args.services) + status = 0 for cnt in compose.containers: if "build" not in cnt: continue if services and cnt["_service"] not in services: continue - await compose.podman.run([], "push", [cnt["image"]]) + s = await compose.podman.run([], "push", [cnt["image"]]) + if s is not None and s != 0: + status = s + return status def is_context_git_url(path: str) -> bool: diff --git a/tests/integration/build_fail_multi/test_podman_compose_build_fail_multi.py b/tests/integration/build_fail_multi/test_podman_compose_build_fail_multi.py deleted file mode 100644 index 167becb..0000000 --- a/tests/integration/build_fail_multi/test_podman_compose_build_fail_multi.py +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -import os -import unittest - -from tests.integration.test_utils import RunSubprocessMixin -from tests.integration.test_utils import podman_compose_path -from tests.integration.test_utils import test_path - - -def compose_yaml_path(): - """ "Returns the path to the compose file used for this test module""" - base_path = os.path.join(test_path(), "build_fail_multi") - return os.path.join(base_path, "docker-compose.yml") - - -class TestComposeBuildFailMulti(unittest.TestCase, RunSubprocessMixin): - def test_build_fail_multi(self): - output, error = self.run_subprocess_assert_returncode( - [ - podman_compose_path(), - "-f", - compose_yaml_path(), - "build", - # prevent the successful build from being cached to ensure it runs long enough - "--no-cache", - ], - expected_returncode=1, - ) - self.assertIn("RUN false", str(output)) - self.assertIn("while running runtime: exit status 1", str(error)) diff --git a/tests/integration/build_fail_multi/__init__.py b/tests/integration/commands_fail_exit_code/__init__.py similarity index 100% rename from tests/integration/build_fail_multi/__init__.py rename to tests/integration/commands_fail_exit_code/__init__.py diff --git a/tests/integration/build_fail_multi/bad/Dockerfile b/tests/integration/commands_fail_exit_code/bad/Dockerfile similarity index 100% rename from tests/integration/build_fail_multi/bad/Dockerfile rename to tests/integration/commands_fail_exit_code/bad/Dockerfile diff --git a/tests/integration/build_fail_multi/docker-compose.yml b/tests/integration/commands_fail_exit_code/docker-compose.yml similarity index 100% rename from tests/integration/build_fail_multi/docker-compose.yml rename to tests/integration/commands_fail_exit_code/docker-compose.yml diff --git a/tests/integration/build_fail_multi/good/Dockerfile b/tests/integration/commands_fail_exit_code/good/Dockerfile similarity index 100% rename from tests/integration/build_fail_multi/good/Dockerfile rename to tests/integration/commands_fail_exit_code/good/Dockerfile diff --git a/tests/integration/commands_fail_exit_code/test_podman_compose_commands_fail_exit_code.py b/tests/integration/commands_fail_exit_code/test_podman_compose_commands_fail_exit_code.py new file mode 100644 index 0000000..0e4fa4e --- /dev/null +++ b/tests/integration/commands_fail_exit_code/test_podman_compose_commands_fail_exit_code.py @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0 + +import os +import unittest + +from tests.integration.test_utils import RunSubprocessMixin +from tests.integration.test_utils import podman_compose_path +from tests.integration.test_utils import test_path + + +def compose_yaml_path() -> str: + """ "Returns the path to the compose file used for this test module""" + base_path = os.path.join(test_path(), "commands_fail_exit_code") + return os.path.join(base_path, "docker-compose.yml") + + +class TestComposeCommandsFailExitCodes(unittest.TestCase, RunSubprocessMixin): + def test_build_command_fail(self) -> None: + output, error = self.run_subprocess_assert_returncode( + [ + podman_compose_path(), + "-f", + compose_yaml_path(), + "build", + # prevent the successful build from being cached to ensure it runs long enough + "--no-cache", + ], + expected_returncode=1, + ) + self.assertIn("RUN false", str(output)) + self.assertIn("while running runtime: exit status 1", str(error)) + + def test_push_command_fail(self) -> None: + # test that push command is able to return other than "0" return code + # "push" command fails due to several steps missing before running it (logging, tagging) + try: + output, error = self.run_subprocess_assert_returncode( + [ + podman_compose_path(), + "-f", + compose_yaml_path(), + "push", + "good", + ], + expected_returncode=125, + ) + finally: + self.run_subprocess_assert_returncode([ + podman_compose_path(), + "-f", + compose_yaml_path(), + "down", + ]) + + def test_run_command_fail(self) -> None: + # test that run command is able to return other than "0" return code + try: + output, error = self.run_subprocess_assert_returncode( + [ + podman_compose_path(), + "-f", + compose_yaml_path(), + "run", + "bad", + ], + expected_returncode=125, + ) + self.assertIn("RUN false", str(output)) + self.assertIn("while running runtime: exit status 1", str(error)) + finally: + self.run_subprocess_assert_returncode([ + podman_compose_path(), + "-f", + compose_yaml_path(), + "down", + ])