github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/releaser/github.go (about)

     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 interface{}) 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  }