From 92a424f94628d6ed3a9149598326b89c2b56ede6 Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Mon, 10 Feb 2025 21:15:30 -0500 Subject: [PATCH] Implement use_max_release for github This follows the logic for use_max_tag but only includes the tags that are part of a github release. The returned version follows include_prerelease and use_release_name just like use_latest_release. This allows waiting for release artifacts to be created after the tag is created on the repo. --- docs/usage.rst | 23 ++++++++++++++-------- nvchecker_source/github.py | 16 ++++++++++++++++ scripts/nvchecker-ini2toml | 2 +- tests/test_github.py | 39 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 9 deletions(-) diff --git a/docs/usage.rst b/docs/usage.rst index eecd993..c2afdf9 100644 --- a/docs/usage.rst +++ b/docs/usage.rst @@ -399,8 +399,8 @@ Check GitHub source = "github" Check `GitHub `_ for updates. The version returned is in -date format ``%Y%m%d.%H%M%S``, e.g. ``20130701.012212``, unless ``use_latest_release`` -or ``use_max_tag`` is used. See below. +date format ``%Y%m%d.%H%M%S``, e.g. ``20130701.012212``, unless ``use_latest_release``, +``use_max_tag`` or ``use_max_release`` is used. See below. github The github repository, with author, e.g. ``lilydjwg/nvchecker``. @@ -426,13 +426,19 @@ use_latest_release Will return the release's tag name instead of date. (For historical reasons it doesn't return the release name. See below to change.) +use_max_release + Set this to ``true`` to check for the max release on GitHub. + This option returns the largest one sorted by the + ``sort_version_key`` option. Will return the tag name instead of date. + use_release_name - When ``use_latest_release`` is ``true``, setting this to ``true`` will cause - nvchecker to return the release name instead of the tag name. + When ``use_latest_release`` or ``use_max_release`` is ``true``, + setting this to ``true`` will cause nvchecker to return the release name + instead of the tag name. include_prereleases - When ``use_latest_release`` is ``true``, set this to ``true`` to take prereleases into - account. + When ``use_latest_release`` or ``use_max_release`` is ``true``, + set this to ``true`` to take prereleases into account. This returns the release names (not the tag names). @@ -449,7 +455,7 @@ query use_max_tag Set this to ``true`` to check for the max tag on GitHub. Unlike - ``use_latest_release``, this option includes both annotated tags and + ``use_max_release``, this option includes both annotated tags and lightweight ones, and return the largest one sorted by the ``sort_version_key`` option. Will return the tag name instead of date. @@ -465,7 +471,8 @@ To set an authorization token, you can set: - an entry in the keyfile for the host (e.g. ``github.com``) - an entry in your ``netrc`` file for the host -This source supports :ref:`list options` when ``use_max_tag`` is set. +This source supports :ref:`list options` when ``use_max_tag`` or +``use_max_release`` is set. Check Gitea ~~~~~~~~~~~ diff --git a/nvchecker_source/github.py b/nvchecker_source/github.py index 8585366..9e2a8d1 100644 --- a/nvchecker_source/github.py +++ b/nvchecker_source/github.py @@ -21,6 +21,7 @@ GITHUB_URL = 'https://api.%s/repos/%s/commits' GITHUB_LATEST_RELEASE = 'https://api.%s/repos/%s/releases/latest' # https://developer.github.com/v3/git/refs/#get-all-references GITHUB_MAX_TAG = 'https://api.%s/repos/%s/git/refs/tags' +GITHUB_MAX_RELEASE = 'https://api.%s/repos/%s/releases' GITHUB_GRAPHQL_URL = 'https://api.%s/graphql' async def get_version(name, conf, **kwargs): @@ -192,10 +193,13 @@ async def get_version_real( br = conf.get('branch') path = conf.get('path') use_max_tag = conf.get('use_max_tag', False) + use_max_release = conf.get('use_max_release', False) if use_latest_release: url = GITHUB_LATEST_RELEASE % (host, repo) elif use_max_tag: url = GITHUB_MAX_TAG % (host, repo) + elif use_max_release: + url = GITHUB_MAX_RELEASE % (host, repo) else: url = GITHUB_URL % (host, repo) parameters = {} @@ -225,6 +229,18 @@ async def get_version_real( raise GetVersionError('No tag found in upstream repository.') return tags + if use_max_release: + releases: List[Union[str, RichResult]] = [ + RichResult( + version = ref['name'] if use_release_name else ref['tag_name'], + gitref = f"refs/tags/{ref['tag_name']}", + url = ref['html_url'], + ) for ref in data if include_prereleases or not ref['prerelease'] + ] + if not releases: + raise GetVersionError('No release found in upstream repository.') + return releases + if use_latest_release: if 'tag_name' not in data: raise GetVersionError('No release found in upstream repository.') diff --git a/scripts/nvchecker-ini2toml b/scripts/nvchecker-ini2toml index e91c03e..7e4f710 100755 --- a/scripts/nvchecker-ini2toml +++ b/scripts/nvchecker-ini2toml @@ -18,7 +18,7 @@ _handler_precedence = ( BOOL_KEYS = [ 'strip_release', 'use_last_modified', 'use_latest_release', 'use_latest_tag', - 'use_max_tag', 'use_pre_release', + 'use_max_release', 'use_max_tag', 'use_pre_release', ] INT_KEYS = [ diff --git a/tests/test_github.py b/tests/test_github.py index c936642..63aeef5 100644 --- a/tests/test_github.py +++ b/tests/test_github.py @@ -59,6 +59,20 @@ async def test_github_max_tag(get_version): "use_max_tag": True, }) == "second_release" +async def test_github_max_release(get_version): + assert await get_version("example", { + "source": "github", + "github": "harry-sanabria/ReleaseTestRepo", + "use_max_release": True, + }) == "second_release" + + assert await get_version("example", { + "source": "github", + "github": "harry-sanabria/ReleaseTestRepo", + "use_max_release": True, + "use_release_name": True, + }) == "second_release" + async def test_github_max_tag_with_ignored(get_version): assert await get_version("example", { "source": "github", @@ -67,6 +81,21 @@ async def test_github_max_tag_with_ignored(get_version): "ignored": "second_release release3", }) == "first_release" +async def test_github_max_release_with_ignored(get_version): + assert await get_version("example", { + "source": "github", + "github": "harry-sanabria/ReleaseTestRepo", + "use_max_release": True, + "ignored": "second_release release3", + }) == "first_release" + assert await get_version("example", { + "source": "github", + "github": "harry-sanabria/ReleaseTestRepo", + "use_max_release": True, + "ignored": "second_release", + "use_release_name": True, + }) == "release #3" + async def test_github_with_path(get_version): assert await get_version("example", { "source": "github", @@ -91,6 +120,16 @@ async def test_github_max_tag_with_include(get_version): }) assert re.match(r'chrome-[\d.]+', version) +async def test_github_max_release_with_include(get_version): + version = await get_version("example", { + "source": "github", + "github": "EFForg/https-everywhere", + "use_max_release": True, + "use_release_name": True, + "include_regex": r"Release \d.*", + }) + assert re.match(r'Release [\d.]+', version) + async def test_github_latest_tag(get_version): assert await get_version("example", { "source": "github",