GitHub Actionsの利用量はsettings/billingから確認できます。
それはいいんですが、問題は今月分しか確認できないこと!
「先月は〇〇分使ったから上限いくらに設定しておくか〜〜」ということができません。 APIは見つけたので、取得スクリプトを組んでみました。
集計スクリプト
GitHub REST APIをたたいて、結果をGoogle Spreadsheetにまとめます。 GitHub REST APIを叩く部分はGitHub CLIを使えばすぐにできるんですが、 Google Spreadsheetへの書き込みをシェルスクリプトで組むのはちょっと大変です。
今回はGoで書いてみました。
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"google.golang.org/api/sheets/v4"
)
func main() {
ctx := context.Background()
token := os.Getenv("GITHUB_TOKEN")
if token == "" {
log.Fatal("GITHUB_TOKEN is required")
}
sheetID := os.Getenv("SHEET_ID")
if sheetID == "" {
log.Fatal("SHEET_ID is required")
}
org := os.Getenv("GITHUB_REPOSITORY_OWNER")
if org == "" {
log.Fatal("GITHUB_REPOSITORY_OWNER is required")
}
now := time.Now()
usage, err := GetGitHubActionsBilling(ctx, token, org)
if err != nil {
log.Fatal(err)
}
svc, err := sheets.NewService(ctx)
if err != nil {
log.Fatal(err)
}
tableRange := "report!A1"
var reportData sheets.ValueRange
reportData.Values = append(reportData.Values, []any{
now,
usage.TotalMinutesUsed,
usage.TotalPaidMinutesUsed,
usage.IncludedMinutes,
usage.MinutesUsedBreakdown["UBUNTU"],
usage.MinutesUsedBreakdown["MACOS"],
usage.MinutesUsedBreakdown["WINDOWS"],
})
_, err = svc.Spreadsheets.Values.Append(sheetID, tableRange, &reportData).
ValueInputOption("USER_ENTERED").
InsertDataOption("INSERT_ROWS").
Context(ctx).
Do()
if err != nil {
log.Fatal(err)
}
}
type GitHubActionsBilling struct {
TotalMinutesUsed float64 `json:"total_minutes_used"`
TotalPaidMinutesUsed float64 `json:"total_paid_minutes_used"`
IncludedMinutes float64 `json:"included_minutes"`
MinutesUsedBreakdown map[string]float64 `json:"minutes_used_breakdown"`
}
func GetGitHubActionsBilling(ctx context.Context, token, org string) (*GitHubActionsBilling, error) {
// build the request
u := "https://api.github.com/orgs/" + org + "/settings/billing/actions"
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil)
if err != nil {
return nil, err
}
req.Header.Set("Accept", "application/vnd.github+json")
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("X-GitHub-Api-Version", "2022-11-28")
// send the request
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}
// parse the response
data, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var usage *GitHubActionsBilling
if err := json.Unmarshal(data, &usage); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
return usage, nil
}
認証設定
実行にはGitHubとGoogleへの認証情報が必要です。
GitHubはsettings/tokensからPAT(Personal access token)を取得し、 環境変数に設定します。
export GITHUB_TOKEN=YOUR_GITHUB_TOKEN
Googleはgcloud
コマンドを使います。
デフォルトの権限ではスプレッドシートへの書き込みができないので、スプレッドシートを書き込み権限をスコープに追加してログインします。
gcloud auth application-default login \
--scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/spreadsheets
実行
他の必要なパラメーターは環境変数で設定します。
export SHEET_ID=hogehoge
export GITHUB_REPOSITORY_OWNER=org
go run main.go
あとでGitHub Actionsで自動化することを想定して、オーガニゼーション名はGITHUB_REPOSITORY_OWNER
から取得するようにしました。
実際にGitHub Actionsを使って動かすのはまた今度。
まとめ
GitHub Actionsの利用量を記録するスクリプトを書きました。
ここまで書いたところでGitHub public roadmapに載っているのでは?と思ったら、 なんかそれっぽいのがありました。
予定では「Q2 2023 – Apr-Jun」とありますが、最初公開されたときの予定はQ4 2021 – Oct-Dec。 そしてこの文章を書いているのは2023-06-22。 さて、僕のスクリプトが動き出すのとどっちが早いでしょう・・・?