hugo/releaser/github.go

144 lines
3.1 KiB
Go

package releaser
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
)
var (
gitHubCommitsAPI = "https://api.github.com/repos/gohugoio/REPO/commits/%s"
gitHubRepoAPI = "https://api.github.com/repos/gohugoio/REPO"
gitHubContributorsAPI = "https://api.github.com/repos/gohugoio/REPO/contributors"
)
type gitHubAPI struct {
commitsAPITemplate string
repoAPI string
contributorsAPITemplate string
}
func newGitHubAPI(repo string) *gitHubAPI {
return &gitHubAPI{
commitsAPITemplate: strings.Replace(gitHubCommitsAPI, "REPO", repo, -1),
repoAPI: strings.Replace(gitHubRepoAPI, "REPO", repo, -1),
contributorsAPITemplate: strings.Replace(gitHubContributorsAPI, "REPO", repo, -1),
}
}
type gitHubCommit struct {
Author gitHubAuthor `json:"author"`
HTMLURL string `json:"html_url"`
}
type gitHubAuthor struct {
ID int `json:"id"`
Login string `json:"login"`
HTMLURL string `json:"html_url"`
AvatarURL string `json:"avatar_url"`
}
type gitHubRepo struct {
ID int `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
HTMLURL string `json:"html_url"`
Stars int `json:"stargazers_count"`
Contributors []gitHubContributor
}
type gitHubContributor struct {
ID int `json:"id"`
Login string `json:"login"`
HTMLURL string `json:"html_url"`
Contributions int `json:"contributions"`
}
func (g *gitHubAPI) fetchCommit(ref string) (gitHubCommit, error) {
var commit gitHubCommit
u := fmt.Sprintf(g.commitsAPITemplate, ref)
req, err := http.NewRequest("GET", u, nil)
if err != nil {
return commit, err
}
err = doGitHubRequest(req, &commit)
return commit, err
}
func (g *gitHubAPI) fetchRepo() (gitHubRepo, error) {
var repo gitHubRepo
req, err := http.NewRequest("GET", g.repoAPI, nil)
if err != nil {
return repo, err
}
err = doGitHubRequest(req, &repo)
if err != nil {
return repo, err
}
var contributors []gitHubContributor
page := 0
for {
page++
var currPage []gitHubContributor
url := fmt.Sprintf(g.contributorsAPITemplate+"?page=%d", page)
req, err = http.NewRequest("GET", url, nil)
if err != nil {
return repo, err
}
err = doGitHubRequest(req, &currPage)
if err != nil {
return repo, err
}
if len(currPage) == 0 {
break
}
contributors = append(contributors, currPage...)
}
repo.Contributors = contributors
return repo, err
}
func doGitHubRequest(req *http.Request, v interface{}) error {
addGitHubToken(req)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if isError(resp) {
b, _ := ioutil.ReadAll(resp.Body)
return fmt.Errorf("GitHub lookup failed: %s", string(b))
}
return json.NewDecoder(resp.Body).Decode(v)
}
func isError(resp *http.Response) bool {
return resp.StatusCode < 200 || resp.StatusCode > 299
}
func addGitHubToken(req *http.Request) {
gitHubToken := os.Getenv("GITHUB_TOKEN")
if gitHubToken != "" {
req.Header.Add("Authorization", "token "+gitHubToken)
}
}