about summary refs log tree commit diff
path: root/src/cli/gha_billing.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/gha_billing.py')
-rw-r--r--src/cli/gha_billing.py44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/cli/gha_billing.py b/src/cli/gha_billing.py
new file mode 100644
index 0000000..00dd5e3
--- /dev/null
+++ b/src/cli/gha_billing.py
@@ -0,0 +1,44 @@
+"""
+Print information about how many free minutes of GitHub actions are left for this cycle.
+
+The API for this is documented [here](https://docs.github.com/en/rest/billing/billing?apiVersion=2022-11-28#get-github-actions-billing-for-an-organization).
+
+For this you need a [token](https://github.com/settings/personal-access-tokens) with the following permissions:
+- [plan](https://docs.github.com/en/rest/authentication/permissions-required-for-fine-grained-personal-access-tokens?apiVersion=2022-11-28#user-permissions-for-plan)
+"""
+import sys
+
+import click
+import requests
+
+API_URL = "https://api.github.com"
+
+
+@click.command()
+@click.option("-t", "--token", required=True, help="GitHub API token")
+@click.option("-u", "--user", default="fcuny", help="GitHub username")
+def cli(token, user):
+    # https://docs.github.com/en/rest/billing/billing?apiVersion=2022-11-28#get-github-actions-billing-for-an-organization
+    url = f"{API_URL}/users/{user}/settings/billing/actions"
+    headers = {"Authorization": f"token {token}", "Accept": "application/vnd.github.v3+json"}
+    try:
+        response = requests.get(url, headers=headers, timeout=30)
+        response.raise_for_status()
+    except requests.exceptions.RequestException as err:
+        click.echo(f"Error making HTTP request: {err}", err=True)
+        sys.exit(1)
+
+    try:
+        billing_info = response.json()
+    except ValueError as err:
+        click.echo(f"Error parsing the JSON response: {err}", err=True)
+        sys.exit(1)
+
+    time_remaining = billing_info["included_minutes"] - billing_info["total_minutes_used"]
+    click.echo(
+        f"This cycle, {int(billing_info['total_minutes_used'])} minutes have been used, and {int(time_remaining)} minutes are remaining"
+    )
+
+
+if __name__ == "__main__":
+    cli()