From 1a76f6a92aef817d41b63d8ce4eeca973a581c92 Mon Sep 17 00:00:00 2001 From: Florian Courtial <173065277+fcourtial@users.noreply.github.com> Date: Thu, 5 Jun 2025 00:48:48 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20[CLI]=20Generate=20one=20`--buil?= =?UTF-8?q?d-context`=20argument=20for=20each=20dependency=20in=20the=20`d?= =?UTF-8?q?ocker=20build`=20command.=20(#4962)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Generate one `--build-context` for each dependency in the `docker build` command. * Try and fix test --------- Co-authored-by: Nuno Campos --- libs/cli/langgraph_cli/cli.py | 6 ++-- libs/cli/tests/unit_tests/cli/test_cli.py | 41 +++++++++++++++++++++-- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/libs/cli/langgraph_cli/cli.py b/libs/cli/langgraph_cli/cli.py index cf2c1429c..c968f33bc 100644 --- a/libs/cli/langgraph_cli/cli.py +++ b/libs/cli/langgraph_cli/cli.py @@ -318,10 +318,8 @@ def _build( ) # add additional_contexts if additional_contexts: - additional_contexts_str = ",".join( - f"{k}={v}" for k, v in additional_contexts.items() - ) - args.extend(["--build-context", additional_contexts_str]) + for k, v in additional_contexts.items(): + args.extend(["--build-context", f"{k}={v}"]) # run docker build runner.run( subp_exec( diff --git a/libs/cli/tests/unit_tests/cli/test_cli.py b/libs/cli/tests/unit_tests/cli/test_cli.py index f458cbcbc..c68c13227 100644 --- a/libs/cli/tests/unit_tests/cli/test_cli.py +++ b/libs/cli/tests/unit_tests/cli/test_cli.py @@ -22,12 +22,14 @@ DEFAULT_DOCKER_CAPABILITIES = DockerCapabilities( @contextmanager -def temporary_config_folder(config_content: dict): +def temporary_config_folder(config_content: dict, levels: int = 0): # Create a temporary directory temp_dir = tempfile.mkdtemp() try: # Define the path for the config.json file - config_path = Path(temp_dir) / "config.json" + config_path = Path(temp_dir) / f"{'a/' * levels}config.json" + # Ensure the parent directory exists + config_path.parent.mkdir(parents=True, exist_ok=True) # Write the provided dictionary content to config.json with open(config_path, "w", encoding="utf-8") as config_file: @@ -532,3 +534,38 @@ def test_build_command_shows_wolfi_warning() -> None: assert "Wolfi Linux" in result.output assert "image_distro" in result.output assert "wolfi" in result.output + + +def test_build_generate_proper_build_context(): + runner = CliRunner() + config_content = { + "python_version": "3.11", + "graphs": {"agent": "agent.py:graph"}, + "dependencies": [".", "../../..", "../.."], + "image_distro": "wolfi", + } + + with temporary_config_folder(config_content, levels=3) as temp_dir: + agent_path = temp_dir / "agent.py" + agent_path.touch() + + # Mock docker command since we don't want to actually build + with runner.isolated_filesystem(): + result = runner.invoke( + cli, + [ + "build", + "--tag", + "test-image", + "--config", + str(temp_dir / "config.json"), + ], + catch_exceptions=True, + ) + + build_context_pattern = re.compile(r"--build-context\s+(\w+)=([^\s]+)") + + build_contexts = re.findall(build_context_pattern, result.output) + assert ( + len(build_contexts) == 2 + ), f"Expected 2 build contexts, but found {len(build_contexts)}"