fix(cli): address deploy zip review feedback

This commit is contained in:
Joao Moura
2026-06-15 11:29:12 -07:00
parent b8c89a81f6
commit dbbdd77449
6 changed files with 122 additions and 9 deletions

View File

@@ -138,3 +138,24 @@ type = "crew"
assert "JsonCrew" in crew_py
assert "from json_crew.crew import JsonCrew" in main_py
assert "run_crew = \"json_crew.main:run\"" in pyproject
def test_create_project_zip_rejects_empty_normalized_package_name(tmp_path: Path):
(tmp_path / "pyproject.toml").write_text(
"""
[project]
name = "!!!"
version = "0.1.0"
[tool.crewai]
type = "crew"
""".strip()
+ "\n"
)
(tmp_path / "crew.jsonc").write_text("{}\n")
with pytest.raises(
ValueError,
match=r"Could not derive a valid Python package name",
):
create_project_zip("invalid", project_dir=tmp_path)

View File

@@ -440,6 +440,41 @@ class TestDeployCommand(unittest.TestCase):
)
self.mock_client.create_crew.assert_not_called()
@patch("crewai_cli.deploy.main.create_project_zip")
@patch("crewai_cli.deploy.main.fetch_and_json_env_file")
@patch("crewai_cli.deploy.main.git.Repository")
def test_create_crew_without_remote_uses_git_file_list_when_commit_fails(
self, mock_repository, mock_fetch_env, mock_create_project_zip
):
mock_fetch_env.return_value = {"ENV_VAR": "value"}
repository = mock_repository.return_value
repository.origin_url.return_value = None
repository.create_initial_commit_if_needed.side_effect = RuntimeError(
"commit failed"
)
mock_create_project_zip.return_value = Path("/tmp/test_project.zip")
mock_response = MagicMock()
mock_response.status_code = 201
mock_response.is_success = True
mock_response.json.return_value = {"uuid": "zip-uuid", "status": "created"}
self.mock_client.create_crew_from_zip.return_value = mock_response
with patch("sys.stdout", new=StringIO()) as fake_out:
self.deploy_command.create_crew(confirm=True, skip_validate=True)
output = fake_out.getvalue()
self.assertIn("Continuing with ZIP deployment using Git", output)
self.assertIn("file listing", output)
mock_create_project_zip.assert_called_once_with(
"test_project", repository=repository
)
self.mock_client.create_crew_from_zip.assert_called_once_with(
Path("/tmp/test_project.zip"),
name="test_project",
env={"ENV_VAR": "value"},
)
self.mock_client.create_crew.assert_not_called()
def test_list_crews(self):
mock_response = MagicMock()
mock_response.status_code = 200

View File

@@ -1,4 +1,5 @@
from pathlib import Path
import subprocess
import pytest
@@ -33,6 +34,28 @@ type = "crew"
install_crew_module.install_crew([])
def test_install_crew_json_project_with_python_package_installs_project(
fp, monkeypatch, tmp_path: Path
):
monkeypatch.chdir(tmp_path)
(tmp_path / "pyproject.toml").write_text(
"""
[project]
name = "hybrid-crew"
[tool.crewai]
type = "crew"
""".strip()
)
(tmp_path / "crew.jsonc").write_text("{}\n")
package_dir = tmp_path / "src" / "hybrid_crew"
package_dir.mkdir(parents=True)
(package_dir / "crew.py").write_text("class HybridCrew: ...\n")
fp.register(["uv", "sync"], stdout="")
install_crew_module.install_crew([])
def test_install_crew_flow_project_installs_project(fp, monkeypatch, tmp_path: Path):
monkeypatch.chdir(tmp_path)
(tmp_path / "pyproject.toml").write_text(
@@ -64,3 +87,16 @@ def test_install_crew_install_project_false_adds_no_install_project(fp):
fp.register(["uv", "sync", "--no-install-project", "--frozen"], stdout="")
install_crew_module.install_crew(["--frozen"], install_project=False)
def test_install_crew_reraises_sync_failure_when_requested(fp):
fp.register(["uv", "sync"], returncode=1, stderr="sync failed\n")
with pytest.raises(subprocess.CalledProcessError):
install_crew_module.install_crew([], raise_on_error=True)
def test_install_crew_swallows_sync_failure_by_default(fp):
fp.register(["uv", "sync"], returncode=1, stderr="sync failed\n")
install_crew_module.install_crew([])