Project Icon

go-github

完整的GitHub API v3 Go语言客户端

go-github是一个用于访问GitHub API v3的Go语言客户端库。它支持认证、速率限制处理、分页等功能,覆盖大部分GitHub API端点。该库还提供webhook事件处理和条件请求支持,便于开发者与GitHub平台进行交互和开发相关应用。

go-github

go-github 最新版本(SemVer) GoDoc 测试状态 测试覆盖率 在 go-github@googlegroups.com 讨论 CII 最佳实践

go-github 是一个用于访问 GitHub API v3 的 Go 客户端库。

目前,go-github 需要 Go 1.13 或更高版本。go-github 遵循 Go 的版本支持策略。我们尽量不破坏旧版本的 Go,但由于工具限制,我们并不总是测试旧版本。

如果你对使用 GraphQL API v4 感兴趣,推荐使用 shurcooL/githubv4 库。

安装

go-github 兼容模块模式下的现代 Go 版本,安装 Go 后:

go get github.com/google/go-github/v64

将解析并将包及其依赖项添加到当前开发模块中。

或者,如果在包中使用导入,也可以实现相同的效果:

import "github.com/google/go-github/v64/github"

然后运行不带参数的 go get

最后,要使用此仓库的最新版本,请使用以下命令:

go get github.com/google/go-github/v64@master

使用

import "github.com/google/go-github/v64/github"	// 启用 go modules(GO111MODULE=on 或在 GOPATH 外)
import "github.com/google/go-github/github" // 禁用 go modules

构造一个新的 GitHub 客户端,然后使用客户端上的各种服务来访问 GitHub API 的不同部分。例如:

client := github.NewClient(nil)

// 列出用户 "willnorris" 的所有组织
orgs, _, err := client.Organizations.List(context.Background(), "willnorris", nil)

一些 API 方法有可选参数可以传递。例如:

client := github.NewClient(nil)

// 列出 "github" 组织的公共仓库
opt := &github.RepositoryListByOrgOptions{Type: "public"}
repos, _, err := client.Repositories.ListByOrg(context.Background(), "github", opt)

客户端的服务将 API 分为逻辑块,并对应于 https://docs.github.com/en/rest 的 GitHub API 文档结构。

注意:使用 context 包,可以轻松地将取消信号和截止时间传递给客户端的各种服务以处理请求。如果没有可用的上下文,可以使用 context.Background() 作为起点。

更多示例代码片段,请查看 example 目录。

身份验证

使用 WithAuthToken 方法配置客户端,以使用 OAuth 令牌(例如,个人访问令牌)进行身份验证。这适用于除 GitHub 应用程序之外的大多数用例。

client := github.NewClient(nil).WithAuthToken("... 你的访问令牌 ...")

请注意,使用经过身份验证的客户端时,客户端发出的所有调用都将包含指定的 OAuth 令牌。因此,经过身份验证的客户端几乎不应该在不同用户之间共享。

对于需要 HTTP 基本身份验证的 API 方法,请使用 BasicAuthTransport

作为 GitHub 应用程序

GitHub 应用程序身份验证可以由不同的包提供,如 ghinstallationgo-githubauth

注意:大多数端点(例如 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/v64/github"
)

func main() {
	// 为集成 ID 1 和安装 ID 99 包装共享传输
	itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem")

	// 或者对于需要 JWT 身份验证的端点
	// itr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, 1, "2016-10-19.private-key.pem")

	if err != nil {
		// 处理错误
	}

	// 使用安装传输创建客户端
	client := github.NewClient(&http.Client{Transport: itr})

	// 使用客户端...
}

go-githubauth 实现了一组 oauth2.TokenSource,用于 oauth2.Client。可以将 oauth2.Client 注入到 github.Client 中以对请求进行身份验证。

使用 go-githubauth 的其他示例:

package main

import (
 "context"
 "fmt"
 "os"
 "strconv"

 "github.com/google/go-github/v64/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("创建应用程序令牌源时出错:", err)
  return
 }

 installationTokenSource := githubauth.NewInstallationTokenSource(1113, appTokenSource)

 // oauth2.NewClient 使用 oauth2.ReuseTokenSource 重用令牌直到过期。
 // 令牌过期时会自动刷新。
 // InstallationTokenSource 具有在令牌过期时刷新的机制。
 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("达到速率限制")
}

了解更多关于 GitHub 速率限制的信息,请访问 https://docs.github.com/en/rest/rate-limit

除了这些速率限制外,GitHub 还对所有 API 客户端施加了二级速率限制。这个速率限制防止客户端发出过多的并发请求。

要检测 API 二级速率限制错误,可以检查其类型是否为 *github.AbuseRateLimitError

repos, _, err := client.Repositories.List(ctx, "", nil)
if _, ok := err.(*github.AbuseRateLimitError); ok {
	log.Println("达到二级速率限制")
}

或者,你可以使用 context.WithValue 方法阻塞直到速率限制重置:

repos, _, err := client.Repositories.List(context.WithValue(ctx, github.SleepUntilPrimaryRateLimitResetWhenRateLimited, true), "", nil)

你可以使用 go-github-ratelimit 来处理二级速率限制的休眠和重试。

了解更多关于 GitHub 二级速率限制的信息,请访问 https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#about-secondary-rate-limits

接受状态

某些端点可能会返回 202 Accepted 状态码,这意味着所需信息尚未准备好,已安排在 GitHub 端收集。已知具有这种行为的方法都有相应的文档说明。

要检测这种错误情况,可以检查其类型是否为 *github.AcceptedError

stats, _, err := client.Repositories.ListContributorsStats(ctx, org, repo)
if _, ok := err.(*github.AcceptedError); ok {
	log.Println("已在 GitHub 端安排")
}

条件请求

GitHub API 对条件请求有很好的支持,这有助于防止你耗尽速率限制,并加快应用程序的速度。go-github 不直接处理条件请求,而是设计为与缓存 http.Transport 一起工作。我们建议使用 https://github.com/gregjones/httpcache 。例如:

import "github.com/gregjones/httpcache"

	client := github.NewClient(
		httpcache.NewMemoryCacheTransport().Client()
    ).WithAuthToken(os.Getenv("GITHUB_TOKEN"))

了解更多关于 GitHub 条件请求的信息,请访问 https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api?apiVersion=2022-11-28#use-conditional-requests-if-appropriate

创建和更新资源

所有 GitHub 资源的结构体对所有非重复字段都使用指针值。这允许区分未设置的字段和设置为零值的字段。已提供辅助函数来轻松创建字符串、布尔和整数值的指针。例如:

// 创建一个名为 "foo" 的新私有仓库
repo := &github.Repository{
	Name:    github.String("foo"),
	Private: github.Bool(true),
}
client.Repositories.Create(ctx, "", repo)

使用过 protocol buffers 的用户应该对这种模式很熟悉。

分页

所有资源集合(仓库、拉取请求、问题等)的请求都支持分页。分页选项在 github.ListOptions 结构中描述,并直接传递给列表方法,或作为更具体的列表选项结构的嵌入类型(例如 github.PullRequestListOptions)。页面信息可通过 github.Response 结构获得。

client := github.NewClient(nil)

opt := &github.RepositoryListByOrgOptions{
	ListOptions: github.ListOptions{PerPage: 10},
}
// 获取所有页面的结果
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

// 创建一个迭代器并开始遍历所有结果
repos := ghiter.NewFromFn1(client.Repositories.ListByOrg, "github")
for repo := range repos.All() {
	allRepos = append(allRepos, repo)
}

有关 enrichman/gh-iter 的完整用法,请参阅完整的包文档

Webhooks

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 的代码

migueleliasweb/go-github-mock 仓库提供了一种模拟响应的方法。查看该仓库以了解更多详情。

集成测试

你可以从 test 目录运行集成测试。请参阅集成测试的 README

贡献

我希望涵盖整个 GitHub API,当然始终欢迎贡献。调用模式已经很好地确立了,所以添加新方法相对简单。有关详细信息,请参阅 CONTRIBUTING.md

版本控制

总的来说,go-github 尽可能遵循 semver 来标记包的发布版本。对于独立的库,语义版本控制的应用相对简单且普遍理解。但由于 go-github 是 GitHub API 的客户端库,而 GitHub API 本身会改变行为,并且我们通常会积极实现 GitHub API 的预览功能,我们采用了以下版本控制策略:

  • 对非预览功能的任何不兼容更改,包括对导出的 Go API 表面或 API 行为的更改,我们都会增加主版本号
  • 对功能的任何向后兼容的更改,以及 GitHub API 中预览功能的任何更改,我们都会增加次版本号。GitHub 不保证预览功能的稳定性,因此我们也不将其视为 go-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 版本
64.0.02022-11-28
63.0.02022-11-28
62.0.02022-11-28
61.0.02022-11-28
60.0.02022-11-28
59.0.02022-11-28
58.0.02022-11-28
57.0.02022-11-28
56.0.02022-11-28
55.0.02022-11-28
54.0.02022-11-28
53.2.02022-11-28
53.1.02022-11-28
53.0.02022-11-28
52.0.02022-11-28
51.0.02022-11-28
50.2.02022-11-28
50.1.02022-11-28
50.0.02022-11-28
49.1.02022-11-28
49.0.02022-11-28
48.2.02022-11-28

许可证

本库在LICENSE文件中的BSD风格许可证下分发。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号