Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions src/mcp_agent/cli/cloud/commands/deploy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,7 @@ def deploy_config(
secrets_transformed_path = None
if secrets_file and not deployed_secrets_file:
print_info("Processing secrets file...")
secrets_transformed_path = Path(
f"{config_dir}/{MCP_DEPLOYED_SECRETS_FILENAME}"
)
secrets_transformed_path = config_dir / MCP_DEPLOYED_SECRETS_FILENAME

run_async(
process_config_secrets(
Expand Down
61 changes: 38 additions & 23 deletions src/mcp_agent/cli/cloud/commands/deploy/wrangler_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,28 @@ def wrangler_deploy(app_id: str, api_key: str, project_dir: Path) -> None:
# Copy existing env to avoid overwriting
env = os.environ.copy()

env.update(
{
"CLOUDFLARE_ACCOUNT_ID": CLOUDFLARE_ACCOUNT_ID,
"CLOUDFLARE_API_TOKEN": api_key,
"CLOUDFLARE_EMAIL": CLOUDFLARE_EMAIL,
"WRANGLER_AUTH_DOMAIN": deployment_settings.wrangler_auth_domain,
"WRANGLER_AUTH_URL": deployment_settings.wrangler_auth_url,
"WRANGLER_SEND_METRICS": str(WRANGLER_SEND_METRICS).lower(),
"CLOUDFLARE_API_BASE_URL": deployment_settings.cloudflare_api_base_url,
"HOME": os.path.expanduser(settings.DEPLOYMENT_CACHE_DIR),
"XDG_HOME_DIR": os.path.expanduser(settings.DEPLOYMENT_CACHE_DIR),
}
)
env_updates = {
"CLOUDFLARE_ACCOUNT_ID": CLOUDFLARE_ACCOUNT_ID,
"CLOUDFLARE_API_TOKEN": api_key,
"CLOUDFLARE_EMAIL": CLOUDFLARE_EMAIL,
"WRANGLER_AUTH_DOMAIN": deployment_settings.wrangler_auth_domain,
"WRANGLER_AUTH_URL": deployment_settings.wrangler_auth_url,
"WRANGLER_SEND_METRICS": str(WRANGLER_SEND_METRICS).lower(),
"CLOUDFLARE_API_BASE_URL": deployment_settings.cloudflare_api_base_url,
"HOME": os.path.expanduser(settings.DEPLOYMENT_CACHE_DIR),
"XDG_HOME_DIR": os.path.expanduser(settings.DEPLOYMENT_CACHE_DIR),
}

if os.name == "nt":
# On Windows, configure npm to use a safe prefix within our cache directory
# to avoid issues with missing global npm directories
npm_prefix = (
Path(os.path.expanduser(settings.DEPLOYMENT_CACHE_DIR)) / "npm-global"
)
npm_prefix.mkdir(parents=True, exist_ok=True)
env_updates["npm_config_prefix"] = str(npm_prefix)

env.update(env_updates)

validate_project(project_dir)

Expand Down Expand Up @@ -303,22 +312,28 @@ def ignore_patterns(_path, names):
task = progress.add_task("Bundling MCP Agent...", total=None)

try:
cmd = [
"npx",
"--yes",
"[email protected]",
"deploy",
main_py,
"--name",
app_id,
"--no-bundle",
]

subprocess.run(
[
"npx",
"--yes",
"[email protected]",
"deploy",
main_py,
"--name",
app_id,
"--no-bundle",
],
cmd,
check=True,
env=env,
cwd=str(temp_project_dir),
capture_output=True,
text=True,
# On Windows, we need to use shell=True for npx to work correctly
shell=(os.name == "nt"),
encoding="utf-8",
errors="replace",
)
progress.update(task, description="✅ Bundled successfully")
return
Expand Down
6 changes: 3 additions & 3 deletions tests/cli/commands/test_deploy_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,9 +452,9 @@ def test_deploy_with_secrets_file():
# Verify secrets file is unchanged
with open(secrets_path, "r", encoding="utf-8") as f:
content = f.read()
assert (
content == secrets_content
), "Output file content should match original secrets"
assert content == secrets_content, (
"Output file content should match original secrets"
)

# Verify the function deployed the correct mock app
assert result == MOCK_APP_ID
132 changes: 66 additions & 66 deletions tests/cli/commands/test_wrangler_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -470,9 +470,9 @@ def check_files_during_subprocess(*args, **kwargs):
# Temp directory should have .mcpac.py versions
assert temp_mcpac_file.exists(), f"Temp {file_path}.mcpac.py should exist"
# Original files in temp should be renamed away
assert (
not temp_original_file.exists()
), f"Temp {file_path} should be renamed"
assert not temp_original_file.exists(), (
f"Temp {file_path} should be renamed"
)

return MagicMock(returncode=0)

Expand Down Expand Up @@ -544,9 +544,9 @@ def test_wrangler_deploy_venv_exclusion(complex_project_structure):
def check_venv_during_subprocess(*args, **kwargs):
temp_project_dir = Path(kwargs["cwd"])
# During subprocess execution, .venv should not exist in temp directory
assert not (
temp_project_dir / ".venv"
).exists(), ".venv should not be copied to temp dir"
assert not (temp_project_dir / ".venv").exists(), (
".venv should not be copied to temp dir"
)
# Original .venv should still exist and be untouched
assert venv_dir.exists(), "Original .venv should still exist"
return MagicMock(returncode=0)
Expand All @@ -569,12 +569,12 @@ def check_nested_files_during_subprocess(*args, **kwargs):
deep_mcpac = temp_project_dir / "nested/deep/deep_file.txt.mcpac.py"

# During subprocess execution, .mcpac.py files should exist in temp nested directories
assert (
nested_mcpac.exists()
), "Nested .mcpac.py file should exist during subprocess"
assert (
deep_mcpac.exists()
), "Deep nested .mcpac.py file should exist during subprocess"
assert nested_mcpac.exists(), (
"Nested .mcpac.py file should exist during subprocess"
)
assert deep_mcpac.exists(), (
"Deep nested .mcpac.py file should exist during subprocess"
)

# Check that the nested directory structure is preserved in temp directory
assert nested_mcpac.parent == temp_project_dir / "nested"
Expand Down Expand Up @@ -650,17 +650,17 @@ def check_complex_extensions_during_subprocess(*args, **kwargs):
original_temp_file = temp_project_dir / filename
original_project_file = project_path / filename

assert (
mcpac_file.exists()
), f"Temp {filename}.mcpac.py should exist during subprocess"
assert mcpac_file.exists(), (
f"Temp {filename}.mcpac.py should exist during subprocess"
)
# Original should not exist in temp directory (renamed to .mcpac.py)
assert (
not original_temp_file.exists()
), f"Temp {filename} should be renamed during subprocess"
assert not original_temp_file.exists(), (
f"Temp {filename} should be renamed during subprocess"
)
# Original project file should be unchanged
assert (
original_project_file.exists()
), f"Original {filename} should be unchanged"
assert original_project_file.exists(), (
f"Original {filename} should be unchanged"
)

return MagicMock(returncode=0)

Expand All @@ -674,15 +674,15 @@ def check_complex_extensions_during_subprocess(*args, **kwargs):
original_file = project_path / filename
mcpac_file = project_path / f"{filename}.mcpac.py"

assert (
original_file.exists()
), f"Original {filename} should be unchanged"
assert (
original_file.read_text() == expected_content
), f"{filename} content should be preserved"
assert (
not mcpac_file.exists()
), f"No {filename}.mcpac.py should exist in original directory"
assert original_file.exists(), (
f"Original {filename} should be unchanged"
)
assert original_file.read_text() == expected_content, (
f"{filename} content should be preserved"
)
assert not mcpac_file.exists(), (
f"No {filename}.mcpac.py should exist in original directory"
)


# Requirements.txt processing tests
Expand Down Expand Up @@ -725,9 +725,9 @@ def test_needs_requirements_modification_with_relative_imports():
{relative_import}
numpy==1.24.0"""
requirements_path.write_text(requirements_content)
assert _needs_requirements_modification(
requirements_path
), f"Should detect relative import: {relative_import}"
assert _needs_requirements_modification(requirements_path), (
f"Should detect relative import: {relative_import}"
)


def test_needs_requirements_modification_mixed_content():
Expand Down Expand Up @@ -843,9 +843,9 @@ def check_requirements_during_subprocess(*args, **kwargs):
assert "mcp-agent\n" in deployed_content

# Original project requirements.txt should be unchanged
assert (
requirements_path.exists()
), "Original requirements.txt should be unchanged"
assert requirements_path.exists(), (
"Original requirements.txt should be unchanged"
)
assert requirements_path.read_text() == original_content

return MagicMock(returncode=0)
Expand Down Expand Up @@ -873,17 +873,17 @@ def check_requirements_during_subprocess(*args, **kwargs):

# In temp directory, requirements.txt should be renamed to .mcpac.py
assert temp_mcpac_path.exists(), "Temp requirements.txt.mcpac.py should exist"
assert (
not temp_requirements_path.exists()
), "Temp requirements.txt should be renamed"
assert not temp_requirements_path.exists(), (
"Temp requirements.txt should be renamed"
)

# Content should be preserved in .mcpac.py version
assert temp_mcpac_path.read_text() == original_content

# Original project requirements.txt should be unchanged
assert (
requirements_path.exists()
), "Original requirements.txt should be unchanged"
assert requirements_path.exists(), (
"Original requirements.txt should be unchanged"
)
assert requirements_path.read_text() == original_content

return MagicMock(returncode=0)
Expand Down Expand Up @@ -950,37 +950,37 @@ def check_secrets_exclusion_during_subprocess(*args, **kwargs):
temp_project_dir = Path(kwargs["cwd"])

# Secrets file should NOT exist in temp directory at all
assert not (
temp_project_dir / MCP_SECRETS_FILENAME
).exists(), "Secrets file should be excluded from temp directory"
assert not (temp_project_dir / MCP_SECRETS_FILENAME).exists(), (
"Secrets file should be excluded from temp directory"
)
assert not (
temp_project_dir / f"{MCP_SECRETS_FILENAME}.mcpac.py"
).exists(), "Secrets file should not be processed as .mcpac.py"

# Other YAML files should be processed normally
assert (
temp_project_dir / "config.yaml.mcpac.py"
).exists(), "Other YAML files should be processed as .mcpac.py"
assert (
temp_project_dir / "mcp_agent.config.yaml.mcpac.py"
).exists(), "mcp_agent.config.yaml should be processed as .mcpac.py"
assert (temp_project_dir / "config.yaml.mcpac.py").exists(), (
"Other YAML files should be processed as .mcpac.py"
)
assert (temp_project_dir / "mcp_agent.config.yaml.mcpac.py").exists(), (
"mcp_agent.config.yaml should be processed as .mcpac.py"
)
assert (
temp_project_dir / "mcp_agent.deployed.secrets.yaml.mcpac.py"
).exists(), (
"mcp_agent.deployed.secrets.yaml should be processed as .mcpac.py"
)
assert not (
temp_project_dir / "config.yaml"
).exists(), "Other YAML files should be renamed in temp directory"
assert not (temp_project_dir / "config.yaml").exists(), (
"Other YAML files should be renamed in temp directory"
)

# Original files should remain untouched
assert (
secrets_file.exists()
), "Original secrets file should remain untouched"
assert secrets_file.exists(), (
"Original secrets file should remain untouched"
)
assert config_file.exists(), "Original config file should remain untouched"
assert (
secrets_file.read_text() == secrets_content
), "Secrets file content should be unchanged"
assert secrets_file.read_text() == secrets_content, (
"Secrets file content should be unchanged"
)

return MagicMock(returncode=0)

Expand All @@ -991,12 +991,12 @@ def check_secrets_exclusion_during_subprocess(*args, **kwargs):

# After deployment, original files should be unchanged
assert secrets_file.exists(), "Secrets file should still exist"
assert (
secrets_file.read_text() == secrets_content
), "Secrets file content should be preserved"
assert secrets_file.read_text() == secrets_content, (
"Secrets file content should be preserved"
)
assert config_file.exists(), "Config file should still exist"

# No secrets-related mcpac.py files should exist in original directory
assert not (
project_path / f"{MCP_SECRETS_FILENAME}.mcpac.py"
).exists(), "No secrets .mcpac.py file should exist in original directory"
assert not (project_path / f"{MCP_SECRETS_FILENAME}.mcpac.py").exists(), (
"No secrets .mcpac.py file should exist in original directory"
)
Loading