Skip to content

Commit 8703324

Browse files
nejchJohnVillalovos
authored andcommitted
feat(issues): add support for issue reorder API
1 parent 4882cb2 commit 8703324

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

docs/gl_objects/issues.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ Move an issue to another project::
153153

154154
issue.move(other_project_id)
155155

156+
Reorder an issue on a board::
157+
158+
issue.reorder(move_after_id=2, move_before_id=3)
159+
156160
Make an issue as todo::
157161

158162
issue.todo()

gitlab/v4/objects/issues.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, cast, Dict, Tuple, TYPE_CHECKING, Union
1+
from typing import Any, cast, Dict, Optional, Tuple, TYPE_CHECKING, Union
22

33
from gitlab import cli
44
from gitlab import exceptions as exc
@@ -140,6 +140,38 @@ def move(self, to_project_id: int, **kwargs: Any) -> None:
140140
assert isinstance(server_data, dict)
141141
self._update_attrs(server_data)
142142

143+
@cli.register_custom_action("ProjectIssue", ("move_after_id", "move_before_id"))
144+
@exc.on_http_error(exc.GitlabUpdateError)
145+
def reorder(
146+
self,
147+
move_after_id: Optional[int] = None,
148+
move_before_id: Optional[int] = None,
149+
**kwargs: Any,
150+
) -> None:
151+
"""Reorder an issue on a board.
152+
153+
Args:
154+
move_after_id: ID of an issue that should be placed after this issue
155+
move_before_id: ID of an issue that should be placed before this issue
156+
**kwargs: Extra options to send to the server (e.g. sudo)
157+
158+
Raises:
159+
GitlabAuthenticationError: If authentication is not correct
160+
GitlabUpdateError: If the issue could not be reordered
161+
"""
162+
path = f"{self.manager.path}/{self.encoded_id}/reorder"
163+
data: Dict[str, Any] = {}
164+
165+
if move_after_id is not None:
166+
data["move_after_id"] = move_after_id
167+
if move_before_id is not None:
168+
data["move_before_id"] = move_before_id
169+
170+
server_data = self.manager.gitlab.http_put(path, post_data=data, **kwargs)
171+
if TYPE_CHECKING:
172+
assert isinstance(server_data, dict)
173+
self._update_attrs(server_data)
174+
143175
@cli.register_custom_action("ProjectIssue")
144176
@exc.on_http_error(exc.GitlabGetError)
145177
def related_merge_requests(self, **kwargs: Any) -> Dict[str, Any]:

tests/unit/objects/test_issues.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,21 @@ def resp_get_issue():
4141
yield rsps
4242

4343

44+
@pytest.fixture
45+
def resp_reorder_issue():
46+
match_params = {"move_after_id": 2, "move_before_id": 3}
47+
with responses.RequestsMock() as rsps:
48+
rsps.add(
49+
method=responses.PUT,
50+
url="http://localhost/api/v4/projects/1/issues/1/reorder",
51+
json={"name": "name", "id": 1},
52+
content_type="application/json",
53+
status=200,
54+
match=[responses.matchers.json_params_matcher(match_params)],
55+
)
56+
yield rsps
57+
58+
4459
@pytest.fixture
4560
def resp_issue_statistics():
4661
content = {"statistics": {"counts": {"all": 20, "closed": 5, "opened": 15}}}
@@ -70,6 +85,11 @@ def test_get_issue(gl, resp_get_issue):
7085
assert issue.name == "name"
7186

7287

88+
def test_reorder_issue(project, resp_reorder_issue):
89+
issue = project.issues.get(1, lazy=True)
90+
issue.reorder(move_after_id=2, move_before_id=3)
91+
92+
7393
def test_get_issues_statistics(gl, resp_issue_statistics):
7494
statistics = gl.issues_statistics.get()
7595
assert isinstance(statistics, IssuesStatistics)

0 commit comments

Comments
 (0)