about summary refs log tree commit diff
path: root/cmd/ghabilling/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/ghabilling/main.go')
-rw-r--r--cmd/ghabilling/main.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/cmd/ghabilling/main.go b/cmd/ghabilling/main.go
new file mode 100644
index 0000000..bb5f41a
--- /dev/null
+++ b/cmd/ghabilling/main.go
@@ -0,0 +1,91 @@
+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")
+	}
+
+	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))
+}