Skip to content

Commit a90f622

Browse files
max-parke-scalestainless-app[bot]claude
authored
feat(cli): stamp global.agent.version from the image tag on helm deploys (#504)
Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 687ebfb commit a90f622

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

‎src/agentex/lib/cli/handlers/deploy_handlers.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ def merge_deployment_configs(
389389
_deep_merge(helm_values, agent_env_config.helm_overrides)
390390
logger.info(f"After-merge helm values: {helm_values}")
391391

392+
_stamp_agent_version(helm_values, set(all_env_vars) | {var["name"] for var in secret_env_vars})
393+
392394
# Set final environment variables
393395
# Environment variable precedence: manifest -> environments.yaml -> secrets (highest)
394396
if all_env_vars:
@@ -430,6 +432,14 @@ def _deep_merge(base_dict: dict[str, Any], override_dict: dict[str, Any]) -> Non
430432
base_dict[key] = value
431433

432434

435+
def _stamp_agent_version(helm_values: dict[str, Any], declared_env_names: set[str]) -> None:
436+
"""Set global.agent.version from the merged image tag unless the deployment declares AGENT_VERSION itself."""
437+
if EnvVarKeys.AGENT_VERSION.value in declared_env_names:
438+
# Chart >=0.6.0 renders global.agent.version as a second AGENT_VERSION env entry.
439+
return
440+
helm_values["global"]["agent"].setdefault("version", helm_values["global"]["image"]["tag"])
441+
442+
433443
def create_helm_values_file(helm_values: dict[str, Any]) -> str:
434444
"""Create a temporary helm values file"""
435445
with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""Tests for the helm values merge_deployment_configs assembles for `agentex agents deploy`."""
2+
3+
from __future__ import annotations
4+
5+
from typing import Any
6+
7+
from agentex.config.agent_config import AgentConfig
8+
from agentex.config.build_config import BuildConfig, BuildContext
9+
from agentex.config.agent_manifest import AgentManifest
10+
from agentex.config.deployment_config import ImageConfig, DeploymentConfig
11+
from agentex.config.environment_config import AgentAuthConfig, AgentEnvironmentConfig
12+
from agentex.lib.cli.handlers.deploy_handlers import InputDeployOverrides, merge_deployment_configs
13+
14+
MANIFEST_TAG = "sha-manifest"
15+
16+
17+
def _manifest(env: dict[str, str] | None = None) -> AgentManifest:
18+
return AgentManifest(
19+
build=BuildConfig(context=BuildContext(root=".", dockerfile="Dockerfile", dockerignore=None)),
20+
agent=AgentConfig(name="emu-tax", description="Files emu taxes", acp_type="async", env=env),
21+
deployment=DeploymentConfig(image=ImageConfig(repository="registry.example.com/emu-tax", tag=MANIFEST_TAG)),
22+
)
23+
24+
25+
def _env_config(helm_overrides: dict[str, Any]) -> AgentEnvironmentConfig:
26+
return AgentEnvironmentConfig(auth=AgentAuthConfig(principal={"user_id": "u-1"}), helm_overrides=helm_overrides)
27+
28+
29+
def _merge(
30+
manifest: AgentManifest,
31+
env_config: AgentEnvironmentConfig | None = None,
32+
image_tag: str | None = None,
33+
) -> dict[str, Any]:
34+
overrides = InputDeployOverrides(image_tag=image_tag)
35+
return merge_deployment_configs(manifest, env_config, overrides, "/nonexistent/manifest.yaml")
36+
37+
38+
class TestAgentVersion:
39+
def test_stamped_from_the_deploy_image_tag(self):
40+
values = _merge(_manifest(), image_tag="sha-cli")
41+
42+
assert values["global"]["agent"]["version"] == "sha-cli"
43+
44+
def test_follows_an_image_tag_overridden_in_helm_overrides(self):
45+
values = _merge(_manifest(), _env_config({"global": {"image": {"tag": "sha-env"}}}))
46+
47+
assert values["global"]["image"]["tag"] == "sha-env"
48+
assert values["global"]["agent"]["version"] == "sha-env"
49+
50+
def test_explicit_helm_override_of_the_version_wins(self):
51+
values = _merge(_manifest(), _env_config({"global": {"agent": {"version": "pinned"}}}))
52+
53+
assert values["global"]["agent"]["version"] == "pinned"
54+
55+
def test_skipped_when_the_manifest_env_declares_agent_version(self):
56+
values = _merge(_manifest(env={"AGENT_VERSION": "v1.2.3"}))
57+
58+
assert "version" not in values["global"]["agent"]
59+
assert {"name": "AGENT_VERSION", "value": "v1.2.3"} in values["env"]
60+
61+
def test_skipped_when_the_environment_env_declares_agent_version(self):
62+
values = _merge(_manifest(), _env_config({"env": [{"name": "AGENT_VERSION", "value": "v9"}]}))
63+
64+
assert "version" not in values["global"]["agent"]

0 commit comments

Comments
 (0)