diff --git a/src/agentex/lib/cli/handlers/deploy_handlers.py b/src/agentex/lib/cli/handlers/deploy_handlers.py index 605d91709..e1cd1965c 100644 --- a/src/agentex/lib/cli/handlers/deploy_handlers.py +++ b/src/agentex/lib/cli/handlers/deploy_handlers.py @@ -389,6 +389,8 @@ def merge_deployment_configs( _deep_merge(helm_values, agent_env_config.helm_overrides) logger.info(f"After-merge helm values: {helm_values}") + _stamp_agent_version(helm_values, set(all_env_vars) | {var["name"] for var in secret_env_vars}) + # Set final environment variables # Environment variable precedence: manifest -> environments.yaml -> secrets (highest) if all_env_vars: @@ -430,6 +432,14 @@ def _deep_merge(base_dict: dict[str, Any], override_dict: dict[str, Any]) -> Non base_dict[key] = value +def _stamp_agent_version(helm_values: dict[str, Any], declared_env_names: set[str]) -> None: + """Set global.agent.version from the merged image tag unless the deployment declares AGENT_VERSION itself.""" + if EnvVarKeys.AGENT_VERSION.value in declared_env_names: + # Chart >=0.6.0 renders global.agent.version as a second AGENT_VERSION env entry. + return + helm_values["global"]["agent"].setdefault("version", helm_values["global"]["image"]["tag"]) + + def create_helm_values_file(helm_values: dict[str, Any]) -> str: """Create a temporary helm values file""" with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: diff --git a/tests/lib/cli/test_deploy_handlers.py b/tests/lib/cli/test_deploy_handlers.py new file mode 100644 index 000000000..835b56ae8 --- /dev/null +++ b/tests/lib/cli/test_deploy_handlers.py @@ -0,0 +1,64 @@ +"""Tests for the helm values merge_deployment_configs assembles for `agentex agents deploy`.""" + +from __future__ import annotations + +from typing import Any + +from agentex.config.agent_config import AgentConfig +from agentex.config.build_config import BuildConfig, BuildContext +from agentex.config.agent_manifest import AgentManifest +from agentex.config.deployment_config import ImageConfig, DeploymentConfig +from agentex.config.environment_config import AgentAuthConfig, AgentEnvironmentConfig +from agentex.lib.cli.handlers.deploy_handlers import InputDeployOverrides, merge_deployment_configs + +MANIFEST_TAG = "sha-manifest" + + +def _manifest(env: dict[str, str] | None = None) -> AgentManifest: + return AgentManifest( + build=BuildConfig(context=BuildContext(root=".", dockerfile="Dockerfile", dockerignore=None)), + agent=AgentConfig(name="emu-tax", description="Files emu taxes", acp_type="async", env=env), + deployment=DeploymentConfig(image=ImageConfig(repository="registry.example.com/emu-tax", tag=MANIFEST_TAG)), + ) + + +def _env_config(helm_overrides: dict[str, Any]) -> AgentEnvironmentConfig: + return AgentEnvironmentConfig(auth=AgentAuthConfig(principal={"user_id": "u-1"}), helm_overrides=helm_overrides) + + +def _merge( + manifest: AgentManifest, + env_config: AgentEnvironmentConfig | None = None, + image_tag: str | None = None, +) -> dict[str, Any]: + overrides = InputDeployOverrides(image_tag=image_tag) + return merge_deployment_configs(manifest, env_config, overrides, "/nonexistent/manifest.yaml") + + +class TestAgentVersion: + def test_stamped_from_the_deploy_image_tag(self): + values = _merge(_manifest(), image_tag="sha-cli") + + assert values["global"]["agent"]["version"] == "sha-cli" + + def test_follows_an_image_tag_overridden_in_helm_overrides(self): + values = _merge(_manifest(), _env_config({"global": {"image": {"tag": "sha-env"}}})) + + assert values["global"]["image"]["tag"] == "sha-env" + assert values["global"]["agent"]["version"] == "sha-env" + + def test_explicit_helm_override_of_the_version_wins(self): + values = _merge(_manifest(), _env_config({"global": {"agent": {"version": "pinned"}}})) + + assert values["global"]["agent"]["version"] == "pinned" + + def test_skipped_when_the_manifest_env_declares_agent_version(self): + values = _merge(_manifest(env={"AGENT_VERSION": "v1.2.3"})) + + assert "version" not in values["global"]["agent"] + assert {"name": "AGENT_VERSION", "value": "v1.2.3"} in values["env"] + + def test_skipped_when_the_environment_env_declares_agent_version(self): + values = _merge(_manifest(), _env_config({"env": [{"name": "AGENT_VERSION", "value": "v9"}]})) + + assert "version" not in values["global"]["agent"]