かなで技術日誌

プログラミングやエンジニアリング周りについて

主なアウトプットはScrapboxObsidianにまとめてます。

GolangでGitHubのrepositoryのcommitを取得する

実現方法

GitHubのPersonal Access Tokenを発行する

Repository accessはprivate repositoryまで取得するならAll repositoryを選択するかOnly select repositoryで直接指定してください。

PermissionsContentsread-onlyに変更して発行してください。

Contentsをread-onlyに変更する
commitを取得するGitHub Personal Access Tokenの設定項目

実装

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "os"

    "github.com/google/go-github/v52/github"
    "golang.org/x/oauth2"
)

func main() {
    // GitHubのPersonal Access Token
    token := os.Getenv("PAT")
    ctx := context.Background()
    tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
    oauth2Client := oauth2.NewClient(ctx, tokenSource)
    githubClient := github.NewClient(oauth2Client)
    opt := &github.RepositoryListOptions{
        Sort:        "updated",
        Direction:   "desc",
        ListOptions: github.ListOptions{PerPage: 10},
    }
    var (
        allRepos []*github.Repository
        nextPage = -1
    )
    repoCommits := make(map[string][]*github.RepositoryCommit)
    for nextPage != 0 {
        repos, r, err := githubClient.Repositories.List(ctx, "kanade0404", opt)
        if err != nil {
            if _, ok := err.(*github.RateLimitError); ok {
                log.Fatalln("error: hit rate limit")
            }
            log.Fatalln(err)
        }
        nextPage = r.NextPage
        opt.Page = nextPage
        allRepos = append(allRepos, repos...)
        commitOpt := &github.CommitsListOptions{
            ListOptions: github.ListOptions{
                PerPage: 10,
            },
        }
        repoCommitNextPage := -1
        for _, repo := range repos {
            if repo.GetOwner().GetLogin() == "kanade0404" && (repo.GetName() == "resume" || repo.GetName() == "hello") {
                for repoCommitNextPage != 0 {
                    commits, commitRes, err := githubClient.Repositories.ListCommits(ctx, "kanade0404", repo.GetName(), commitOpt)
                    if err != nil {
                        log.Fatalln(err)
                    }
                    repoCommits[repo.GetName()] = append(repoCommits[repo.GetName()], commits...)
                    if commitRes.NextPage == 0 {
                        break
                    }
                    repoCommitNextPage = commitRes.NextPage
                    commitOpt.Page = repoCommitNextPage
                }
            }
        }
    }
    for k, v := range repoCommits {
        if err := json.NewEncoder(os.Stdout).Encode(v); err != nil {
            log.Fatalln(err)
        }
    }
}