# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""Tool for counting the number of currently running Github actions jobs.
This tool counts and enumerates the currently active jobs in Github actions
for the monorepo.
python3 ./count_running_jobs.py --token=<github token>
Note that the token argument is optional. If it is not specified, the queries
will be performed unauthenticated.
"""
import argparse
import github
import sys
import time
def main(token, filter_gha_runners):
workflows = (
github.Github(args.token)
.get_repo("llvm/llvm-project")
.get_workflow_runs(status="in_progress")
)
in_progress_jobs = 0
for workflow in workflows:
for job in workflow.jobs():
if job.status == "in_progress":
# TODO(boomanaiden154): Remove the try/except block once we are able
# to pull in a PyGithub release that has the runner_group_name property
# for workflow jobs.
try:
if filter_gha_runners and job.runner_group_name != "GitHub Actions":
continue
except:
print(
"Failed to filter runners. Your PyGithub version is "
"most likely too old."
)
print(f"{workflow.name}/{job.name}")
in_progress_jobs += 1
print(f"\nFound {in_progress_jobs} running jobs.")
return in_progress_jobs
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="A tool for listing and counting Github actions jobs"
)
parser.add_argument(
"--token",
type=str,
help="The Github token to use to authorize with the API",
default=None,
nargs="?",
)
parser.add_argument(
"--output-file",
type=str,
help="The output file to write time-series data to",
default=None,
nargs="?",
)
parser.add_argument(
"--data-collection-interval",
type=int,
help="The number of seconds between data collection intervals",
default=None,
nargs="?",
)
parser.add_argument(
"--filter-gha-runners",
help="Only consider jobs running on hosted Github actions runners",
action="store_true",
)
parser.add_argument(
"--no-filter-gha-runners",
dest="filter_gha_runners",
action="store_false",
help="Consider all running jobs",
)
parser.set_defaults(filter_gha_runners=False)
args = parser.parse_args()
# Perform some basic argument validation
# If an output file is specified, the user must also specify the data
# collection interval.
if bool(args.output_file) and not bool(args.data_collection_interval):
print("A data collection interval must be specified when --output_file is used")
sys.exit(1)
if args.data_collection_interval:
while True:
current_time = time.localtime()
current_time_string = time.strftime("%Y/%m/%d %H:%M:%S", current_time)
print(f"Collecting data at {current_time_string}")
current_job_count = main(args.token, args.filter_gha_runners)
if args.output_file:
with open(args.output_file, "a") as output_file_handle:
output_file_handle.write(
f"{current_time_string},{current_job_count}\n"
)
time.sleep(args.data_collection_interval)
else:
main(args.token, args.filter_gha_runners)