Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

feat(api): add support for the Draft notes API#2728

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
max-wittig merged 2 commits intomainfromfeat/draft-notes
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes fromall 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
1 change: 1 addition & 0 deletionsdocs/api-objects.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,7 @@ API examples
gl_objects/deploy_tokens
gl_objects/deployments
gl_objects/discussions
gl_objects/draft_notes
gl_objects/environments
gl_objects/events
gl_objects/epics
Expand Down
58 changes: 58 additions & 0 deletionsdocs/gl_objects/draft_notes.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
.. _draft-notes:

###########
Draft Notes
###########

Draft notes are pending, unpublished comments on merge requests.
They can be either start a discussion, or be associated with an existing discussion as a reply.
They are viewable only by the author until they are published.

Reference
---------

* v4 API:

+ :class:`gitlab.v4.objects.ProjectMergeRequestDraftNote`
+ :class:`gitlab.v4.objects.ProjectMergeRequestDraftNoteManager`
+ :attr:`gitlab.v4.objects.ProjectMergeRequest.draft_notes`


* GitLab API: https://docs.gitlab.com/ee/api/draft_notes.html

Examples
--------

List all draft notes for a merge request::

draft_notes = merge_request.draft_notes.list()

Get a draft note for a merge request by ID::

draft_note = merge_request.draft_notes.get(note_id)

.. warning::

When creating or updating draft notes, you can provide a complex nested ``position`` argument as a dictionary.
Please consult the upstream API documentation linked above for the exact up-to-date attributes.

Create a draft note for a merge request::

draft_note = merge_request.draft_notes.create({'note': 'note content'})

Update an existing draft note::

draft_note.note = 'updated note content'
draft_note.save()

Delete an existing draft note::

draft_note.delete()

Publish an existing draft note::

draft_note.publish()

Publish all existing draft notes for a merge request in bulk::

merge_request.draft_notes.bulk_publish()
2 changes: 2 additions & 0 deletionsgitlab/client.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1061,6 +1061,8 @@ def http_put(
raw=raw,
**kwargs,
)
if result.status_code in gitlab.const.NO_JSON_RESPONSE_CODES:
return result
try:
json_result = result.json()
if TYPE_CHECKING:
Expand Down
1 change: 1 addition & 0 deletionsgitlab/v4/objects/__init__.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,7 @@
from .deploy_tokens import *
from .deployments import *
from .discussions import *
from .draft_notes import *
from .environments import *
from .epics import *
from .events import *
Expand Down
43 changes: 43 additions & 0 deletionsgitlab/v4/objects/draft_notes.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
from typing import Any, cast, Union

from gitlab.base import RESTManager, RESTObject
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
from gitlab.types import RequiredOptional

__all__ = [
"ProjectMergeRequestDraftNote",
"ProjectMergeRequestDraftNoteManager",
]


class ProjectMergeRequestDraftNote(ObjectDeleteMixin, SaveMixin, RESTObject):
def publish(self, **kwargs: Any) -> None:
path = f"{self.manager.path}/{self.encoded_id}/publish"
self.manager.gitlab.http_put(path, **kwargs)


class ProjectMergeRequestDraftNoteManager(CRUDMixin, RESTManager):
_path = "/projects/{project_id}/merge_requests/{mr_iid}/draft_notes"
_obj_cls = ProjectMergeRequestDraftNote
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
_create_attrs = RequiredOptional(
required=("note",),
optional=(
"commit_id",
"in_reply_to_discussion_id",
"position",
"resolve_discussion",
),
)
_update_attrs = RequiredOptional(optional=("position",))

def get(
self, id: Union[str, int], lazy: bool = False, **kwargs: Any
) -> ProjectMergeRequestDraftNote:
return cast(
ProjectMergeRequestDraftNote, super().get(id=id, lazy=lazy, **kwargs)
)

def bulk_publish(self, **kwargs: Any) -> None:
path = f"{self.path}/bulk_publish"
self.gitlab.http_post(path, **kwargs)
2 changes: 2 additions & 0 deletionsgitlab/v4/objects/merge_requests.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,6 +28,7 @@
from .award_emojis import ProjectMergeRequestAwardEmojiManager # noqa: F401
from .commits import ProjectCommit, ProjectCommitManager
from .discussions import ProjectMergeRequestDiscussionManager # noqa: F401
from .draft_notes import ProjectMergeRequestDraftNoteManager
from .events import ( # noqa: F401
ProjectMergeRequestResourceLabelEventManager,
ProjectMergeRequestResourceMilestoneEventManager,
Expand DownExpand Up@@ -157,6 +158,7 @@ class ProjectMergeRequest(
awardemojis: ProjectMergeRequestAwardEmojiManager
diffs: "ProjectMergeRequestDiffManager"
discussions: ProjectMergeRequestDiscussionManager
draft_notes: ProjectMergeRequestDraftNoteManager
notes: ProjectMergeRequestNoteManager
pipelines: ProjectMergeRequestPipelineManager
resourcelabelevents: ProjectMergeRequestResourceLabelEventManager
Expand Down
175 changes: 175 additions & 0 deletionstests/unit/objects/test_draft_notes.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
"""
GitLab API: https://docs.gitlab.com/ee/api/draft_notes.html
"""
from copy import deepcopy

import pytest
import responses

from gitlab.v4.objects import ProjectMergeRequestDraftNote

draft_note_content = {
"id": 1,
"author_id": 23,
"merge_request_id": 1,
"resolve_discussion": False,
"discussion_id": None,
"note": "Example title",
"commit_id": None,
"line_code": None,
"position": {
"base_sha": None,
"start_sha": None,
"head_sha": None,
"old_path": None,
"new_path": None,
"position_type": "text",
"old_line": None,
"new_line": None,
"line_range": None,
},
}


@pytest.fixture()
def resp_list_merge_request_draft_notes():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/merge_requests/1/draft_notes",
json=[draft_note_content],
content_type="application/json",
status=200,
)
yield rsps


@pytest.fixture()
def resp_get_merge_request_draft_note():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/merge_requests/1/draft_notes/1",
json=draft_note_content,
content_type="application/json",
status=200,
)
yield rsps


@pytest.fixture()
def resp_create_merge_request_draft_note():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.POST,
url="http://localhost/api/v4/projects/1/merge_requests/1/draft_notes",
json=draft_note_content,
content_type="application/json",
status=201,
)
yield rsps


@pytest.fixture()
def resp_update_merge_request_draft_note():
updated_content = deepcopy(draft_note_content)
updated_content["note"] = "New title"

with responses.RequestsMock() as rsps:
rsps.add(
method=responses.PUT,
url="http://localhost/api/v4/projects/1/merge_requests/1/draft_notes/1",
json=updated_content,
content_type="application/json",
status=201,
)
yield rsps


@pytest.fixture()
def resp_delete_merge_request_draft_note():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.DELETE,
url="http://localhost/api/v4/projects/1/merge_requests/1/draft_notes/1",
json=draft_note_content,
content_type="application/json",
status=201,
)
yield rsps


@pytest.fixture()
def resp_publish_merge_request_draft_note():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.PUT,
url="http://localhost/api/v4/projects/1/merge_requests/1/draft_notes/1/publish",
status=204,
)
yield rsps


@pytest.fixture()
def resp_bulk_publish_merge_request_draft_notes():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.POST,
url="http://localhost/api/v4/projects/1/merge_requests/1/draft_notes/bulk_publish",
status=204,
)
yield rsps


def test_list_merge_requests_draft_notes(
project_merge_request, resp_list_merge_request_draft_notes
):
draft_notes = project_merge_request.draft_notes.list()
assert len(draft_notes) == 1
assert isinstance(draft_notes[0], ProjectMergeRequestDraftNote)
assert draft_notes[0].note == draft_note_content["note"]


def test_get_merge_requests_draft_note(
project_merge_request, resp_get_merge_request_draft_note
):
draft_note = project_merge_request.draft_notes.get(1)
assert isinstance(draft_note, ProjectMergeRequestDraftNote)
assert draft_note.note == draft_note_content["note"]


def test_create_merge_requests_draft_note(
project_merge_request, resp_create_merge_request_draft_note
):
draft_note = project_merge_request.draft_notes.create({"note": "Example title"})
assert isinstance(draft_note, ProjectMergeRequestDraftNote)
assert draft_note.note == draft_note_content["note"]


def test_update_merge_requests_draft_note(
project_merge_request, resp_update_merge_request_draft_note
):
draft_note = project_merge_request.draft_notes.get(1, lazy=True)
draft_note.note = "New title"
draft_note.save()
assert draft_note.note == "New title"


def test_delete_merge_requests_draft_note(
project_merge_request, resp_delete_merge_request_draft_note
):
draft_note = project_merge_request.draft_notes.get(1, lazy=True)
draft_note.delete()


def test_publish_merge_requests_draft_note(
project_merge_request, resp_publish_merge_request_draft_note
):
draft_note = project_merge_request.draft_notes.get(1, lazy=True)
draft_note.publish()


def test_bulk_publish_merge_requests_draft_notes(
project_merge_request, resp_bulk_publish_merge_request_draft_notes
):
project_merge_request.draft_notes.bulk_publish()
15 changes: 15 additions & 0 deletionstests/unit/test_gitlab_http_methods.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -766,6 +766,21 @@ def test_put_request_404(gl):
assert responses.assert_call_count(url, 1) is True


@responses.activate
def test_put_request_204(gl):
url = "http://localhost/api/v4/projects"
responses.add(
method=responses.PUT,
url=url,
status=204,
match=helpers.MATCH_EMPTY_QUERY_PARAMS,
)

result = gl.http_put("/projects")
assert isinstance(result, requests.Response)
assert responses.assert_call_count(url, 1) is True


@responses.activate
def test_put_request_invalid_data(gl):
url = "http://localhost/api/v4/projects"
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp