aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/ghabilling/README.md15
-rw-r--r--cmd/ghabilling/main.go92
-rw-r--r--pyproject.toml1
-rw-r--r--src/cli/gha_billing.py44
4 files changed, 45 insertions, 107 deletions
diff --git a/cmd/ghabilling/README.md b/cmd/ghabilling/README.md
deleted file mode 100644
index 2aa08ce..0000000
--- a/cmd/ghabilling/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# `gha-billing`
-
-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)
-
-## usage
-
-```sh
-➜ world git:(main) ✗ go run ./cmd/ghabilling -t github_pat_<TOKEN>
-this cycle, 14 minutes have been used, and 1986 minutes are remaining
-```
diff --git a/cmd/ghabilling/main.go b/cmd/ghabilling/main.go
deleted file mode 100644
index 4865a4a..0000000
--- a/cmd/ghabilling/main.go
+++ /dev/null
@@ -1,92 +0,0 @@
-package main
-
-import (
- "context"
- "encoding/json"
- "flag"
- "fmt"
- "net/http"
- "os"
- "time"
-
- "github.com/fcuny/world/internal/version"
-)
-
-const API_URL = "https://api.github.com"
-
-const usage = `Usage:
- gha-billing -t [TOKEN]
-
-Options:
- -t, --token GitHub API's token
- -v, --version Print version information
- -h, --help Print this message
-`
-
-// https://docs.github.com/en/rest/billing/billing?apiVersion=2022-11-28#get-github-actions-billing-for-an-organization
-type githubActionBilling struct {
- TotalMinutesUsed float64 `json:"total_minutes_used"`
- TotalPaidMinutesUsed float64 `json:"total_paid_minutes_used"`
- IncludedMinutes float64 `json:"included_minutes"`
- MinutesUsedBreakdown map[string]int `json:"minutes_used_breakdown"`
-}
-
-func main() {
- flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) }
-
- var (
- tokenFlag string
- userFlag string
- versionFlag bool
- )
-
- flag.StringVar(&tokenFlag, "token", "", "GitHub API token")
- flag.StringVar(&tokenFlag, "t", "", "GitHub API token")
- flag.StringVar(&userFlag, "user", "fcuny", "GitHub API token")
- flag.StringVar(&userFlag, "u", "fcuny", "GitHub API token")
- flag.BoolVar(&versionFlag, "version", false, "Print version information")
- flag.BoolVar(&versionFlag, "v", false, "Print version information")
-
- flag.Parse()
-
- if versionFlag {
- information := version.VersionAndBuildInfo()
- fmt.Println(information)
- return
- }
-
- if tokenFlag == "" {
- fmt.Fprintf(os.Stderr, "The API token is not set\n")
- os.Exit(1)
- }
-
- ctx := context.TODO()
-
- url := fmt.Sprintf("%s/users/%s/settings/billing/actions", API_URL, userFlag)
- req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
- if err != nil {
- fmt.Fprintf(os.Stderr, "could not create a request: %v\n", err)
- os.Exit(1)
- }
- req.Header.Set("Authorization", fmt.Sprintf("token %s", tokenFlag))
- req.Header.Set("Accept", "application/vnd.github.v3+json")
-
- client := http.Client{
- Timeout: 30 * time.Second,
- }
-
- res, err := client.Do(req)
- if err != nil {
- fmt.Fprintf(os.Stderr, "error making http request: %s\n", err)
- os.Exit(1)
- }
-
- var b githubActionBilling
- if err := json.NewDecoder(res.Body).Decode(&b); err != nil {
- fmt.Fprintf(os.Stderr, "error parsing the JSON response: %v\n", err)
- os.Exit(1)
- }
-
- timeRemaining := b.IncludedMinutes - b.TotalMinutesUsed
- fmt.Printf("this cycle, %d minutes have been used, and %d minutes are remaining\n", int(b.TotalMinutesUsed), int(timeRemaining))
-}
diff --git a/pyproject.toml b/pyproject.toml
index 4400828..e0ff2f4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -65,6 +65,7 @@ combine-as-imports = true
known-first-party = ["rbx_nomad"]
[project.scripts]
+gha_billing = "cli.gha_billing:cli"
hashi_env = "cli.hash_env:cli"
int2ip = "cli.ipconverter:int2ip"
ip2int = "cli.ipconverter:ip2int"
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()