xref: /llvm-project/llvm/utils/count_running_jobs.py (revision 9c6df7d90a74c3b98e33d3edf0b5d8982093b4f7)
1# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2# See https://llvm.org/LICENSE.txt for license information.
3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4"""Tool for counting the number of currently running Github actions jobs.
5
6This tool counts and enumerates the currently active jobs in Github actions
7for the monorepo.
8
9python3 ./count_running_jobs.py --token=<github token>
10
11Note that the token argument is optional. If it is not specified, the queries
12will be performed unauthenticated.
13"""
14
15import argparse
16import github
17import sys
18import time
19
20
21def main(token, filter_gha_runners):
22    workflows = (
23        github.Github(args.token)
24        .get_repo("llvm/llvm-project")
25        .get_workflow_runs(status="in_progress")
26    )
27
28    in_progress_jobs = 0
29
30    for workflow in workflows:
31        for job in workflow.jobs():
32            if job.status == "in_progress":
33                # TODO(boomanaiden154): Remove the try/except block once we are able
34                # to pull in a PyGithub release that has the runner_group_name property
35                # for workflow jobs.
36                try:
37                    if filter_gha_runners and job.runner_group_name != "GitHub Actions":
38                        continue
39                except:
40                    print(
41                        "Failed to filter runners. Your PyGithub version is "
42                        "most likely too old."
43                    )
44                print(f"{workflow.name}/{job.name}")
45                in_progress_jobs += 1
46
47    print(f"\nFound {in_progress_jobs} running jobs.")
48
49    return in_progress_jobs
50
51
52if __name__ == "__main__":
53    parser = argparse.ArgumentParser(
54        description="A tool for listing and counting Github actions jobs"
55    )
56    parser.add_argument(
57        "--token",
58        type=str,
59        help="The Github token to use to authorize with the API",
60        default=None,
61        nargs="?",
62    )
63    parser.add_argument(
64        "--output-file",
65        type=str,
66        help="The output file to write time-series data to",
67        default=None,
68        nargs="?",
69    )
70    parser.add_argument(
71        "--data-collection-interval",
72        type=int,
73        help="The number of seconds between data collection intervals",
74        default=None,
75        nargs="?",
76    )
77    parser.add_argument(
78        "--filter-gha-runners",
79        help="Only consider jobs running on hosted Github actions runners",
80        action="store_true",
81    )
82    parser.add_argument(
83        "--no-filter-gha-runners",
84        dest="filter_gha_runners",
85        action="store_false",
86        help="Consider all running jobs",
87    )
88    parser.set_defaults(filter_gha_runners=False)
89    args = parser.parse_args()
90
91    # Perform some basic argument validation
92
93    # If an output file is specified, the user must also specify the data
94    # collection interval.
95    if bool(args.output_file) and not bool(args.data_collection_interval):
96        print("A data collection interval must be specified when --output_file is used")
97        sys.exit(1)
98
99    if args.data_collection_interval:
100        while True:
101            current_time = time.localtime()
102            current_time_string = time.strftime("%Y/%m/%d %H:%M:%S", current_time)
103
104            print(f"Collecting data at {current_time_string}")
105
106            current_job_count = main(args.token, args.filter_gha_runners)
107
108            if args.output_file:
109                with open(args.output_file, "a") as output_file_handle:
110                    output_file_handle.write(
111                        f"{current_time_string},{current_job_count}\n"
112                    )
113
114            time.sleep(args.data_collection_interval)
115    else:
116        main(args.token, args.filter_gha_runners)
117