Skip to content

Commit 33d3428

Browse files
authored
Merge pull request #1522 from PPaques/1521-releases-edit
Support Release Update API
2 parents 2c86003 + 13bf61d commit 33d3428

File tree

5 files changed

+60
-7
lines changed

5 files changed

+60
-7
lines changed

docs/gl_objects/projects.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,6 @@ Create a tag::
412412

413413
tag = project.tags.create({'tag_name': '1.0', 'ref': 'master'})
414414

415-
Set or update the release note for a tag::
416-
417-
tag.set_release_description('awesome v1.0 release')
418-
419415
Delete a tag::
420416

421417
project.tags.delete('1.0')

docs/gl_objects/releases.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ Get a single release::
2727

2828
release = project.releases.get('v1.2.3')
2929

30+
Edit a release::
31+
32+
release.name = "Demo Release"
33+
release.description = "release notes go here"
34+
release.save()
35+
3036
Create a release for a project tag::
3137

3238
release = project.releases.create({'name':'Demo Release', 'tag_name':'v1.2.3', 'description':'release notes go here'})

gitlab/v4/objects/releases.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from gitlab.base import RequiredOptional, RESTManager, RESTObject
2-
from gitlab.mixins import CRUDMixin, NoUpdateMixin, ObjectDeleteMixin, SaveMixin
2+
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin
33

44
__all__ = [
55
"ProjectRelease",
@@ -9,18 +9,21 @@
99
]
1010

1111

12-
class ProjectRelease(RESTObject):
12+
class ProjectRelease(SaveMixin, RESTObject):
1313
_id_attr = "tag_name"
1414
_managers = (("links", "ProjectReleaseLinkManager"),)
1515

1616

17-
class ProjectReleaseManager(NoUpdateMixin, RESTManager):
17+
class ProjectReleaseManager(CRUDMixin, RESTManager):
1818
_path = "/projects/%(project_id)s/releases"
1919
_obj_cls = ProjectRelease
2020
_from_parent_attrs = {"project_id": "id"}
2121
_create_attrs = RequiredOptional(
2222
required=("name", "tag_name", "description"), optional=("ref", "assets")
2323
)
24+
_update_attrs = RequiredOptional(
25+
optional=("name", "description", "milestones", "released_at")
26+
)
2427

2528

2629
class ProjectReleaseLink(ObjectDeleteMixin, SaveMixin, RESTObject):

tests/functional/api/test_releases.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ def test_create_project_release(project, project_file):
2323
assert release.description == release_description
2424

2525

26+
def test_update_save_project_release(project, release):
27+
updated_description = f"{release.description} updated"
28+
release.description = updated_description
29+
release.save()
30+
31+
release = project.releases.get(release.tag_name)
32+
assert release.description == updated_description
33+
34+
2635
def test_delete_project_release(project, release):
2736
project.releases.delete(release.tag_name)
2837
assert release not in project.releases.list()

tests/unit/objects/test_releases.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@
1010

1111
from gitlab.v4.objects import ProjectReleaseLink
1212

13+
tag_name = "v1.0.0"
1314
encoded_tag_name = "v1%2E0%2E0"
15+
release_name = "demo-release"
16+
release_description = "my-rel-desc"
17+
released_at = "2019-03-15T08:00:00Z"
1418
link_name = "hello-world"
1519
link_url = "https://gitlab.example.com/group/hello/-/jobs/688/artifacts/raw/bin/hello-darwin-amd64"
1620
direct_url = f"https://gitlab.example.com/group/hello/-/releases/{encoded_tag_name}/downloads/hello-world"
@@ -24,6 +28,18 @@
2428
"link_type": "other",
2529
}
2630

31+
release_content = {
32+
"id": 3,
33+
"tag_name": tag_name,
34+
"name": release_name,
35+
"description": release_description,
36+
"milestones": [],
37+
"released_at": released_at,
38+
}
39+
40+
release_url = re.compile(
41+
rf"http://localhost/api/v4/projects/1/releases/{encoded_tag_name}"
42+
)
2743
links_url = re.compile(
2844
rf"http://localhost/api/v4/projects/1/releases/{encoded_tag_name}/assets/links"
2945
)
@@ -100,6 +116,21 @@ def resp_delete_link(no_content):
100116
yield rsps
101117

102118

119+
@pytest.fixture
120+
def resp_update_release():
121+
updated_content = dict(release_content)
122+
123+
with responses.RequestsMock() as rsps:
124+
rsps.add(
125+
method=responses.PUT,
126+
url=release_url,
127+
json=updated_content,
128+
content_type="application/json",
129+
status=200,
130+
)
131+
yield rsps
132+
133+
103134
def test_list_release_links(release, resp_list_links):
104135
links = release.links.list()
105136
assert isinstance(links, list)
@@ -129,3 +160,11 @@ def test_update_release_link(release, resp_update_link):
129160
def test_delete_release_link(release, resp_delete_link):
130161
link = release.links.get(1, lazy=True)
131162
link.delete()
163+
164+
165+
def test_update_release(release, resp_update_release):
166+
release.name = release_name
167+
release.description = release_description
168+
release.save()
169+
assert release.name == release_name
170+
assert release.description == release_description

0 commit comments

Comments
 (0)