Harrison Mutai | 0e9964e | 2024-06-14 09:51:42 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | import re |
| 4 | from dataclasses import dataclass |
| 5 | |
| 6 | import requests |
| 7 | |
Boyan Karatotev | 12cd590 | 2025-06-25 09:22:46 +0100 | [diff] [blame^] | 8 | openci_url = "https://ci.trustedfirmware.org/" |
Harrison Mutai | 0e9964e | 2024-06-14 09:51:42 +0100 | [diff] [blame] | 9 | |
| 10 | |
| 11 | class Job: |
| 12 | |
| 13 | def __init__(self, name: str, response: dict, get_sub_jobs=False) -> None: |
| 14 | self.name = name |
| 15 | self.url = ( |
| 16 | response["url"] |
| 17 | if openci_url in response["url"] |
| 18 | else openci_url + response["url"] |
| 19 | ) |
| 20 | self.number = ( |
| 21 | response["buildNumber"] if "buildNumber" in response else response["number"] |
| 22 | ) |
| 23 | |
| 24 | if "result" in response: |
| 25 | self.passed = response["result"].lower() == "success" |
| 26 | |
| 27 | if get_sub_jobs and not "subBuilds" in response: |
| 28 | console = requests.get(self.url + "consoleText").text |
| 29 | self.set_sub_jobs(SubJob.get_jobs_from_console_log(console)) |
| 30 | elif "subBuilds" in response: |
| 31 | self.set_sub_jobs( |
| 32 | list(map(lambda j: SubJob(j["jobAlias"], j), response["subBuilds"])) |
| 33 | ) |
| 34 | else: |
| 35 | self.jobs = [] |
| 36 | |
| 37 | def __str__(self) -> str: |
Boyan Karatotev | 12cd590 | 2025-06-25 09:22:46 +0100 | [diff] [blame^] | 38 | return f"{'✅' if self.passed else '❌'} *{self.name}* [#{self.number}]({self.url})" |
Harrison Mutai | 0e9964e | 2024-06-14 09:51:42 +0100 | [diff] [blame] | 39 | |
| 40 | def __iter__(self): |
| 41 | yield from self.jobs |
| 42 | |
| 43 | def failed_sub_jobs(self): |
| 44 | return list(filter(lambda j: not j.passed, self.jobs)) |
| 45 | |
| 46 | def print_failed_subjobs(self): |
| 47 | for j in self.failed_sub_jobs(): |
| 48 | print(" " * 2, j) |
| 49 | |
| 50 | def set_sub_jobs(self, jobs): |
| 51 | self.jobs = jobs |
| 52 | self.passed = not self.failed_sub_jobs() |
| 53 | |
| 54 | |
| 55 | class SubJob(Job): |
Harrison Mutai | 0e9964e | 2024-06-14 09:51:42 +0100 | [diff] [blame] | 56 | @classmethod |
| 57 | def get_jobs_from_console_log(cls, log): |
| 58 | sub_jobs = [] |
| 59 | |
| 60 | for name, num in re.findall(r"(tf-a[-\w+]+) #(\d+) started", log): |
| 61 | response = requests.get(openci_url + f"job/{name}/{num}/api/json").json() |
| 62 | sub_jobs.append(cls(name, response, get_sub_jobs=False)) |
| 63 | return sub_jobs |
| 64 | |
| 65 | |
| 66 | def main(): |
| 67 | job_urls = map( |
| 68 | lambda j: openci_url + f"job/{j}/api/json", ["tf-a-daily", "tf-a-tftf-main"] |
| 69 | ) |
| 70 | |
| 71 | jobs = list( |
| 72 | map( |
| 73 | lambda r: Job(r["displayName"], r["lastCompletedBuild"], get_sub_jobs=True), |
| 74 | map(lambda j: requests.get(j).json(), job_urls), |
| 75 | ) |
| 76 | ) |
| 77 | |
| 78 | print("🟢" if all(j.passed for j in jobs) else "🔴", "Daily Status") |
| 79 | |
| 80 | for j in jobs: |
Boyan Karatotev | 12cd590 | 2025-06-25 09:22:46 +0100 | [diff] [blame^] | 81 | print("*", j) |
| 82 | if j.name == "tf-a-daily": |
Harrison Mutai | 0e9964e | 2024-06-14 09:51:42 +0100 | [diff] [blame] | 83 | for subjob in j: |
Boyan Karatotev | 12cd590 | 2025-06-25 09:22:46 +0100 | [diff] [blame^] | 84 | print(" *", subjob) |
| 85 | elif not j.passed: |
| 86 | for subjob in j: |
| 87 | if not subjob.passed: |
| 88 | print(" *", subjob) |
Harrison Mutai | 0e9964e | 2024-06-14 09:51:42 +0100 | [diff] [blame] | 89 | |
| 90 | |
| 91 | if __name__ == "__main__": |
| 92 | main() |