-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
142 lines (115 loc) · 3.17 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main
import (
"context"
"flag"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/bradleyfalzon/ghinstallation/v2"
"github.com/google/go-github/v64/github"
"github.com/k0kubun/pp/v3"
)
var (
version = "dev"
commit = "none"
date = "unknown"
)
func versionInfo() {
fmt.Fprintf(os.Stderr, "Version: %s\nCommit: %s\nBuiltAt: %s\n", version, commit, date)
}
func main() {
appID := flag.Int64("app-id", 0, "App ID")
instID := flag.Int64("inst-id", 0, "Installation ID")
export := flag.Bool("export", false, "show token as 'export GITHUB_TOKEN=...'")
showVersion := flag.Bool("version", false, "show version info")
showInsts := flag.Bool("show-insts", false, "show all of the installations for the app")
githubURL := flag.String("url", "https://api.github.com", "specify the base URL for Github API, for use with Github Enterprise. Example: 'https://github.example.com/api/v3'")
origUsage := flag.Usage
flag.Usage = func() {
origUsage()
fmt.Fprintf(os.Stderr, "\n")
fmt.Fprintf(os.Stderr, "== Build Info ==\n")
versionInfo()
}
flag.Parse()
// See https://github.com/golang/go/issues/37533
// I decided to implement -version flag to return 0
if *showVersion {
flag.Usage()
os.Exit(0)
}
key := os.Getenv("GITHUB_PRIV_KEY")
if key == "" {
log.Fatal("Please populate GITHUB_PRIV_KEY environment variable with the private key for the App")
}
if *showInsts {
if *appID == 0 {
fmt.Fprintf(os.Stderr, "App ID is required to show the installations for the app.\n\n")
flag.Usage()
os.Exit(1)
}
showInstallations(*appID, []byte(key), *githubURL)
return
}
if *appID == 0 || *instID == 0 {
fmt.Fprintf(os.Stderr, "App ID and Installation ID are required.\n\n")
flag.Usage()
os.Exit(1)
}
// Wrap the shared transport for use with the app ID 1 authenticating with installation ID 99.
itr, err := ghinstallation.New(http.DefaultTransport, *appID, *instID, []byte(key))
if err != nil {
log.Fatal(err)
}
if githubURL != nil && *githubURL != "" {
itr.BaseURL = *githubURL
}
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
token, err := itr.Token(ctx)
if err != nil {
log.Fatalf("unable to get github token: %s", err)
}
if *export {
showExport(token)
} else {
fmt.Println(token)
}
}
func showExport(token string) {
fmt.Printf("export GITHUB_TOKEN=%s\n", token)
}
func showInstallations(appID int64, key []byte, githubURL string) {
atr, err := ghinstallation.NewAppsTransport(http.DefaultTransport, appID, key)
if err != nil {
log.Fatal(err)
}
var client *github.Client
if githubURL != "" {
atr.BaseURL = githubURL
client, err = github.NewEnterpriseClient(githubURL, githubURL, &http.Client{Transport: atr})
if err != nil {
log.Fatalf("failed creating enterprise client: %v", err)
}
} else {
client = github.NewClient(&http.Client{Transport: atr})
}
opts := &github.ListOptions{
PerPage: 10,
}
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
for {
inst, resp, err := client.Apps.ListInstallations(ctx, opts)
if err != nil {
log.Fatal(err)
}
pp.Println(inst)
if resp.NextPage == 0 {
break
}
opts.Page = resp.NextPage
}
}