go-github

go-github

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

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

go-githubGitHub APIGo客户端API访问开源项目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风格许可证下分发。

编辑推荐精选

商汤小浣熊

商汤小浣熊

最强AI数据分析助手

小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。

imini AI

imini AI

像人一样思考的AI智能体

imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。

Keevx

Keevx

AI数字人视频创作平台

Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。

即梦AI

即梦AI

一站式AI创作平台

提供 AI 驱动的图片、视频生成及数字人等功能,助力创意创作

扣子-AI办公

扣子-AI办公

AI办公助手,复杂任务高效处理

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

热门AI工具生产力协作转型TraeAI IDE
蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI助手AI工具AI写作工具AI辅助写作蛙蛙写作学术助手办公助手营销助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

聊天机器人AI助手热门AI工具AI对话
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

热门AI工具AI办公办公工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图
下拉加载更多