Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions 4 gitlab/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ class GitlabTransferProjectError(GitlabOperationError):
pass


class GitlabGroupTransferError(GitlabOperationError):
pass


class GitlabProjectDeployKeyError(GitlabOperationError):
pass

Expand Down
24 changes: 23 additions & 1 deletion 24 gitlab/v4/objects/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,34 @@ def transfer_project(self, project_id: int, **kwargs: Any) -> None:
path = f"/groups/{self.id}/projects/{project_id}"
self.manager.gitlab.http_post(path, **kwargs)

@cli.register_custom_action("Group", tuple(), ("group_id",))
@exc.on_http_error(exc.GitlabGroupTransferError)
def transfer(self, group_id: Optional[int] = None, **kwargs: Any) -> None:
"""Transfer the group to a new parent group or make it a top-level group.

Requires GitLab ≥14.6.

Args:
group_id: ID of the new parent group. When not specified,
the group to transfer is instead turned into a top-level group.
**kwargs: Extra options to send to the server (e.g. sudo)

Raises:
GitlabAuthenticationError: If authentication is not correct
GitlabGroupTransferError: If the group could not be transferred
"""
path = f"/groups/{self.encoded_id}/transfer"
post_data = {}
if group_id is not None:
post_data["group_id"] = group_id
self.manager.gitlab.http_post(path, post_data=post_data, **kwargs)

@cli.register_custom_action("Group", ("scope", "search"))
@exc.on_http_error(exc.GitlabSearchError)
def search(
self, scope: str, search: str, **kwargs: Any
) -> Union[gitlab.GitlabList, List[Dict[str, Any]]]:
"""Search the group resources matching the provided string.'
"""Search the group resources matching the provided string.

Args:
scope: Scope of the search
Expand Down
14 changes: 8 additions & 6 deletions 14 tests/functional/api/test_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,19 @@ def test_group_hooks(group):
hook.delete()


@pytest.mark.skip(reason="Pending #1807")
def test_group_transfer(gl, group):
transfer_group = gl.groups.create({"name": "transfer-test-group"})
assert group.namespace["path"] != group.full_path
transfer_group = gl.groups.create(
{"name": "transfer-test-group", "path": "transfer-test-group"}
)
transfer_group = gl.groups.get(transfer_group.id)
assert transfer_group.parent_id != group.id

transfer_group.transfer(group.id)

transferred_group = gl.projects.get(transfer_group.id)
assert transferred_group.namespace["path"] == group.full_path
transferred_group = gl.groups.get(transfer_group.id)
assert transferred_group.parent_id == group.id

transfer_group.transfer()

transferred_group = gl.projects.get(transfer_group.id)
transferred_group = gl.groups.get(transfer_group.id)
assert transferred_group.path == transferred_group.full_path
2 changes: 1 addition & 1 deletion 2 tests/functional/fixtures/.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
GITLAB_IMAGE=gitlab/gitlab-ce
GITLAB_TAG=14.5.2-ce.0
GITLAB_TAG=14.6.2-ce.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sneaky... 😁

5 changes: 2 additions & 3 deletions 5 tests/unit/objects/test_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ def resp_create_import(accepted_content):
def resp_transfer_group():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.PUT,
method=responses.POST,
url="http://localhost/api/v4/groups/1/transfer",
json=content,
content_type="application/json",
status=200,
match=[
responses.matchers.json_params_matcher({"namespace": "test-namespace"})
responses.matchers.json_params_matcher({"group_id": "test-namespace"})
],
)
yield rsps
Expand Down Expand Up @@ -170,7 +170,6 @@ def test_refresh_group_import_status(group, resp_groups):
assert group_import.import_status == "finished"


@pytest.mark.skip("Pending #1807")
def test_transfer_group(gl, resp_transfer_group):
group = gl.groups.get(1, lazy=True)
group.transfer("test-namespace")
Morty Proxy This is a proxified and sanitized view of the page, visit original site.