From 024395fc09cbc4cd178ed186355f92d8de9b0ad1 Mon Sep 17 00:00:00 2001 From: ninglinLiu Date: Thu, 29 Oct 2026 01:48:27 +0800 Subject: [PATCH] fix(cli): default deploy images to Python 3.12 Agent Engine / Cloud Run / GKE / Docker deploys defaulted to python:3.11-slim. google-cloud-modelarmor (and the Model Armor plugin) warn that Python 3.11 support ends in 2027-10 and ask for at least 3.12. Bump _DEFAULT_PYTHON_VERSION and the matching CLI defaults to 3.12. --python_version and .agent_engine_config.json still accept 3.11+. Fixes #7775 AI assistance: Cursor was used to draft this change; I reviewed and tested it. --- src/google/adk/cli/cli_deploy.py | 2 +- src/google/adk/cli/cli_tools_click.py | 16 ++++++++-------- .../adk/cli/deployers/_dockerfile_template.py | 4 ++-- tests/unittests/cli/utils/test_cli_deploy.py | 8 ++++---- .../cli/utils/test_cli_deploy_to_cloud_run.py | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/google/adk/cli/cli_deploy.py b/src/google/adk/cli/cli_deploy.py index fcb25ac8f10..8fee70e450e 100644 --- a/src/google/adk/cli/cli_deploy.py +++ b/src/google/adk/cli/cli_deploy.py @@ -264,7 +264,7 @@ def _resolve_python_version_from_agent_config( Supports three sources, in increasing precedence: - 1. The default, ``3.11``. + 1. The default, ``3.12``. 2. Top-level ``python_version`` in ``.agent_engine_config.json`` (popped so it is not forwarded to the Agent Engine API, which ignores it when the image is built from a Dockerfile). diff --git a/src/google/adk/cli/cli_tools_click.py b/src/google/adk/cli/cli_tools_click.py index 198dc6903ba..4349821de66 100644 --- a/src/google/adk/cli/cli_tools_click.py +++ b/src/google/adk/cli/cli_tools_click.py @@ -591,11 +591,11 @@ def deploy_options(command: _F) -> _F: click.option( "--python_version", type=str, - default="3.11", + default="3.12", show_default=True, help=( "Optional. The Python version used in the container image" - " (default: 3.11)." + " (default: 3.12)." ), ), click.argument( @@ -2713,7 +2713,7 @@ def cli_deploy_cloud_run( provider_args: tuple[str, ...] = (), env: tuple[str, ...] = (), extra_packages: tuple[str, ...] = (), - python_version: str = "3.11", + python_version: str = "3.12", ) -> None: """Deploys an agent to Cloud Run. @@ -2797,7 +2797,7 @@ def cli_deploy_docker( a2a: bool = False, provider_args: tuple[str, ...] = (), env: tuple[str, ...] = (), - python_version: str = "3.11", + python_version: str = "3.12", ) -> None: """Deploys an agent to a local Docker container.""" _warn_if_with_ui(with_ui) @@ -3100,7 +3100,7 @@ def cli_migrate_session( "Optional. The Python version used in the container image. Overrides" " `python_version` in `.agent_engine_config.json` when both are set." " (default: `python_version` from `.agent_engine_config.json`, or" - " 3.11)" + " 3.12)" ), ) @click.option( @@ -3369,11 +3369,11 @@ def cli_deploy_agent_engine( @click.option( "--python_version", type=str, - default="3.11", + default="3.12", show_default=True, help=( "Optional. The Python version used in the container image" - " (default: 3.11)." + " (default: 3.12)." ), ) # Kept as raw str (not parsed to list) — interpolated directly into Dockerfile CMD. @@ -3450,7 +3450,7 @@ def cli_deploy_gke( trigger_oidc_audience: str | None = None, trigger_oidc_service_accounts: str | None = None, extra_packages: tuple[str, ...] = (), - python_version: str = "3.11", + python_version: str = "3.12", ) -> None: """Deploys an agent to GKE. diff --git a/src/google/adk/cli/deployers/_dockerfile_template.py b/src/google/adk/cli/deployers/_dockerfile_template.py index c0a7cd1a32e..5a1eec84dec 100644 --- a/src/google/adk/cli/deployers/_dockerfile_template.py +++ b/src/google/adk/cli/deployers/_dockerfile_template.py @@ -31,7 +31,7 @@ r'^[A-Za-z0-9_-][A-Za-z0-9_.-]{0,62}$' ) -_DEFAULT_PYTHON_VERSION: Final[str] = '3.11' +_DEFAULT_PYTHON_VERSION: Final[str] = '3.12' _PYTHON_VERSION_PATTERN: Final[re.Pattern[str]] = re.compile( r'^3\.(1[1-9]|[2-9][0-9])(\.[0-9]+)?$' @@ -250,7 +250,7 @@ def _render_dockerfile( express_mode_option: `--express_mode` or an empty string. extra_packages_copy: Extra `COPY`/`ENV` instructions, or an empty string. extra_env_vars: Extra `ENV` lines, or an empty string. - python_version: The Python version for the base image (default: '3.11'). + python_version: The Python version for the base image (default: '3.12'). Returns: The Dockerfile contents. diff --git a/tests/unittests/cli/utils/test_cli_deploy.py b/tests/unittests/cli/utils/test_cli_deploy.py index 87718de136e..ac3076d078a 100644 --- a/tests/unittests/cli/utils/test_cli_deploy.py +++ b/tests/unittests/cli/utils/test_cli_deploy.py @@ -3152,7 +3152,7 @@ def test_to_agent_engine_renders_python_version_and_pops_config_key( assert "python_version" not in captured[0] -@pytest.mark.parametrize("cli_python_version", ["3.11", "3.13"]) +@pytest.mark.parametrize("cli_python_version", ["3.12", "3.13"]) def test_to_agent_engine_cli_python_version_overrides_config_file( monkeypatch: pytest.MonkeyPatch, agent_dir: Callable[[bool, bool], Path], @@ -3160,7 +3160,7 @@ def test_to_agent_engine_cli_python_version_overrides_config_file( ) -> None: """An explicit python_version wins over .agent_engine_config.json. - Covers both the value that equals the built-in default (3.11) and a + Covers both the value that equals the built-in default (3.12) and a different one, so the override cannot depend on a default sentinel. """ monkeypatch.setattr(shutil, "rmtree", _Recorder()) @@ -3194,7 +3194,7 @@ def test_to_agent_engine_defaults_python_version_without_flag_or_config( monkeypatch: pytest.MonkeyPatch, agent_dir: Callable[[bool, bool], Path], ) -> None: - """With neither the flag nor a config key, the image is built on 3.11.""" + """With neither the flag nor a config key, the image is built on 3.12.""" monkeypatch.setattr(shutil, "rmtree", _Recorder()) captured: List[Dict[str, Any]] = [] recording_agentplatform = _make_recording_agentplatform(captured) @@ -3215,7 +3215,7 @@ def test_to_agent_engine_defaults_python_version_without_flag_or_config( ) dockerfile_content = (tmp_dir / "Dockerfile").read_text() - assert "FROM python:3.11-slim" in dockerfile_content + assert "FROM python:3.12-slim" in dockerfile_content def test_to_agent_engine_rejects_non_string_python_version_in_config( diff --git a/tests/unittests/cli/utils/test_cli_deploy_to_cloud_run.py b/tests/unittests/cli/utils/test_cli_deploy_to_cloud_run.py index bfaeebfe940..45633d75c82 100644 --- a/tests/unittests/cli/utils/test_cli_deploy_to_cloud_run.py +++ b/tests/unittests/cli/utils/test_cli_deploy_to_cloud_run.py @@ -195,7 +195,7 @@ def test_to_cloud_run_happy_path( assert "--with_ui" not in cmd_argv assert "--port=8080" in cmd_argv assert cmd_argv[-1] == "/app/agents" - assert "FROM python:3.11-slim" in dockerfile_content + assert "FROM python:3.12-slim" in dockerfile_content assert ( 'RUN adduser --disabled-password --gecos "" myuser' in dockerfile_content )