...
1 package githubclient
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7 "regexp"
8 "time"
9
10 "go.uber.org/multierr"
11 "golang.org/x/oauth2"
12
13 "github.com/bradleyfalzon/ghinstallation/v2"
14 )
15
16 type Config struct {
17
18 Repository string
19
20
21 PrivateKey []byte
22 AppID int64
23 InstallationID int64
24
25 AccessToken string
26 }
27
28 var (
29 errEmptyRepositoryError = fmt.Errorf("Repository must be provided")
30 errInvalidRepositoryError = fmt.Errorf("Invalid repository URL")
31 errEmptyKeyError = fmt.Errorf("PrivateKey or AccessToken must be set")
32 errEmptyAppIDError = fmt.Errorf("AppID must be greater than zero")
33 )
34
35
36 var reValidRepository = regexp.MustCompile("^https://github.com/[^/]+/[^/]+([.]git)?$")
37
38 var (
39
40 reGithubOwner = regexp.MustCompile(`^https://github.com/|/[^/]*$`)
41
42 reGithubRepo = regexp.MustCompile(`^.*/|[.]git$`)
43 )
44
45
46 func (c *Config) Owner() string {
47 return reGithubOwner.ReplaceAllString(c.Repository, "")
48 }
49
50
51 func (c *Config) Repo() string {
52 return reGithubRepo.ReplaceAllString(c.Repository, "")
53 }
54
55
56 func (c *Config) Validate() error {
57 var errs []error
58 if c.AccessToken != "" {
59 return nil
60 }
61 if c.PrivateKey == nil && c.AccessToken == "" {
62 errs = append(errs, errEmptyKeyError)
63 }
64 if c.AppID <= 0 {
65 errs = append(errs, errEmptyAppIDError)
66 }
67 if c.Repository == "" {
68 errs = append(errs, errEmptyRepositoryError)
69 }
70 if !reValidRepository.MatchString(c.Repository) {
71 errs = append(errs, errInvalidRepositoryError)
72 }
73 return multierr.Combine(errs...)
74 }
75
76 func (c *Config) HTTPClient() (*http.Client, error) {
77 if err := c.Validate(); err != nil {
78 return nil, err
79 }
80
81 if c.AccessToken != "" {
82 return oauth2.NewClient(context.Background(), oauth2.StaticTokenSource(
83 &oauth2.Token{AccessToken: c.AccessToken},
84 )), nil
85 }
86
87 transport := http.DefaultTransport
88 const timeout = 5 * time.Minute
89
90 if c.InstallationID == 0 {
91
92 tr, err := ghinstallation.NewAppsTransport(transport, c.AppID, c.PrivateKey)
93 if err != nil {
94 return nil, err
95 }
96 return &http.Client{
97 Transport: tr,
98 Timeout: timeout,
99 }, nil
100 }
101 tr, err := ghinstallation.New(transport, c.AppID, c.InstallationID, c.PrivateKey)
102 if err != nil {
103 return nil, err
104 }
105 return &http.Client{
106 Transport: tr,
107 Timeout: timeout,
108 }, nil
109 }
110
View as plain text