From ee5b843c2cbd84a8c7613ad373287339ba3aeb26 Mon Sep 17 00:00:00 2001 From: Ratchanan Srirattanamet Date: Mon, 17 Feb 2025 16:28:59 +0700 Subject: [PATCH 1/2] gitlab_release_notes/generate.py: also take merged_at into consideration `updated_at` could be after `merged_at`, e.g. for MRs that has additional comments after it's merged. So, after filtering by `updated_after` parameter, also do client-side filtering on `merged_at` field. Now, an interesting thing is that while GitLab offers order_by='merged_at' (since GitLab 17.2 [1]), there's no `merged_after` parameter that we can use. So we can't tell server to filter this for us. Also, Python cannot parse GitLab's spec-complient ISO8601 datetime until 3.11 [2]. Thus a library called `dateutil` is added as an external dependency. [1]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147052 [2]: https://docs.python.org/3/whatsnew/3.11.html#datetime --- gitlab_release_notes/generate.py | 16 ++++++++++++++-- setup.py | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/gitlab_release_notes/generate.py b/gitlab_release_notes/generate.py index a66c81e..7b6558a 100644 --- a/gitlab_release_notes/generate.py +++ b/gitlab_release_notes/generate.py @@ -1,4 +1,5 @@ import datetime +import dateutil.parser import gitlab import os.path import sys @@ -43,11 +44,17 @@ def generate_release_notes(project_id, endstr = '
', since=None, quiet=Fals last_date = since elif not project.releases.list(get_all=False): log_pending = f"Changelog of {project.name}:{endstr}" - last_date = '0000-01-01T00:00:00Z' + last_date = dateutil.parser.isoparse('0000-01-01T00:00:00Z') else: last_release = project.releases.list(get_all=False)[0] log_pending = f"Changelog since release {last_release.name} of {project.name}:{endstr}" - last_date = last_release.released_at + last_date = dateutil.parser.isoparse(last_release.released_at) + + last_datetime = last_date + if not isinstance(last_datetime, datetime.datetime): + last_datetime = \ + datetime.datetime.combine(last_datetime, datetime.datetime.min.time()) \ + .replace(tzinfo=datetime.timezone.utc) page = 1 list_mrs = project.mergerequests.list(state='merged', @@ -64,6 +71,11 @@ def generate_release_notes(project_id, endstr = '
', since=None, quiet=Fals log += log_pending while list_mrs: for mr in list_mrs: + # `updated_at` could be after `merged_at`, e.g. for MRs that has + # additional comments after it's merged. + if dateutil.parser.isoparse(mr.merged_at) < last_datetime: + continue + line = f" * {mr.title} (@{mr.author['username']}){endstr}" log += line diff --git a/setup.py b/setup.py index 8a19d99..34f22fd 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ def read_requirements(path): long_description_content_type="text/markdown", author="vuillaut", packages=find_packages(exclude=["gitlab_release_notes/tests", ".github"]), - install_requires=['python-gitlab>=3.0'], + install_requires=['python-gitlab>=3.0', 'python-dateutil'], entry_points={ "console_scripts": ["gitlab-release-notes = gitlab_release_notes.generate:main"] }, From 9b703604e73b833e20bb0d7f74c3fa127ecee84a Mon Sep 17 00:00:00 2001 From: Ratchanan Srirattanamet Date: Mon, 17 Feb 2025 16:38:02 +0700 Subject: [PATCH 2/2] gitlab_release_notes/generate.py: order MRs by `merged_at` field It was not possible to order by `merged_at` field until GitLab 17.2, released ~6 months ago (and is already EoL). --- gitlab_release_notes/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitlab_release_notes/generate.py b/gitlab_release_notes/generate.py index 7b6558a..9e3dc67 100644 --- a/gitlab_release_notes/generate.py +++ b/gitlab_release_notes/generate.py @@ -59,7 +59,7 @@ def generate_release_notes(project_id, endstr = '
', since=None, quiet=Fals page = 1 list_mrs = project.mergerequests.list(state='merged', get_all=False, - order_by='updated_at', + order_by='merged_at', updated_after=last_date, page=page) if not list_mrs: