...
1 package githubclient
2
3 import (
4 "context"
5 "fmt"
6 "sync"
7 "time"
8
9 "github.com/google/go-github/v47/github"
10 )
11
12 type Client struct {
13 *github.Client
14 cfg Config
15 owner string
16 repo string
17 }
18
19
20 func (c *Client) ToString() string {
21 return fmt.Sprintf("org %s repo %s", c.owner, c.repo)
22 }
23
24 func (c *Client) Config() Config {
25 return c.cfg
26 }
27
28
29 func NewClient(cfg Config) (*Client, error) {
30 err := cfg.Validate()
31 if err != nil {
32 return nil, err
33 }
34
35 if cfg.AccessToken != "" {
36 hc, err := cfg.HTTPClient()
37 if err != nil {
38 return nil, err
39 }
40 client := github.NewClient(hc)
41 owner := cfg.Owner()
42 repo := cfg.Repo()
43 return &Client{client, cfg, owner, repo}, nil
44 }
45
46 if cfg.InstallationID == 0 {
47 cfg.InstallationID, err = getInstallationID(cfg)
48 if err != nil {
49 return nil, err
50 }
51 }
52 fmt.Printf("cfg %+v \n", cfg.InstallationID)
53
54 hc, err := cfg.HTTPClient()
55 if err != nil {
56 return nil, err
57 }
58
59 client := github.NewClient(hc)
60 owner := cfg.Owner()
61 repo := cfg.Repo()
62 return &Client{client, cfg, owner, repo}, nil
63 }
64
65
66
67
68
69
70
71 var installationIDCache = struct {
72 sync.Mutex
73 c map[string]int64
74 }{
75 c: make(map[string]int64),
76 }
77
78 func setInstallationIDCache(repository string, id int64) {
79 installationIDCache.Lock()
80 installationIDCache.c[repository] = id
81 installationIDCache.Unlock()
82 }
83
84 func getInstallationIDCache(repository string) (id int64, found bool) {
85 installationIDCache.Lock()
86 id, found = installationIDCache.c[repository]
87 installationIDCache.Unlock()
88 return
89 }
90
91
92
93
94
95
96
97
98
99 func getInstallationID(cfg Config) (int64, error) {
100 if cfg.InstallationID != 0 {
101 return 0, fmt.Errorf("InstallationID not zero. Got: %d", cfg.InstallationID)
102 }
103
104 if cached, found := getInstallationIDCache(cfg.Repository); found {
105 return cached, nil
106 }
107 hc, err := cfg.HTTPClient()
108 if err != nil {
109 return 0, err
110 }
111 ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
112 defer cancel()
113
114 apps := github.NewClient(hc).Apps
115 installation, _, err := apps.FindRepositoryInstallation(ctx, cfg.Owner(), cfg.Repo())
116 if err != nil {
117 return 0, err
118 }
119 id := installation.GetID()
120 if id <= 0 {
121 return 0, fmt.Errorf("InstallationID less than or equal to 0 means installation does not exist for owner/repo. Got %d", id)
122 }
123 setInstallationIDCache(cfg.Repository, id)
124 return id, nil
125 }
126
View as plain text