fetch_github_release.py (2961B)
1 # Copyright 2023 The Chromium Authors 2 # Use of this source code is governed by a BSD-style license that can be 3 # found in the LICENSE file. 4 5 import argparse 6 import hashlib 7 import json 8 import os 9 import pathlib 10 import re 11 import urllib.request 12 13 14 def _fetch_json(url): 15 return json.load(urllib.request.urlopen(url)) 16 17 18 def _latest(api_url, install_scripts=None): 19 # Make the version change every time this file changes. 20 md5 = hashlib.md5() 21 md5.update(pathlib.Path(__file__).read_bytes()) 22 import __main__ 23 md5.update(pathlib.Path(__main__.__file__).read_bytes()) 24 25 if install_scripts: 26 for path in install_scripts: 27 md5.update(pathlib.Path(path).read_bytes()) 28 file_hash = md5.hexdigest()[:10] 29 30 release = _fetch_json(f'{api_url}/releases/latest')['tag_name'] 31 print('{}.{}'.format(release, file_hash)) 32 33 34 def _get_url(api_url, 35 artifact_filename=None, 36 artifact_extension=None, 37 artifact_regex=None): 38 # Split off our md5 hash. 39 version = os.environ['_3PP_VERSION'].rsplit('.', 1)[0] 40 json_dict = _fetch_json(f'{api_url}/releases/tags/{version}') 41 urls = [x['browser_download_url'] for x in json_dict['assets']] 42 43 if artifact_regex: 44 urls = [x for x in urls if re.search(artifact_regex, x)] 45 46 if len(urls) != 1: 47 raise Exception('len(urls) != 1: \n' + '\n'.join(urls)) 48 49 partial_manifest = { 50 'url': urls, 51 'ext': artifact_extension or '', 52 } 53 if artifact_filename: 54 partial_manifest['name'] = [artifact_filename] 55 56 print(json.dumps(partial_manifest)) 57 58 59 def main(*, 60 project, 61 artifact_filename=None, 62 artifact_extension=None, 63 artifact_regex=None, 64 install_scripts=None, 65 extract_extension=None): 66 """The fetch.py script for a 3pp module. 67 68 Args: 69 project: GitHub username for the repo. e.g. "google/protobuf". 70 artifact_filename: The name for the downloaded file. Required when not 71 setting "unpack_archive: true" in 3pp.pb. 72 artifact_extension: File extension of file being downloaded. Required when 73 setting "unpack_archive: true" in 3pp.pb. 74 artifact_regex: A regex to use to identify the desired artifact from the 75 list of artifacts on the release. 76 install_scripts: List of script to add to the md5 of the version. The main 77 module and this module are always included. 78 """ 79 parser = argparse.ArgumentParser() 80 parser.add_argument('action', choices=('latest', 'get_url')) 81 args = parser.parse_args() 82 83 api_url = f'https://api.github.com/repos/{project}' 84 if args.action == 'latest': 85 _latest(api_url, install_scripts=install_scripts) 86 else: 87 _get_url(api_url, 88 artifact_filename=artifact_filename, 89 artifact_extension=artifact_extension, 90 artifact_regex=artifact_regex) 91 92 93 if __name__ == '__main__': 94 main()