GitHub: add use_latest_tag

This commit is contained in:
lilydjwg 2020-06-14 13:55:51 +08:00
parent ac3e2beef9
commit 7a2d3d226b
4 changed files with 84 additions and 7 deletions

View file

@ -298,6 +298,15 @@ use_latest_release
Will return the release name instead of date.
use_latest_tag
Set this to ``true`` to check for the latest tag on GitHub.
This requires a token because it's using the v4 GraphQL API.
query
When ``use_latest_tag`` is ``true``, this sets a query for the tag. The exact
matching method is not documented by GitHub.
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

View file

@ -17,6 +17,7 @@ GITHUB_URL = 'https://api.github.com/repos/%s/commits'
GITHUB_LATEST_RELEASE = 'https://api.github.com/repos/%s/releases/latest'
# https://developer.github.com/v3/git/refs/#get-all-references
GITHUB_MAX_TAG = 'https://api.github.com/repos/%s/git/refs/tags'
GITHUB_GRAPHQL_URL = 'https://api.github.com/graphql'
async def get_version(name, conf, **kwargs):
try:
@ -24,7 +25,68 @@ async def get_version(name, conf, **kwargs):
except HTTPError as e:
check_ratelimit(e, name)
QUERY_LATEST_TAG = '''
{{
repository(name: "{name}", owner: "{owner}") {{
refs(refPrefix: "refs/tags/", first: 1,
query: "{query}",
orderBy: {{field: TAG_COMMIT_DATE, direction: DESC}}) {{
edges {{
node {{
name
}}
}}
}}
}}
}}
'''
async def get_latest_tag(name, conf, token):
repo = conf.get('github')
query = conf.get('query', '')
owner, reponame = repo.split('/')
headers = {
'Authorization': 'bearer %s' % token,
'Content-Type': 'application/json',
}
q = QUERY_LATEST_TAG.format(
owner = owner,
name = reponame,
query = query,
)
async with session.post(
GITHUB_GRAPHQL_URL,
headers = headers,
json = {'query': q},
) as res:
j = await res.json()
refs = j['data']['repository']['refs']['edges']
if not refs:
logger.error('no tag found', name=name)
return
return refs[0]['node']['name']
def get_token(kwargs):
token = os.environ.get('NVCHECKER_GITHUB_TOKEN')
if token:
return token
token = kwargs['keyman'].get_key('github')
return token
async def get_version_real(name, conf, **kwargs):
token = get_token(kwargs)
use_latest_tag = conf.getboolean('use_latest_tag', False)
if use_latest_tag:
if not token:
logger.error('token not given but it is required',
name = name)
return
return await get_latest_tag(name, conf, token)
repo = conf.get('github')
br = conf.get('branch')
path = conf.get('path')
@ -47,12 +109,8 @@ async def get_version_real(name, conf, **kwargs):
headers = {
'Accept': 'application/vnd.github.quicksilver-preview+json',
}
if 'NVCHECKER_GITHUB_TOKEN' in os.environ:
headers['Authorization'] = 'token %s' % os.environ['NVCHECKER_GITHUB_TOKEN']
else:
key = kwargs['keyman'].get_key('github')
if key:
headers['Authorization'] = 'token %s' % key
if token:
headers['Authorization'] = 'token %s' % token
kwargs = {}
if conf.get('proxy'):

View file

@ -34,6 +34,12 @@ def try_use_http2(curl):
curl.setopt(pycurl.HTTP_VERSION, 4)
class Session:
def post(self, url, **kwargs):
j = kwargs.pop('json', None)
if j:
kwargs['body'] = json.dumps(j)
return self.get(url, method='POST', **kwargs)
def get(self, url, **kwargs):
kwargs['prepare_curl_callback'] = try_use_http2

View file

@ -1,5 +1,5 @@
# MIT licensed
# Copyright (c) 2013-2018 lilydjwg <lilydjwg@gmail.com>, et al.
# Copyright (c) 2013-2020 lilydjwg <lilydjwg@gmail.com>, et al.
import os
import re
@ -48,3 +48,7 @@ async def test_github_max_tag_with_include(get_version):
"include_regex": r"chrome-\d.*",
})
assert re.match(r'chrome-[\d.]+', version)
async def test_github_latest_tag(get_version):
assert await get_version("example", {"github": "harry-sanabria/ReleaseTestRepo", "use_latest_tag": 1}) == "release3"