diff --git a/preswald/deploy.py b/preswald/deploy.py index 40ca2c95..cf1322a8 100644 --- a/preswald/deploy.py +++ b/preswald/deploy.py @@ -29,6 +29,12 @@ def get_deploy_dir(script_path: str) -> Path: return deploy_dir +# Google Cloud Run rejects service names of 50 characters or more +# (`CreateServiceRequest.service_id`), so the generated container name must +# stay under that limit even after the "preswald-app-" prefix is added. +GCP_SERVICE_NAME_MAX_LENGTH = 49 + + def get_container_name(script_path: str) -> str: """Generate a consistent container name for a given script""" script_dir = Path(script_path).parent @@ -39,6 +45,7 @@ def get_container_name(script_path: str) -> str: container_name = container_name.lower() container_name = re.sub(r"[^a-z0-9-]", "", container_name) container_name = container_name.strip("-") + container_name = container_name[:GCP_SERVICE_NAME_MAX_LENGTH].rstrip("-") return container_name diff --git a/tests/test_deploy.py b/tests/test_deploy.py new file mode 100644 index 00000000..aabe4b6e --- /dev/null +++ b/tests/test_deploy.py @@ -0,0 +1,41 @@ +import tempfile +from pathlib import Path + +import pytest + +from preswald.deploy import GCP_SERVICE_NAME_MAX_LENGTH, get_container_name + + +def _write_toml_project(tmp_path: Path, slug: str) -> Path: + script_path = tmp_path / "hello.py" + script_path.write_text("") + (tmp_path / "preswald.toml").write_text( + f'[project]\nslug = "{slug}"\nport = 8501\n' + ) + return script_path + + +def test_get_container_name_stays_under_gcp_limit(): + # A long-but-valid project slug used to produce a container name past + # Cloud Run's <50 char service_id limit once the "preswald-app-" prefix + # was added, causing `CreateServiceRequest.service_id` violations (#659). + long_slug = "a-very-descriptive-project-slug-for-an-org-1744321134" + with tempfile.TemporaryDirectory() as tmp: + script_path = _write_toml_project(Path(tmp), long_slug) + container_name = get_container_name(str(script_path)) + + assert len(container_name) <= GCP_SERVICE_NAME_MAX_LENGTH + assert not container_name.endswith("-") + assert container_name.startswith("preswald-app-") + + +def test_get_container_name_short_slug_unaffected(): + with tempfile.TemporaryDirectory() as tmp: + script_path = _write_toml_project(Path(tmp), "zwbq") + container_name = get_container_name(str(script_path)) + + assert container_name == "preswald-app-zwbq" + + +if __name__ == "__main__": + raise SystemExit(pytest.main([__file__, "-v"]))