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.
This commit is contained in:
Yichao Yu 2025-02-10 21:15:30 -05:00
parent bd72ea04d2
commit 92a424f946
4 changed files with 71 additions and 9 deletions

View file

@ -399,8 +399,8 @@ Check GitHub
source = "github" source = "github"
Check `GitHub <https://github.com/>`_ for updates. The version returned is in Check `GitHub <https://github.com/>`_ for updates. The version returned is in
date format ``%Y%m%d.%H%M%S``, e.g. ``20130701.012212``, unless ``use_latest_release`` date format ``%Y%m%d.%H%M%S``, e.g. ``20130701.012212``, unless ``use_latest_release``,
or ``use_max_tag`` is used. See below. ``use_max_tag`` or ``use_max_release`` is used. See below.
github github
The github repository, with author, e.g. ``lilydjwg/nvchecker``. 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 Will return the release's tag name instead of date. (For historical reasons
it doesn't return the release name. See below to change.) 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 use_release_name
When ``use_latest_release`` is ``true``, setting this to ``true`` will cause When ``use_latest_release`` or ``use_max_release`` is ``true``,
nvchecker to return the release name instead of the tag name. setting this to ``true`` will cause nvchecker to return the release name
instead of the tag name.
include_prereleases include_prereleases
When ``use_latest_release`` is ``true``, set this to ``true`` to take prereleases into When ``use_latest_release`` or ``use_max_release`` is ``true``,
account. set this to ``true`` to take prereleases into account.
This returns the release names (not the tag names). This returns the release names (not the tag names).
@ -449,7 +455,7 @@ query
use_max_tag use_max_tag
Set this to ``true`` to check for the max tag on GitHub. Unlike 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 lightweight ones, and return the largest one sorted by the
``sort_version_key`` option. Will return the tag name instead of date. ``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 the keyfile for the host (e.g. ``github.com``)
- an entry in your ``netrc`` file for the host - 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 Check Gitea
~~~~~~~~~~~ ~~~~~~~~~~~

View file

@ -21,6 +21,7 @@ GITHUB_URL = 'https://api.%s/repos/%s/commits'
GITHUB_LATEST_RELEASE = 'https://api.%s/repos/%s/releases/latest' GITHUB_LATEST_RELEASE = 'https://api.%s/repos/%s/releases/latest'
# https://developer.github.com/v3/git/refs/#get-all-references # https://developer.github.com/v3/git/refs/#get-all-references
GITHUB_MAX_TAG = 'https://api.%s/repos/%s/git/refs/tags' 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' GITHUB_GRAPHQL_URL = 'https://api.%s/graphql'
async def get_version(name, conf, **kwargs): async def get_version(name, conf, **kwargs):
@ -192,10 +193,13 @@ async def get_version_real(
br = conf.get('branch') br = conf.get('branch')
path = conf.get('path') path = conf.get('path')
use_max_tag = conf.get('use_max_tag', False) use_max_tag = conf.get('use_max_tag', False)
use_max_release = conf.get('use_max_release', False)
if use_latest_release: if use_latest_release:
url = GITHUB_LATEST_RELEASE % (host, repo) url = GITHUB_LATEST_RELEASE % (host, repo)
elif use_max_tag: elif use_max_tag:
url = GITHUB_MAX_TAG % (host, repo) url = GITHUB_MAX_TAG % (host, repo)
elif use_max_release:
url = GITHUB_MAX_RELEASE % (host, repo)
else: else:
url = GITHUB_URL % (host, repo) url = GITHUB_URL % (host, repo)
parameters = {} parameters = {}
@ -225,6 +229,18 @@ async def get_version_real(
raise GetVersionError('No tag found in upstream repository.') raise GetVersionError('No tag found in upstream repository.')
return tags 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 use_latest_release:
if 'tag_name' not in data: if 'tag_name' not in data:
raise GetVersionError('No release found in upstream repository.') raise GetVersionError('No release found in upstream repository.')

View file

@ -18,7 +18,7 @@ _handler_precedence = (
BOOL_KEYS = [ BOOL_KEYS = [
'strip_release', 'use_last_modified', 'strip_release', 'use_last_modified',
'use_latest_release', 'use_latest_tag', 'use_latest_release', 'use_latest_tag',
'use_max_tag', 'use_pre_release', 'use_max_release', 'use_max_tag', 'use_pre_release',
] ]
INT_KEYS = [ INT_KEYS = [

View file

@ -59,6 +59,20 @@ async def test_github_max_tag(get_version):
"use_max_tag": True, "use_max_tag": True,
}) == "second_release" }) == "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): async def test_github_max_tag_with_ignored(get_version):
assert await get_version("example", { assert await get_version("example", {
"source": "github", "source": "github",
@ -67,6 +81,21 @@ async def test_github_max_tag_with_ignored(get_version):
"ignored": "second_release release3", "ignored": "second_release release3",
}) == "first_release" }) == "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): async def test_github_with_path(get_version):
assert await get_version("example", { assert await get_version("example", {
"source": "github", "source": "github",
@ -91,6 +120,16 @@ async def test_github_max_tag_with_include(get_version):
}) })
assert re.match(r'chrome-[\d.]+', 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): async def test_github_latest_tag(get_version):
assert await get_version("example", { assert await get_version("example", {
"source": "github", "source": "github",