Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/build_config/download_artifact.py
194645 views
1
#!/usr/bin/env python3
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2008-2026 German Aerospace Center (DLR) and others.
4
# This program and the accompanying materials are made available under the
5
# terms of the Eclipse Public License 2.0 which is available at
6
# https://www.eclipse.org/legal/epl-2.0/
7
# This Source Code may also be made available under the following Secondary
8
# Licenses when the conditions for such availability set forth in the Eclipse
9
# Public License 2.0 are satisfied: GNU General Public License, version 2
10
# or later which is available at
11
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
14
# @file download_artifact.py
15
# @author Michael Behrisch
16
# @date 2024-05-03
17
18
import argparse
19
import io
20
import os
21
import sys
22
import zipfile
23
24
import requests
25
26
27
def request(url, token):
28
if token:
29
return requests.get(url, headers={"Authorization": "Bearer " + token})
30
return requests.get(url)
31
32
33
def get_latest_artifact_url(options):
34
prefix = "%s/repos/%s/%s/actions/" % (options.api_url, options.owner, options.repository)
35
workflow_id = 0
36
response = request(prefix + "workflows", options.token)
37
for workflow in response.json()['workflows']:
38
# for several workflows with the same name we take the one most recently created (highest id)
39
if workflow['name'] == options.workflow and workflow['id'] > workflow_id:
40
workflow_id = workflow['id']
41
if workflow_id == 0:
42
raise RuntimeError("Workflow '%s' not found." % options.workflow)
43
44
workflow_run_ids = []
45
response = request("%sworkflows/%s/runs" % (prefix, workflow_id), options.token)
46
for workflow_run in response.json()['workflow_runs']:
47
if options.branch == "main" and workflow_run['head_branch'][:1] == "v":
48
# there seems to be no easy way to identify a tag so we take the first letter
49
workflow_run_ids.append(workflow_run['id'])
50
for workflow_run in response.json()['workflow_runs']:
51
if (workflow_run['status'] == "completed"
52
and (options.allow_failed or workflow_run['conclusion'] == "success")
53
and workflow_run['head_branch'] == options.branch):
54
workflow_run_ids.append(workflow_run['id'])
55
break
56
if not workflow_run_ids:
57
raise RuntimeError("No successful workflow run found in branch '%s'." % options.branch)
58
59
for workflow_run_id in workflow_run_ids:
60
response = request("%sruns/%s/artifacts" % (prefix, workflow_run_id), options.token)
61
for artifact in response.json()['artifacts']:
62
if artifact['name'].startswith(options.prefix):
63
yield "%sartifacts/%s/zip" % (prefix, artifact['id'])
64
65
66
if __name__ == "__main__":
67
ap = argparse.ArgumentParser()
68
ap.add_argument("--api-url", default="https://api.github.com")
69
ap.add_argument("--owner", default="eclipse-sumo")
70
ap.add_argument("--repository", default="sumo")
71
ap.add_argument("--workflow", default="cibuildwheel")
72
ap.add_argument("--branch", default="main")
73
ap.add_argument("--token", help="GitHub authentication token")
74
ap.add_argument("--directory", help="output directory")
75
ap.add_argument("--prefix", default="cibw", help="prefix of the artifact zip file")
76
ap.add_argument("--allow-failed", action="store_true", default=False, help="download even if the build failed")
77
ap.add_argument("-v", "--verbose", action="store_true", default=False, help="tell me more")
78
options = ap.parse_args()
79
80
if not options.token:
81
for cred_path in (".", os.path.dirname(__file__), os.path.expanduser("~")):
82
if os.path.exists(os.path.join(cred_path, ".git-credentials")):
83
with open(os.path.join(cred_path, ".git-credentials")) as f:
84
options.token = f.read().split(":")[-1].split("@")[0]
85
break
86
if not options.token:
87
sys.exit("no authentication token found, please use the option --token or provide a .git-credentials file")
88
for artifact_url in get_latest_artifact_url(options):
89
response = request(artifact_url, options.token)
90
if response.status_code == 200:
91
with zipfile.ZipFile(io.BytesIO(response.content)) as zip:
92
zip.extractall(options.directory)
93
if options.verbose:
94
print(artifact_url, response)
95
96