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