Skip to content

Commit 38cfd35

Browse files
committed
add main job from gha
1 parent f242146 commit 38cfd35

File tree

1 file changed

+92
-26
lines changed

1 file changed

+92
-26
lines changed

fetch_and_render.py

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import argparse
2+
from concurrent.futures import ThreadPoolExecutor, wait
23
import sys
34
import traceback
45
from collections import defaultdict
@@ -73,7 +74,47 @@ class TravisJobStat:
7374
duration_s: str
7475

7576

77+
GITHUB_TO_TRAVIS_STATUS_MAP = {
78+
"action_required": "created",
79+
"cancelled": "failed",
80+
"failure": "failed",
81+
"neutral": "created",
82+
"success": "passed",
83+
"skipped": "failed",
84+
"stale": "failed",
85+
"timed_out": "failed",
86+
}
87+
88+
7689
def get_travis_status(commit_sha, cache_dir="travis_events") -> List[TravisJobStat]:
90+
def get_gha_status(sha):
91+
data = requests.get(
92+
f"https://api.github.com/repos/ray-project/ray/commits/{sha}/check-suites",
93+
headers=GH_HEADERS,
94+
).json()
95+
96+
if "check_suites" not in data:
97+
return None
98+
99+
for check in data["check_suites"]:
100+
slug = check["app"]["slug"]
101+
if slug == "github-actions" and check["status"] == "completed":
102+
data = requests.get(check["check_runs_url"], headers=GH_HEADERS).json()
103+
if len(data["check_runs"]) == 0:
104+
return None
105+
run = data["check_runs"][0]
106+
return TravisJobStat(
107+
job_id=run["id"],
108+
os="windows",
109+
commit=sha,
110+
env="github action main job",
111+
state=GITHUB_TO_TRAVIS_STATUS_MAP[check["conclusion"]],
112+
url=run["html_url"],
113+
duration_s=_parse_duration(
114+
check.get("started_at"), check.get("completed_at")
115+
),
116+
)
117+
77118
def find_travis_build_id(sha):
78119
data = requests.get(
79120
f"https://api.github.com/repos/ray-project/ray/commits/{sha}/check-suites",
@@ -121,15 +162,23 @@ def list_travis_job_status(build_id):
121162
status_file = dir_name / "status_complete"
122163
data_file = dir_name / "status.json"
123164
if not status_file.exists():
165+
statuses = []
166+
gha_status = get_gha_status(commit_sha)
167+
if gha_status:
168+
statuses.append(gha_status)
169+
124170
build_id = find_travis_build_id(commit_sha)
125-
if build_id is None:
171+
if build_id is not None:
172+
job_status = list_travis_job_status(build_id)
173+
statuses.extend(job_status)
174+
175+
if len(statuses) == 0:
126176
return []
127-
job_status = list_travis_job_status(build_id)
128177

129178
with open(data_file, "w") as f:
130-
f.write(TravisJobStat.schema().dumps(job_status, many=True))
179+
f.write(TravisJobStat.schema().dumps(statuses, many=True))
131180

132-
job_states = {job.state for job in job_status}
181+
job_states = {job.state for job in statuses}
133182
if len(job_states.intersection({"created", "started"})) == 0:
134183
status_file.touch()
135184

@@ -147,28 +196,32 @@ class BuildkiteStatus:
147196
state: str
148197
url: str
149198
commit: str
150-
created_at: Optional[str]
199+
startedAt: Optional[str]
151200
finished_at: Optional[str]
152201

153202
def get_duration_s(self) -> int:
154-
return _parse_duration(self.created_at, self.finished_at)
203+
return _parse_duration(self.startedAt, self.finished_at)
155204

156205

157-
def get_buildkite_status() -> List[BuildkiteStatus]:
206+
def get_buildkite_status() -> Tuple[List, List[BuildkiteStatus]]:
207+
builds = []
158208
result = []
159209
page_token = None
160210
for offset in [0, 20, 40, 60, 80, 100]:
161211
if offset == 0:
162-
chunks, page_token = get_buildkite_status_paginated(f"first: 20")
212+
builds_chunk, result_chunks, page_token = get_buildkite_status_paginated(
213+
f"first: 20"
214+
)
163215
else:
164-
chunks, page_token = get_buildkite_status_paginated(
216+
builds_chunk, result_chunks, page_token = get_buildkite_status_paginated(
165217
f'first: 20, after: "{page_token}"'
166218
)
167-
result.extend(chunks)
168-
return result
219+
builds.extend(builds_chunk)
220+
result.extend(result_chunks)
221+
return builds, result
169222

170223

171-
def get_buildkite_status_paginated(page_command) -> List[BuildkiteStatus]:
224+
def get_buildkite_status_paginated(page_command):
172225
BUILDKITE_TOKEN = os.environ["BUILDKITE_TOKEN"]
173226
tries = 5
174227
for attempt in range(tries):
@@ -185,6 +238,10 @@ def get_buildkite_status_paginated(page_command) -> List[BuildkiteStatus]:
185238
}
186239
edges {
187240
node {
241+
createdAt
242+
startedAt
243+
finishedAt
244+
number
188245
jobs(first: 100) {
189246
edges {
190247
node {
@@ -198,6 +255,8 @@ def get_buildkite_status_paginated(page_command) -> List[BuildkiteStatus]:
198255
commit
199256
}
200257
createdAt
258+
runnableAt
259+
startedAt
201260
finishedAt
202261
artifacts(first: 100) {
203262
edges {
@@ -232,8 +291,11 @@ def get_buildkite_status_paginated(page_command) -> List[BuildkiteStatus]:
232291
page_cursor = resp.json()["data"]["pipeline"]["builds"]["pageInfo"]["endCursor"]
233292
builds = resp.json()["data"]["pipeline"]["builds"]["edges"]
234293
results = []
235-
exception_counter: int = 0
236-
for build in builds:
294+
295+
thread_pool = ThreadPoolExecutor(100)
296+
futures = []
297+
298+
for build in tqdm(builds):
237299
jobs = build["node"]["jobs"]["edges"]
238300
for job in jobs:
239301
actual_job = job["node"]
@@ -246,7 +308,7 @@ def get_buildkite_status_paginated(page_command) -> List[BuildkiteStatus]:
246308
state=actual_job["state"],
247309
url=actual_job["url"],
248310
commit=sha,
249-
created_at=actual_job["createdAt"],
311+
startedAt=actual_job["startedAt"],
250312
finished_at=actual_job["finishedAt"],
251313
)
252314
results.append(status)
@@ -260,8 +322,8 @@ def get_buildkite_status_paginated(page_command) -> List[BuildkiteStatus]:
260322
if not os.path.exists(on_disk_path):
261323
# Use the artifact link to download the logs. This might not work well
262324
# on slower internet because the link is presigned S3 url and only last 10min.
263-
try:
264-
resp = requests.get(url)
325+
def task(url, on_disk_path, actual_job):
326+
resp = requests.get(url, timeout=5)
265327
assert (
266328
resp.status_code == 200
267329
), f"failed to download {url} for {actual_job}: {resp.text}"
@@ -270,15 +332,17 @@ def get_buildkite_status_paginated(page_command) -> List[BuildkiteStatus]:
270332
os.makedirs(os.path.split(on_disk_path)[0], exist_ok=True)
271333
with open(on_disk_path, "wb") as f:
272334
f.write(resp.content)
273-
except Exception as e:
274-
traceback.print_exc()
275-
exception_counter += 1
276335

277-
if exception_counter > 100:
278-
assert (
279-
False
280-
), "More than 100 exception as occured when downloading Buldkite status."
281-
return results, page_cursor
336+
futures.append(
337+
thread_pool.submit(task, url, on_disk_path, actual_job)
338+
)
339+
wait(futures)
340+
exception_set = [fut for fut in futures if fut.exception()]
341+
342+
if len(exception_set) > 100:
343+
print("More than 100 exception as occured when downloading Buldkite status.")
344+
raise exception_set[0]
345+
return builds, results, page_cursor
282346

283347

284348
def download_files_given_prefix(prefix: str):
@@ -704,7 +768,9 @@ def main():
704768
print("Downloading Travis Status")
705769
travis_data = [get_travis_status(commit.sha) for commit in tqdm(commits)]
706770
print("Downloading Buildkite Status")
707-
buildkite_status = get_buildkite_status()
771+
raw_builds_result, buildkite_status = get_buildkite_status()
772+
with open("cached_buildkite.json", "w") as f:
773+
json.dump(raw_builds_result, f)
708774

709775
print("✍️ Writing Data")
710776
db = ResultsDB("./results.db")

0 commit comments

Comments
 (0)