github.com/mistwind/reviewdog@v0.0.0-20230322024206-9cfa11856d58/doghouse/server/github.go (about) 1 package server 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 8 "github.com/bradleyfalzon/ghinstallation/v2" 9 "github.com/google/go-github/v39/github" 10 ) 11 12 type NewGitHubClientOption struct { 13 // Required 14 PrivateKey []byte 15 // Required 16 IntegrationID int 17 18 // RepoOwner is required for installation API. 19 RepoOwner string 20 21 // Optional 22 Client *http.Client 23 } 24 25 func NewGitHubClient(ctx context.Context, opt *NewGitHubClientOption) (*github.Client, error) { 26 client := opt.Client 27 if client == nil { 28 client = http.DefaultClient 29 } 30 31 itr, err := githubAppTransport(ctx, client, opt) 32 if err != nil { 33 return nil, fmt.Errorf("failed to create gh transport: %w", err) 34 } 35 36 client.Transport = itr 37 return github.NewClient(client), nil 38 } 39 40 func githubAppTransport(ctx context.Context, client *http.Client, opt *NewGitHubClientOption) (http.RoundTripper, error) { 41 if opt.RepoOwner == "" { 42 return ghinstallation.NewAppsTransport(getTransport(client), int64(opt.IntegrationID), opt.PrivateKey) 43 } 44 installationID, err := findInstallationID(ctx, opt) 45 if err != nil { 46 return nil, err 47 } 48 return ghinstallation.New(getTransport(client), int64(opt.IntegrationID), installationID, opt.PrivateKey) 49 } 50 51 func getTransport(client *http.Client) http.RoundTripper { 52 if client.Transport != nil { 53 return client.Transport 54 } 55 return http.DefaultTransport 56 } 57 58 func findInstallationID(ctx context.Context, opt *NewGitHubClientOption) (int64, error) { 59 appCli, err := NewGitHubClient(ctx, &NewGitHubClientOption{ 60 PrivateKey: opt.PrivateKey, 61 IntegrationID: opt.IntegrationID, 62 Client: &http.Client{}, // Use different client to get installation. 63 // Do no set RepoOwner. 64 }) 65 if err != nil { 66 return 0, err 67 } 68 inst, _, err := appCli.Apps.FindUserInstallation(ctx, opt.RepoOwner) 69 if err != nil { 70 return 0, err 71 } 72 return inst.GetID(), nil 73 }