#!/usr/bin/env python3 # # Copyright 2022-2024 New Vector Ltd. # # SPDX-License-Identifier: AGPL-3.0-only # Please see LICENSE in the repository root for full details. # import argparse import hashlib import json import os # Run `pip3 install requests --break-system-packages` if not installed yet import requests # Run `pip3 install re` if not installed yet import re import time # This script downloads artifacts from GitHub. # Ref: https://docs.github.com/en/rest/actions/artifacts#get-an-artifact error = False ### Arguments parser = argparse.ArgumentParser(description='Download artifacts from GitHub.') parser.add_argument('-t', '--token', required=True, help='The GitHub token with read access.') parser.add_argument('-r', '--runUrl', required=True, help='the GitHub action run url.') parser.add_argument('-d', '--directory', default="", help='the target directory, where files will be downloaded. If not provided the runId will be used to create a directory.') parser.add_argument('-v', '--verbose', help="increase output verbosity.", action="store_true") parser.add_argument('-s', '--simulate', help="simulate action, do not create folder or download any file.", action="store_true") args = parser.parse_args() if args.verbose: print("Argument:") print(args) # Split the artifact URL to get information # Ex: https://github.com/element-hq/element-x-android/actions/runs/9065756777 runUrl = args.runUrl url_regex = r"https://github.com/(.+?)/(.+?)/actions/runs/(.+)" result = re.search(url_regex, runUrl) if result is None: print( "❌ Invalid parameter --runUrl '%s'. Please check the format.\nIt should be something like: %s" % (runUrl, 'https://github.com/element-hq/element-x-android/actions/runs/9065756777') ) exit(1) (gitHubRepoOwner, gitHubRepo, runId) = result.groups() if args.verbose: print("gitHubRepoOwner: %s, gitHubRepo: %s, runId: %s" % (gitHubRepoOwner, gitHubRepo, runId)) headers = { 'Authorization': "Bearer %s" % args.token, 'Accept': 'application/vnd.github+json' } base_url = "https://api.github.com/repos/%s/%s/actions/runs/%s" % (gitHubRepoOwner, gitHubRepo, runId) ### Fetch build state status = "" data = "{}" while status != "completed": r = requests.get(base_url, headers=headers) data = json.loads(r.content.decode()) if args.verbose: print("Json data:") print(data) status = data.get("status") if data.get("status") == "completed": if data.get("conclusion") != "success": print("❌ The action %s is completed, but there is an error, the conclusion is: %s." % (runUrl, data.get("conclusion"))) exit(1) else: # Wait 1 minute print("The action %s is not completed yet, waiting 1 minute..." % runUrl) time.sleep(60) artifacts_url = data.get("artifacts_url") if args.verbose: print("Artifacts url: %s" % artifacts_url) r = requests.get(artifacts_url, headers=headers) data = json.loads(r.content.decode()) if args.directory == "": targetDir = runId else: targetDir = args.directory for artifact in data.get("artifacts"): if args.verbose: print("Artifact:") print(artifact) # Invoke the script to download the artifact os.system("python3 ./tools/github/download_github_artifacts.py -t %s -d %s -a %s" % (args.token, targetDir, artifact.get("url")))