Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Projects] Fix second create_remote not overriding current remote #5245

Merged
merged 7 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 40 additions & 0 deletions mlrun/projects/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import nuclio
import requests
import yaml
from deprecated import deprecated

import mlrun.common.helpers
import mlrun.common.schemas.model_monitoring
Expand Down Expand Up @@ -2332,6 +2333,12 @@ def pull(
elif url and url.endswith(".zip"):
clone_zip(url, self.spec.context, self._secrets)

# TODO: remove in 1.9.0
@deprecated(
version="1.7.0",
reason="'create_remote' will be removed in version 1.9.0. Use 'set_remote' instead.",
category=FutureWarning,
)
def create_remote(self, url, name="origin", branch=None):
"""create remote for the project git

Expand All @@ -2352,6 +2359,39 @@ def create_remote(self, url, name="origin", branch=None):
self.spec._source = self.spec.source or url
self.spec.origin_url = self.spec.origin_url or url

def set_remote(self, url, name="origin", branch=None, overwrite=False):
"""create or update a remote for the project git repository.

This method allows you to manage remote repositories associated with the project.
It checks if a remote with the specified name already exists. If it does, you have
the option to overwrite it with a new URL or keep the existing remote.
If a remote with the same name does not exist, it will be created.

:param url: remote git url
:param name: name for the remote (default is 'origin')
:param branch: Git branch to use as source
:param overwrite: if `overwrite` is True, and a remote with the given name already exists,
it will update the existing remote with the given url.
If set to False (default),
raise an error when attempting to create a remote with a name that already exists
:raises MLRunConflictError: If a remote with the same name already exists and overwrite
is set to False.
"""
if self._remote_exists(name):
if overwrite:
self.spec.repo.delete_remote(name)
else:
raise mlrun.errors.MLRunConflictError(
f"Remote '{name}' already exists in the project, "
f"Each remote in the project must have a unique name."
yaelgen marked this conversation as resolved.
Show resolved Hide resolved
"Use overwrite=True to override the remote, or choose a different name."
)
self.create_remote(url=url, name=name, branch=branch)

def _remote_exists(self, name):
"""check if a remote with the given name already exists"""
return any(remote.name == name for remote in self.spec.repo.remotes)

def _ensure_git_repo(self):
if self.spec.repo:
return
Expand Down
59 changes: 59 additions & 0 deletions tests/projects/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -1562,6 +1562,65 @@ def test_project_create_remote():
assert "mlrun-remote" in [remote.name for remote in project.spec.repo.remotes]


@pytest.mark.parametrize(
"url,set_url,name,set_name,overwrite,expected_url,expected",
[
# Remote doesn't exist, create normally
(
"https://github.com/mlrun/some-git-repo.git",
"https://github.com/mlrun/some-other-git-repo.git",
"mlrun-remote",
"mlrun-another-remote",
False,
"https://github.com/mlrun/some-other-git-repo.git",
does_not_raise(),
),
# Remote exists, overwrite False, raise MLRunConflictError
(
"https://github.com/mlrun/some-git-repo.git",
"https://github.com/mlrun/some-git-other-repo.git",
"mlrun-remote",
"mlrun-remote",
False,
"https://github.com/mlrun/some-git-repo.git",
pytest.raises(mlrun.errors.MLRunConflictError),
),
# Remote exists, overwrite True, update remote
(
"https://github.com/mlrun/some-git-repo.git",
"https://github.com/mlrun/some-git-other-repo.git",
"mlrun-remote",
"mlrun-remote",
True,
"https://github.com/mlrun/some-git-other-repo.git",
does_not_raise(),
),
],
)
def test_set_remote_as_update(
url, set_url, name, set_name, overwrite, expected_url, expected
):
with tempfile.TemporaryDirectory() as tmp_dir:
# create a project
project_name = "project-name"
project = mlrun.get_or_create_project(project_name, context=tmp_dir)

project.create_remote(
url=url,
name=name,
)
with expected:
project.set_remote(
url=set_url,
name=set_name,
overwrite=overwrite,
)

if name != set_name:
assert project.spec.repo.remote(name).url == url
assert project.spec.repo.remote(set_name).url == expected_url


@pytest.mark.parametrize(
"source_url, pull_at_runtime, base_image, image_name, target_dir",
[
Expand Down