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

fix(service): fix working on branches in the core-svc #3472

Merged
merged 5 commits into from May 26, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions renku/ui/service/cache/models/job.py
Expand Up @@ -43,6 +43,7 @@ class Job(Model):
state = TextField()
extras = JSONField()
client_extras = TextField()
branch = TextField()

ctrl_context = JSONField()
ctrl_result = JSONField()
Expand Down
22 changes: 11 additions & 11 deletions renku/ui/service/controllers/api/mixins.py
Expand Up @@ -169,8 +169,8 @@ def execute_op(self):
"git_url": self.request_data["git_url"],
}

if "ref" in self.request_data:
clone_context["ref"] = self.request_data["ref"]
if "branch" in self.request_data:
clone_context["branch"] = self.request_data["branch"]

# NOTE: If we want to migrate project, then we need to do full clone.
# This operation can take very long time, and as such is expected
Expand All @@ -185,27 +185,27 @@ def execute_op(self):
if not project.initialized:
raise UninitializedProject(project.abs_path)
else:
ref = self.request_data.get("ref", None)
branch = self.request_data.get("branch", None)

if ref:
if branch:
with Repository(project.abs_path) as repository:
if ref != repository.active_branch.name:
if branch != repository.active_branch.name:
# NOTE: Command called for different branch than the one used in cache, change branch
if len(repository.remotes) != 1:
raise RenkuException("Couldn't find remote for project in cache.")
origin = repository.remotes[0]
remote_branch = f"{origin}/{ref}"
remote_branch = f"{origin}/{branch}"

with project.write_lock():
# NOTE: Add new ref to remote branches
repository.run_git_command("remote", "set-branches", "--add", origin, ref)
# NOTE: Add new branch to remote branches
repository.run_git_command("remote", "set-branches", "--add", origin, branch)
if self.migrate_project or self.clone_depth == PROJECT_CLONE_NO_DEPTH:
repository.fetch(origin, ref)
repository.fetch(origin, branch)
else:
repository.fetch(origin, ref, depth=self.clone_depth)
repository.fetch(origin, branch, depth=self.clone_depth)

# NOTE: Switch to new ref
repository.run_git_command("checkout", "--track", "-f", "-b", ref, remote_branch)
repository.run_git_command("checkout", "--track", "-f", "-b", branch, remote_branch)

# NOTE: cleanup remote branches in case a remote was deleted (fetch fails otherwise)
repository.run_git_command("remote", "prune", origin)
Expand Down
2 changes: 1 addition & 1 deletion renku/ui/service/controllers/cache_migrations_check.py
Expand Up @@ -66,7 +66,7 @@ def _fast_op_without_cache(self):
],
tempdir_path,
remote=self.ctx["git_url"],
ref=self.request_data.get("ref", None),
branch=self.request_data.get("branch", None),
token=self.user_data.get("token", None),
)
with renku_project_context(tempdir_path):
Expand Down
4 changes: 2 additions & 2 deletions renku/ui/service/controllers/templates_create_project.py
Expand Up @@ -65,7 +65,7 @@ def default_metadata(self):

metadata = {
"__template_source__": self.ctx["git_url"],
"__template_ref__": self.ctx["ref"],
"__template_ref__": self.ctx["branch"],
"__template_id__": self.ctx["identifier"],
"__namespace__": self.ctx["project_namespace"],
"__repository__": self.ctx["project_repository"],
Expand Down Expand Up @@ -115,7 +115,7 @@ def setup_new_project(self):

def setup_template(self):
"""Reads template manifest."""
templates_source = fetch_templates_source(source=self.ctx["git_url"], reference=self.ctx["ref"])
templates_source = fetch_templates_source(source=self.ctx["git_url"], reference=self.ctx["branch"])
identifier = self.ctx["identifier"]
try:
self.template = templates_source.get_template(id=identifier, reference=None)
Expand Down
2 changes: 1 addition & 1 deletion renku/ui/service/controllers/templates_read_manifest.py
Expand Up @@ -50,7 +50,7 @@ def template_manifest(self):
"""Reads template manifest."""
from PIL import Image

templates_source = fetch_templates_source(source=self.ctx["git_url"], reference=self.ctx["ref"])
templates_source = fetch_templates_source(source=self.ctx["git_url"], reference=self.ctx["branch"])
manifest = templates_source.manifest.get_raw_content()

# NOTE: convert icons to base64
Expand Down
2 changes: 1 addition & 1 deletion renku/ui/service/controllers/utils/project_clone.py
Expand Up @@ -73,7 +73,7 @@ def user_project_clone(cache, user_data, project_data):
"user.email": project_data["email"],
"pull.rebase": False,
},
checkout_revision=project_data["ref"],
checkout_revision=project_data["branch"],
)
).output
project.save()
Expand Down
2 changes: 1 addition & 1 deletion renku/ui/service/controllers/utils/remote_project.py
Expand Up @@ -45,7 +45,7 @@ def __init__(self, user_data, request_data):
self.ctx = ProjectCloneContext().load({**user_data, **request_data}, unknown=EXCLUDE)

self.git_url = self.ctx["url_with_auth"]
self.branch = self.ctx["ref"]
self.branch = self.ctx["branch"]

@property
def remote_url(self):
Expand Down
8 changes: 4 additions & 4 deletions renku/ui/service/gateways/gitlab_api_provider.py
Expand Up @@ -47,11 +47,11 @@ def download_files_from_api(
target_folder: Union[Path, str],
remote: str,
token: str,
ref: Optional[str] = None,
branch: Optional[str] = None,
):
"""Download files through a remote Git API."""
if not ref:
ref = "HEAD"
if not branch:
branch = "HEAD"

target_folder = Path(target_folder)

Expand Down Expand Up @@ -82,7 +82,7 @@ def download_files_from_api(

try:
with open(full_path, "wb") as f:
project.files.raw(file_path=str(path), ref=ref, streamed=True, action=f.write)
project.files.raw(file_path=str(path), ref=branch, streamed=True, action=f.write)

result_paths.append(full_path)
except gitlab.GitlabGetError:
Expand Down
2 changes: 1 addition & 1 deletion renku/ui/service/interfaces/git_api_provider.py
Expand Up @@ -30,7 +30,7 @@ def download_files_from_api(
target_folder: Union[Path, str],
remote: str,
token: str,
ref: Optional[str] = None,
branch: Optional[str] = None,
):
"""Download files through a remote Git API."""
raise NotImplementedError()
13 changes: 0 additions & 13 deletions renku/ui/service/serializers/cache.py
Expand Up @@ -131,7 +131,6 @@ class RepositoryCloneRequest(RemoteRepositorySchema):
"""Request schema for repository clone."""

depth = fields.Integer(metadata={"description": "Git fetch depth"}, load_default=PROJECT_CLONE_DEPTH_DEFAULT)
ref = fields.String(metadata={"description": "Repository reference (branch, commit or tag)"}, load_default=None)


class ProjectCloneContext(RepositoryCloneRequest):
Expand Down Expand Up @@ -240,18 +239,6 @@ class ProjectMigrateRequest(AsyncSchema, LocalRepositorySchema, RemoteRepository
skip_docker_update = fields.Boolean(dump_default=False)
skip_migrations = fields.Boolean(dump_default=False)

@pre_load()
def handle_ref(self, data, **kwargs):
"""Handle ref and branch."""

# Backward compatibility: branch and ref were both used. Let's keep branch as the exposed field
# even if interally it gets converted to "ref" later.
if data.get("ref"):
data["branch"] = data["ref"]
del data["ref"]

return data


class ProjectMigrateResponse(RenkuSyncSchema):
"""Response schema for project migrate."""
Expand Down
15 changes: 13 additions & 2 deletions renku/ui/service/serializers/common.py
Expand Up @@ -19,7 +19,7 @@
from datetime import datetime

import yagup
from marshmallow import Schema, fields, validates
from marshmallow import Schema, fields, pre_load, validates

from renku.ui.service.errors import UserRepoUrlInvalidError
from renku.ui.service.serializers.rpc import JsonRPCResponse
Expand Down Expand Up @@ -52,7 +52,18 @@ def validate_git_url(self, value):
class RemoteRepositorySchema(RemoteRepositoryBaseSchema):
"""Schema for tracking a remote repository and branch."""

branch = fields.String(metadata={"description": "Remote git branch."})
branch = fields.String(load_default=None, metadata={"description": "Remote git branch (or tag or commit SHA)."})

@pre_load
def set_branch_from_ref(self, data, **kwargs):
"""Set `branch` field from `ref` if present."""
if "ref" in data and not data.get("branch"):
# Backward compatibility: branch and ref were both used. Let's keep branch as the exposed field
# even if internally it gets converted to "ref" later.
data["branch"] = data["ref"]
del data["ref"]

return data


class AsyncSchema(Schema):
Expand Down
17 changes: 4 additions & 13 deletions renku/ui/service/serializers/datasets.py
Expand Up @@ -32,12 +32,6 @@
from renku.ui.service.serializers.rpc import JsonRPCResponse


class DatasetRefSchema(Schema):
"""Schema for specifying a reference."""

ref = fields.String(metadata={"description": "Target reference."})


class DatasetNameSchema(Schema):
"""Schema for dataset name."""

Expand All @@ -53,7 +47,7 @@ class DatasetDetailsRequest(DatasetDetails):


class DatasetCreateRequest(
AsyncSchema, DatasetDetailsRequest, DatasetRefSchema, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema
AsyncSchema, DatasetDetailsRequest, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema
):
"""Request schema for a dataset create view."""

Expand All @@ -75,7 +69,7 @@ class DatasetCreateResponseRPC(JsonRPCResponse):


class DatasetRemoveRequest(
AsyncSchema, DatasetNameSchema, DatasetRefSchema, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema
AsyncSchema, DatasetNameSchema, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema
):
"""Request schema for a dataset remove."""

Expand All @@ -99,9 +93,7 @@ class DatasetAddFile(Schema):
job_id = fields.String()


class DatasetAddRequest(
AsyncSchema, DatasetNameSchema, DatasetRefSchema, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema
):
class DatasetAddRequest(AsyncSchema, DatasetNameSchema, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema):
"""Request schema for a dataset add file view."""

files = fields.List(fields.Nested(DatasetAddFile), required=True)
Expand Down Expand Up @@ -203,7 +195,6 @@ class DatasetEditRequest(
AsyncSchema,
DatasetDetailsRequest,
DatasetNameSchema,
DatasetRefSchema,
LocalRepositorySchema,
RemoteRepositorySchema,
MigrateSchema,
Expand Down Expand Up @@ -240,7 +231,7 @@ class DatasetEditResponseRPC(JsonRPCResponse):


class DatasetUnlinkRequest(
AsyncSchema, DatasetNameSchema, DatasetRefSchema, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema
AsyncSchema, DatasetNameSchema, LocalRepositorySchema, RemoteRepositorySchema, MigrateSchema
):
"""Dataset unlink file request."""

Expand Down
1 change: 0 additions & 1 deletion renku/ui/service/serializers/templates.py
Expand Up @@ -32,7 +32,6 @@ class ManifestTemplatesRequest(RepositoryCloneRequest):
"""Request schema for listing manifest templates."""

url = fields.String(required=True)
ref = fields.String(load_default=None)
depth = fields.Integer(load_default=TEMPLATE_CLONE_DEPTH_DEFAULT)

@pre_load()
Expand Down
6 changes: 3 additions & 3 deletions tests/fixtures/templates.py
Expand Up @@ -59,7 +59,7 @@ def template(template_metadata):
"url": "https://github.com/SwissDataScienceCenter/renku-project-template",
"id": "python-minimal",
"index": 1,
"ref": "master",
"branch": "master",
# TODO: Add template parameters here once parameters are added to the template.
"metadata": {},
"default_metadata": template_metadata,
Expand All @@ -84,15 +84,15 @@ def project_init(template):
"init_custom": [
"init",
"--template-ref",
template["ref"],
template["branch"],
"--template-id",
"python-minimal",
data["test_project"],
],
"init_custom_template": (
"https://gitlab.dev.renku.ch/renku-python-integration-tests/core-it-template-variable-test-project"
),
"remote": ["--template-source", template["url"], "--template-ref", template["ref"]],
"remote": ["--template-source", template["url"], "--template-ref", template["branch"]],
"id": ["--template-id", template["id"]],
"force": ["--force"],
"parameters": ["--parameter", "p1=v1", "--parameter", "p2=v2"],
Expand Down
4 changes: 2 additions & 2 deletions tests/service/controllers/test_templates_create_project.py
Expand Up @@ -62,7 +62,7 @@ def test_template_create_project_ctrl(ctrl_init, svc_client_templates_creation,
"git_url",
"project_name_stripped",
"depth",
"ref",
"branch",
"new_project_url_with_auth",
"url_with_auth",
}
Expand All @@ -83,7 +83,7 @@ def test_template_create_project_ctrl(ctrl_init, svc_client_templates_creation,
expected_metadata.add("__renku_version__")
assert expected_metadata == set(received_metadata.keys())
assert payload["url"] == received_metadata["__template_source__"]
assert payload["ref"] == received_metadata["__template_ref__"]
assert payload["branch"] == received_metadata["__template_ref__"]
assert payload["identifier"] == received_metadata["__template_id__"]
assert payload["project_namespace"] == received_metadata["__namespace__"]
assert payload["project_repository"] == received_metadata["__repository__"]
Expand Down
6 changes: 3 additions & 3 deletions tests/service/controllers/utils/test_remote_project.py
Expand Up @@ -55,13 +55,13 @@ def test_project_metadata_custom_remote():

request_data = {
"git_url": "https://gitlab.dev.renku.ch/renku-python-integration-tests/import-me",
"ref": "my-branch",
"branch": "my-branch",
}

ctrl = RemoteProject(user_data, request_data)
ref = ctrl.ctx["ref"]
branch = ctrl.ctx["branch"]

assert request_data["ref"] == ref
assert request_data["branch"] == branch


def test_project_metadata_remote_err():
Expand Down