import argparse
import io
import zipfile
import requests
def request(url, token):
if token:
return requests.get(url, headers={"Authorization": "Bearer " + token})
return requests.get(url)
def get_latest_artifact_url(options):
prefix = "%s/repos/%s/%s/actions/" % (options.api_url, options.owner, options.repository)
workflow_id = None
response = request(prefix + "workflows", options.token)
for workflow in response.json()['workflows']:
if workflow['name'] == options.workflow:
workflow_id = workflow['id']
if workflow_id is None:
raise RuntimeError("Workflow '%s' not found." % options.workflow)
workflow_run_ids = []
response = request("%sworkflows/%s/runs" % (prefix, workflow_id), options.token)
for workflow_run in response.json()['workflow_runs']:
if options.branch == "main" and workflow_run['head_branch'][:1] == "v":
workflow_run_ids.append(workflow_run['id'])
for workflow_run in response.json()['workflow_runs']:
if (workflow_run['status'] == "completed"
and (options.allow_failed or workflow_run['conclusion'] == "success")
and workflow_run['head_branch'] == options.branch):
workflow_run_ids.append(workflow_run['id'])
break
if not workflow_run_ids:
raise RuntimeError("No successful workflow run found in branch '%s'." % options.branch)
for workflow_run_id in workflow_run_ids:
response = request("%sruns/%s/artifacts" % (prefix, workflow_run_id), options.token)
for artifact in response.json()['artifacts']:
if artifact['name'].startswith(options.prefix):
yield "%sartifacts/%s/zip" % (prefix, artifact['id'])
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("--api-url", default="https://api.github.com")
ap.add_argument("--owner", default="eclipse-sumo")
ap.add_argument("--repository", default="sumo")
ap.add_argument("--workflow", default="windows-wheels")
ap.add_argument("--branch", default="main")
ap.add_argument("--token", help="GitHub authentication token")
ap.add_argument("--directory", help="output directory")
ap.add_argument("--prefix", default="libsumo-python-3.", help="prefix of the artifact zip file")
ap.add_argument("--allow-failed", action="store_true", default=False, help="download even if the build failed")
ap.add_argument("-v", "--verbose", action="store_true", default=False, help="tell me more")
options = ap.parse_args()
for artifact_url in get_latest_artifact_url(options):
response = request(artifact_url, options.token)
if response.status_code == 200:
with zipfile.ZipFile(io.BytesIO(response.content)) as zip:
zip.extractall(options.directory)
if options.verbose:
print(artifact_url, response)