Go-GitHub是访问GitHub API V3的GO客户库。
Go-Github需要GO版本1.17及更高版本,并且对GO版本1.22及更大的GO进行了测试。 Go-Github跟踪GO的版本支持策略。如果不需要,我们会尽最大努力不要破坏GO的旧版本,但是由于工具限制,我们并不总是测试较旧版本的版本。
如果您有兴趣使用GraphQl API V4,则推荐的库是Shurcool/githubv4。
Go-GitHub与Modern Go在模块模式下兼容,并安装了GO:
go get github.com/google/go-github/v68将解决并将软件包添加到当前开发模块及其依赖项。
或者,如果您在软件包中使用导入,则可以实现相同的情况:
import "github.com/google/go-github/v68/github"然后go get无参数。
最后,要使用此存储库的陷入最高版本,请使用以下命令:
go get github.com/google/go-github/v68@master import "github.com/google/go-github/v68/github" // with go modules enabled (GO111MODULE=on or outside GOPATH)
import "github.com/google/go-github/github" // with go modules disabled构建一个新的GitHub客户端,然后使用客户端上的各种服务访问GitHub API的不同部分。例如:
client := github . NewClient ( nil )
// list all organizations for user "willnorris"
orgs , _ , err := client . Organizations . List ( context . Background (), "willnorris" , nil )一些API方法具有可以传递的可选参数。例如:
client := github . NewClient ( nil )
// list public repositories for org "github"
opt := & github. RepositoryListByOrgOptions { Type : "public" }
repos , _ , err := client . Repositories . ListByOrg ( context . Background (), "github" , opt )客户的服务将API分为逻辑块,并与GitHub API文档的结构相对应。
注意:使用上下文软件包,可以轻松地将取消信号和截止日期传递给客户的各种服务,以处理请求。如果没有可用的上下文,则可以将context.Background()用作起点。
有关更多示例代码段,请转到示例目录。
使用WithAuthToken方法配置客户端使用OAuth代币(例如,个人访问令牌)进行身份验证。除GitHub应用程序外,这是大多数用例所需的。
client := github . NewClient ( nil ). WithAuthToken ( "... your access token ..." )请注意,使用身份验证的客户端时,客户端的所有呼叫都将包括指定的OAUTH令牌。因此,经过身份验证的客户几乎不应在不同用户之间共享。
对于需要HTTP基本身份验证的API方法,请使用BasicAuthTransport 。
GitHub应用程序身份验证可以由Bradleyfalzon/Ghinstallation或Jferrl/Go-Githubauth等不同的PKG提供。
注意:大多数端点(例如
GET /rate_limit)需要访问令牌身份验证,而其他一些(例如GET /app/hook/deliveries)需要JWT身份验证。
ghinstallation提供了Transport ,该传输实现了http.RoundTripper ,以提供身份验证作为GitHub应用程序的安装。
这是如何使用ghinstallation软件包作为GITHUB应用进行身份验证的示例:
import (
"net/http"
"github.com/bradleyfalzon/ghinstallation/v2"
"github.com/google/go-github/v68/github"
)
func main () {
// Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99.
itr , err := ghinstallation . NewKeyFromFile ( http . DefaultTransport , 1 , 99 , "2016-10-19.private-key.pem" )
// Or for endpoints that require JWT authentication
// itr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, 1, "2016-10-19.private-key.pem")
if err != nil {
// Handle error.
}
// Use installation transport with client.
client := github . NewClient ( & http. Client { Transport : itr })
// Use client...
} go-githubauth实现了一组oauth2.TokenSource将与oauth2.Client一起使用。 oauth2.Client可以注入github.Client以身份验证请求。
使用go-githubauth的其他示例:
package main
import (
"context"
"fmt"
"os"
"strconv"
"github.com/google/go-github/v68/github"
"github.com/jferrl/go-githubauth"
"golang.org/x/oauth2"
)
func main () {
privateKey := [] byte ( os . Getenv ( "GITHUB_APP_PRIVATE_KEY" ))
appTokenSource , err := githubauth . NewApplicationTokenSource ( 1112 , privateKey )
if err != nil {
fmt . Println ( "Error creating application token source:" , err )
return
}
installationTokenSource := githubauth . NewInstallationTokenSource ( 1113 , appTokenSource )
// oauth2.NewClient uses oauth2.ReuseTokenSource to reuse the token until it expires.
// The token will be automatically refreshed when it expires.
// InstallationTokenSource has the mechanism to refresh the token when it expires.
httpClient := oauth2 . NewClient ( context . Background (), installationTokenSource )
client := github . NewClient ( httpClient )
}注意:为了与某些API进行交互,例如将文件写入回购,必须使用GitHub应用程序的安装ID生成安装令牌,并使用上面提到的OAUTH方法进行身份验证。请参阅示例。
GitHub对所有API客户端施加了率限制。未经验证的客户每小时限制60个请求,而经过验证的客户每小时最多可提供5,000个请求。搜索API具有自定义费率限制。未经验证的客户限制为每分钟10个请求,而身份验证的客户每分钟最多可弥补30个请求。要在代表用户发出未发出的呼叫时接收较高的利率限制,请使用UnauthenticatedRateLimitedTransport 。
返回的Response.Rate值包含最新API调用中的速率限制信息。如果最近没有足够的响应,您可以使用RateLimits获取客户端的最新利率限制数据。
要检测API率限制错误,您可以检查其类型是否为*github.RateLimitError :
repos , _ , err := client . Repositories . List ( ctx , "" , nil )
if _ , ok := err .( * github. RateLimitError ); ok {
log . Println ( "hit rate limit" )
}在“ REST API端点的利率限制”中了解有关GitHub速率限制的更多信息。
除了这些速率限制外,GitHub还对所有API客户限制了次要率限制。此速率限制可阻止客户提出太多并发请求。
要检测API二级率限制错误,您可以检查其类型是否为*github.AbuseRateLimitError :
repos , _ , err := client . Repositories . List ( ctx , "" , nil )
if _ , ok := err .( * github. AbuseRateLimitError ); ok {
log . Println ( "hit secondary rate limit" )
}另外,您可以阻止使用context.WithValue来重置速率限制。
repos , _ , err := client . Repositories . List ( context . WithValue ( ctx , github . SleepUntilPrimaryRateLimitResetWhenRateLimited , true ), "" , nil )您可以使用Gofri/go-github比例来处理次要费率限制您的睡眠和退休。
在“大约二级利率限制”中了解有关GitHub次要率限制的更多信息。
一些端点可能会返回202个接受的状态代码,这意味着所需的信息尚未准备就绪,并计划收集在Github侧。已知的行为方式已被记录为指定此行为。
为了检测此错误条件,您可以检查其类型是否为*github.AcceptedError :
stats , _ , err := client . Repositories . ListContributorsStats ( ctx , org , repo )
if _ , ok := err .( * github. AcceptedError ); ok {
log . Println ( "scheduled on GitHub side" )
}GitHub API对有条件的请求有很好的支持,这将有助于防止您燃烧的费率限制,并有助于加快应用程序的速度。 go-github不能直接处理有条件的请求,而是设计用于使用缓存http.Transport 。我们建议对此使用Gregjones/httpcache。例如:
import "github.com/gregjones/httpcache"
client := github . NewClient (
httpcache . NewMemoryCacheTransport (). Client ()
). WithAuthToken ( os . Getenv ( "GITHUB_TOKEN" ))在“如果适当的话使用条件请求”中了解有关GitHub条件请求的更多信息。
GitHub资源的所有结构都为所有未重复的字段使用指针值。这允许区分未设置的字段和设置为零值的字段。已经提供了辅助功能,以轻松为字符串,bool和int值创建这些指针。例如:
// create a new private repository named "foo"
repo := & github. Repository {
Name : github . Ptr ( "foo" ),
Private : github . Ptr ( true ),
}
client . Repositories . Create ( ctx , "" , repo )使用协议缓冲区的用户应该熟悉这种模式。
所有资源收集请求(存储库,拉请请求,问题等)都支持分页。分页选项在github.ListOptions struct中描述,并直接传递到列表方法或作为更特定列表选项struck的嵌入式类型(例如github.PullRequestListOptions )。页面信息可通过github.Response struct获得。
client := github . NewClient ( nil )
opt := & github. RepositoryListByOrgOptions {
ListOptions : github. ListOptions { PerPage : 10 },
}
// get all pages of results
var allRepos [] * github. Repository
for {
repos , resp , err := client . Repositories . ListByOrg ( ctx , "github" , opt )
if err != nil {
return err
}
allRepos = append ( allRepos , repos ... )
if resp . NextPage == 0 {
break
}
opt . Page = resp . NextPage
} GO V1.23介绍了新的iter软件包。
使用enrichman/gh-iter软件包,可以为go-github创建迭代器。迭代器将为您处理分页,循环通过所有可用结果。
client := github . NewClient ( nil )
var allRepos [] * github. Repository
// create an iterator and start looping through all the results
repos := ghiter . NewFromFn1 ( client . Repositories . ListByOrg , "github" )
for repo := range repos . All () {
allRepos = append ( allRepos , repo )
}有关enrichman/gh-iter的完整使用,请参阅完整的软件包文档。
go-github提供了几乎所有GitHub Webhook事件的结构,以及函数以验证它们,并从http.Request结构中删除JSON有效载荷。
func ( s * GitHubEventMonitor ) ServeHTTP ( w http. ResponseWriter , r * http. Request ) {
payload , err := github . ValidatePayload ( r , s . webhookSecretKey )
if err != nil { ... }
event , err := github . ParseWebHook ( github . WebHookType ( r ), payload )
if err != nil { ... }
switch event := event .( type ) {
case * github. CommitCommentEvent :
processCommitCommentEvent ( event )
case * github. CreateEvent :
processCreateEvent ( event )
...
}
}此外,还有诸如CBRGM/githubevents之类的库在上面的示例上建立,并提供了订阅对特定事件的回调的功能。
有关Go-Github的完整使用,请参阅完整的包装文档。
go-github的测试代码Repo Migueliasweb/go-github-Mock提供了一种模拟响应的方法。检查存储库以获取更多详细信息。
您可以从test目录运行集成测试。请参阅“集成测试”。
我想介绍整个GitHub API,并且总是欢迎贡献。调用模式已经建立得很好,因此添加新方法相对简单。有关详细信息,请参见CONTRIBUTING.md 。
通常,go-github尽可能地跟随SEMVER标记包装的版本。对于独立的库,语义版本的应用相对简单,并且通常被理解。但是,由于Go-Github是GitHub API的客户端库,该客户库本身会改变行为,而且由于我们在实施GitHub API的预览功能方面通常非常积极,因此我们采用了以下版本控制策略:
预览功能可以采用整个方法的形式,也可以简单地从其他非浏览方法返回的其他数据。有关预览功能的详细信息,请参阅GitHub API文档。
截至2022-11-28,GitHub宣布他们将根据“日历否定”开始版本的V3 API。
在实践中,我们的目标是使人均版本覆盖(至少在核心库中)稀有和临时。
我们对GITHUB文档的理解是,即使只有少数方法有破坏性的更改,它们也将将整个API传递到每个基于日期的新版本。其他方法将接受具有现有功能的新版本。因此,当发布GITHUB API的新的基于日期的新版本时,我们(回购维护者)计划:
更新每个具有破坏更改的方法,从而覆盖其每手电API版本标头。这可能发生在一个或多个提交和PR中,并且全部在主分支中完成。
一旦更新了破坏更改的所有方法,就将最终提交撞击默认的API版本,并删除所有人均替代。现在,当制作下一个Go-GitHub发行版时,这将会引起主要版本的颠簸。
下表确定了此仓库(go-github)的此(和过去)版本支持哪个版本的GitHub API。未列出48.2.0之前的版本。
| go-github版本 | GitHub V3 API版本 |
|---|---|
| 68.0.0 | 2022-11-28 |
| ... | 2022-11-28 |
| 48.2.0 | 2022-11-28 |
该库是根据许可证文件中的BSD式许可分配的。