summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNejc Habjan <hab.nejc@gmail.com>2021-06-26 22:32:41 +0200
committerGitHub <noreply@github.com>2021-06-26 22:32:41 +0200
commit33d342818599f403434e7024097449b6f21babc0 (patch)
treeb72e149f518bbf1feb5d75d4d64eee27c9a6cc40
parent2c86003b36b443203c881dbcefb0ae3908ea1e34 (diff)
parent13bf61d07e84cd719931234c3ccbb9977c8f6416 (diff)
downloadgitlab-33d342818599f403434e7024097449b6f21babc0.tar.gz
Merge pull request #1522 from PPaques/1521-releases-edit
Support Release Update API
-rw-r--r--docs/gl_objects/projects.rst4
-rw-r--r--docs/gl_objects/releases.rst6
-rw-r--r--gitlab/v4/objects/releases.py9
-rw-r--r--tests/functional/api/test_releases.py9
-rw-r--r--tests/unit/objects/test_releases.py39
5 files changed, 60 insertions, 7 deletions
diff --git a/docs/gl_objects/projects.rst b/docs/gl_objects/projects.rst
index 7935bf9..77b32ba 100644
--- a/docs/gl_objects/projects.rst
+++ b/docs/gl_objects/projects.rst
@@ -412,10 +412,6 @@ Create a tag::
tag = project.tags.create({'tag_name': '1.0', 'ref': 'master'})
-Set or update the release note for a tag::
-
- tag.set_release_description('awesome v1.0 release')
-
Delete a tag::
project.tags.delete('1.0')
diff --git a/docs/gl_objects/releases.rst b/docs/gl_objects/releases.rst
index 3813857..6077fe9 100644
--- a/docs/gl_objects/releases.rst
+++ b/docs/gl_objects/releases.rst
@@ -27,6 +27,12 @@ Get a single release::
release = project.releases.get('v1.2.3')
+Edit a release::
+
+ release.name = "Demo Release"
+ release.description = "release notes go here"
+ release.save()
+
Create a release for a project tag::
release = project.releases.create({'name':'Demo Release', 'tag_name':'v1.2.3', 'description':'release notes go here'})
diff --git a/gitlab/v4/objects/releases.py b/gitlab/v4/objects/releases.py
index ab490dd..6216e45 100644
--- a/gitlab/v4/objects/releases.py
+++ b/gitlab/v4/objects/releases.py
@@ -1,5 +1,5 @@
from gitlab.base import RequiredOptional, RESTManager, RESTObject
-from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin
+from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
__all__ = [
"ProjectRelease",
@@ -9,18 +9,21 @@ __all__ = [
]
-class ProjectRelease(RESTObject):
+class ProjectRelease(SaveMixin, RESTObject):
_id_attr = "tag_name"
_managers = (("links", "ProjectReleaseLinkManager"),)
-class ProjectReleaseManager(NoUpdateMixin, RESTManager):
+class ProjectReleaseManager(CRUDMixin, RESTManager):
_path = "/projects/%(project_id)s/releases"
_obj_cls = ProjectRelease
_from_parent_attrs = {"project_id": "id"}
_create_attrs = RequiredOptional(
required=("name", "tag_name", "description"), optional=("ref", "assets")
)
+ _update_attrs = RequiredOptional(
+ optional=("name", "description", "milestones", "released_at")
+ )
class ProjectReleaseLink(ObjectDeleteMixin, SaveMixin, RESTObject):
diff --git a/tests/functional/api/test_releases.py b/tests/functional/api/test_releases.py
index f49181a..81ae7de 100644
--- a/tests/functional/api/test_releases.py
+++ b/tests/functional/api/test_releases.py
@@ -23,6 +23,15 @@ def test_create_project_release(project, project_file):
assert release.description == release_description
+def test_update_save_project_release(project, release):
+ updated_description = f"{release.description} updated"
+ release.description = updated_description
+ release.save()
+
+ release = project.releases.get(release.tag_name)
+ assert release.description == updated_description
+
+
def test_delete_project_release(project, release):
project.releases.delete(release.tag_name)
assert release not in project.releases.list()
diff --git a/tests/unit/objects/test_releases.py b/tests/unit/objects/test_releases.py
index 6c38a7c..58ab5d0 100644
--- a/tests/unit/objects/test_releases.py
+++ b/tests/unit/objects/test_releases.py
@@ -10,7 +10,11 @@ import responses
from gitlab.v4.objects import ProjectReleaseLink
+tag_name = "v1.0.0"
encoded_tag_name = "v1%2E0%2E0"
+release_name = "demo-release"
+release_description = "my-rel-desc"
+released_at = "2019-03-15T08:00:00Z"
link_name = "hello-world"
link_url = "https://gitlab.example.com/group/hello/-/jobs/688/artifacts/raw/bin/hello-darwin-amd64"
direct_url = f"https://gitlab.example.com/group/hello/-/releases/{encoded_tag_name}/downloads/hello-world"
@@ -24,6 +28,18 @@ link_content = {
"link_type": "other",
}
+release_content = {
+ "id": 3,
+ "tag_name": tag_name,
+ "name": release_name,
+ "description": release_description,
+ "milestones": [],
+ "released_at": released_at,
+}
+
+release_url = re.compile(
+ rf"http://localhost/api/v4/projects/1/releases/{encoded_tag_name}"
+)
links_url = re.compile(
rf"http://localhost/api/v4/projects/1/releases/{encoded_tag_name}/assets/links"
)
@@ -100,6 +116,21 @@ def resp_delete_link(no_content):
yield rsps
+@pytest.fixture
+def resp_update_release():
+ updated_content = dict(release_content)
+
+ with responses.RequestsMock() as rsps:
+ rsps.add(
+ method=responses.PUT,
+ url=release_url,
+ json=updated_content,
+ content_type="application/json",
+ status=200,
+ )
+ yield rsps
+
+
def test_list_release_links(release, resp_list_links):
links = release.links.list()
assert isinstance(links, list)
@@ -129,3 +160,11 @@ def test_update_release_link(release, resp_update_link):
def test_delete_release_link(release, resp_delete_link):
link = release.links.get(1, lazy=True)
link.delete()
+
+
+def test_update_release(release, resp_update_release):
+ release.name = release_name
+ release.description = release_description
+ release.save()
+ assert release.name == release_name
+ assert release.description == release_description