diff --git a/src/together/lib/cli/api/beta/jig/jig.py b/src/together/lib/cli/api/beta/jig/jig.py index 11d3a951..2e9bd683 100644 --- a/src/together/lib/cli/api/beta/jig/jig.py +++ b/src/together/lib/cli/api/beta/jig/jig.py @@ -592,6 +592,11 @@ def delete_secret(self, name: str) -> None: # == Build / Push / Deploy / Track == def build(self, tag: str = "latest", warmup: bool = False, docker_args: str | None = None) -> None: + if self.config.deploy.image: + raise JigError( + f"Invalid command: deploy.image is set to '{self.config.deploy.image}'. " + "Use 'jig deploy' to deploy the configured image, or remove deploy.image to build from source." + ) image = self.image(tag) if not _dockerfile(self.config): diff --git a/tests/cli/test_beta_jig.py b/tests/cli/test_beta_jig.py index dd9bd3ae..fc443398 100644 --- a/tests/cli/test_beta_jig.py +++ b/tests/cli/test_beta_jig.py @@ -228,6 +228,28 @@ def test_unset_missing_secret_message(self, tmp_path: Path) -> None: assert "Secret nope is not set" in result.output +class TestBetaJigBuild: + def test_build_blocked_when_deploy_image_set(self, tmp_path: Path) -> None: + with patch.object(_jig_mod.Config, "__post_init__", _noop_config_post_init): + cfg = _jig_mod.Config( + model_name=_DEPLOY_NAME, + image=_jig_mod.ImageConfig(), + deploy=_jig_mod.DeployConfig(image="ghcr.io/org/prebuilt:latest"), + _path=tmp_path / "pyproject.toml", + _unique_name_hint="h", + ) + + def _find(*_args: Any): + return cfg + + with patch.object(_jig_mod.Config, "find", classmethod(_find)): + runner = CliRunner(env=_ENV) + with _chdir(tmp_path): + result = runner.invoke(main, ["beta", "jig", "build"]) + assert result.exit_code == 1 + assert "deploy.image is set" in result.output + + class TestBetaJigVolumes: @pytest.mark.respx(base_url=base_url) def test_delete(self, respx_mock: MockRouter, tmp_path: Path) -> None: