github.go (3128B)
1 package releaser 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "os" 9 "strings" 10 ) 11 12 var ( 13 gitHubCommitsAPI = "https://api.github.com/repos/gohugoio/REPO/commits/%s" 14 gitHubRepoAPI = "https://api.github.com/repos/gohugoio/REPO" 15 gitHubContributorsAPI = "https://api.github.com/repos/gohugoio/REPO/contributors" 16 ) 17 18 type gitHubAPI struct { 19 commitsAPITemplate string 20 repoAPI string 21 contributorsAPITemplate string 22 } 23 24 func newGitHubAPI(repo string) *gitHubAPI { 25 return &gitHubAPI{ 26 commitsAPITemplate: strings.Replace(gitHubCommitsAPI, "REPO", repo, -1), 27 repoAPI: strings.Replace(gitHubRepoAPI, "REPO", repo, -1), 28 contributorsAPITemplate: strings.Replace(gitHubContributorsAPI, "REPO", repo, -1), 29 } 30 } 31 32 type gitHubCommit struct { 33 Author gitHubAuthor `json:"author"` 34 HTMLURL string `json:"html_url"` 35 } 36 37 type gitHubAuthor struct { 38 ID int `json:"id"` 39 Login string `json:"login"` 40 HTMLURL string `json:"html_url"` 41 AvatarURL string `json:"avatar_url"` 42 } 43 44 type gitHubRepo struct { 45 ID int `json:"id"` 46 Name string `json:"name"` 47 Description string `json:"description"` 48 HTMLURL string `json:"html_url"` 49 Stars int `json:"stargazers_count"` 50 Contributors []gitHubContributor 51 } 52 53 type gitHubContributor struct { 54 ID int `json:"id"` 55 Login string `json:"login"` 56 HTMLURL string `json:"html_url"` 57 Contributions int `json:"contributions"` 58 } 59 60 func (g *gitHubAPI) fetchCommit(ref string) (gitHubCommit, error) { 61 var commit gitHubCommit 62 63 u := fmt.Sprintf(g.commitsAPITemplate, ref) 64 65 req, err := http.NewRequest("GET", u, nil) 66 if err != nil { 67 return commit, err 68 } 69 70 err = doGitHubRequest(req, &commit) 71 72 return commit, err 73 } 74 75 func (g *gitHubAPI) fetchRepo() (gitHubRepo, error) { 76 var repo gitHubRepo 77 78 req, err := http.NewRequest("GET", g.repoAPI, nil) 79 if err != nil { 80 return repo, err 81 } 82 83 err = doGitHubRequest(req, &repo) 84 if err != nil { 85 return repo, err 86 } 87 88 var contributors []gitHubContributor 89 page := 0 90 for { 91 page++ 92 var currPage []gitHubContributor 93 url := fmt.Sprintf(g.contributorsAPITemplate+"?page=%d", page) 94 95 req, err = http.NewRequest("GET", url, nil) 96 if err != nil { 97 return repo, err 98 } 99 100 err = doGitHubRequest(req, &currPage) 101 if err != nil { 102 return repo, err 103 } 104 if len(currPage) == 0 { 105 break 106 } 107 108 contributors = append(contributors, currPage...) 109 110 } 111 112 repo.Contributors = contributors 113 114 return repo, err 115 } 116 117 func doGitHubRequest(req *http.Request, v any) error { 118 addGitHubToken(req) 119 120 resp, err := http.DefaultClient.Do(req) 121 if err != nil { 122 return err 123 } 124 defer resp.Body.Close() 125 126 if isError(resp) { 127 b, _ := ioutil.ReadAll(resp.Body) 128 return fmt.Errorf("GitHub lookup failed: %s", string(b)) 129 } 130 131 return json.NewDecoder(resp.Body).Decode(v) 132 } 133 134 func isError(resp *http.Response) bool { 135 return resp.StatusCode < 200 || resp.StatusCode > 299 136 } 137 138 func addGitHubToken(req *http.Request) { 139 gitHubToken := os.Getenv("GITHUB_TOKEN") 140 if gitHubToken != "" { 141 req.Header.Add("Authorization", "token "+gitHubToken) 142 } 143 }