github.com/google/go-github/v50@v50.2.0/README.md (about) 1 # go-github # 2 3 [](https://github.com/google/go-github/releases) 4 [](https://pkg.go.dev/github.com/google/go-github/v50/github) 5 [](https://github.com/google/go-github/actions?query=workflow%3Atests) 6 [](https://codecov.io/gh/google/go-github) 7 [](https://groups.google.com/group/go-github) 8 [](https://bestpractices.coreinfrastructure.org/projects/796) 9 10 go-github is a Go client library for accessing the [GitHub API v3][]. 11 12 Currently, **go-github requires Go version 1.13 or greater**. go-github tracks 13 [Go's version support policy][support-policy]. We do our best not to break 14 older versions of Go if we don't have to, but due to tooling constraints, we 15 don't always test older versions. 16 17 [support-policy]: https://golang.org/doc/devel/release.html#policy 18 19 If you're interested in using the [GraphQL API v4][], the recommended library is 20 [shurcooL/githubv4][]. 21 22 ## Installation ## 23 24 go-github is compatible with modern Go releases in module mode, with Go installed: 25 26 ```bash 27 go get github.com/google/go-github/v50 28 ``` 29 30 will resolve and add the package to the current development module, along with its dependencies. 31 32 Alternatively the same can be achieved if you use import in a package: 33 34 ```go 35 import "github.com/google/go-github/v50/github" 36 ``` 37 38 and run `go get` without parameters. 39 40 Finally, to use the top-of-trunk version of this repo, use the following command: 41 42 ```bash 43 go get github.com/google/go-github/v50@master 44 ``` 45 46 ## Usage ## 47 48 ```go 49 import "github.com/google/go-github/v50/github" // with go modules enabled (GO111MODULE=on or outside GOPATH) 50 import "github.com/google/go-github/github" // with go modules disabled 51 ``` 52 53 Construct a new GitHub client, then use the various services on the client to 54 access different parts of the GitHub API. For example: 55 56 ```go 57 client := github.NewClient(nil) 58 59 // list all organizations for user "willnorris" 60 orgs, _, err := client.Organizations.List(context.Background(), "willnorris", nil) 61 ``` 62 63 Some API methods have optional parameters that can be passed. For example: 64 65 ```go 66 client := github.NewClient(nil) 67 68 // list public repositories for org "github" 69 opt := &github.RepositoryListByOrgOptions{Type: "public"} 70 repos, _, err := client.Repositories.ListByOrg(context.Background(), "github", opt) 71 ``` 72 73 The services of a client divide the API into logical chunks and correspond to 74 the structure of the GitHub API documentation at 75 https://docs.github.com/en/rest . 76 77 NOTE: Using the [context](https://godoc.org/context) package, one can easily 78 pass cancelation signals and deadlines to various services of the client for 79 handling a request. In case there is no context available, then `context.Background()` 80 can be used as a starting point. 81 82 For more sample code snippets, head over to the 83 [example](https://github.com/google/go-github/tree/master/example) directory. 84 85 ### Authentication ### 86 87 The go-github library does not directly handle authentication. Instead, when 88 creating a new client, pass an `http.Client` that can handle authentication for 89 you. The easiest and recommended way to do this is using the [oauth2][] 90 library, but you can always use any other library that provides an 91 `http.Client`. If you have an OAuth2 access token (for example, a [personal 92 API token][]), you can use it with the oauth2 library using: 93 94 ```go 95 import "golang.org/x/oauth2" 96 97 func main() { 98 ctx := context.Background() 99 ts := oauth2.StaticTokenSource( 100 &oauth2.Token{AccessToken: "... your access token ..."}, 101 ) 102 tc := oauth2.NewClient(ctx, ts) 103 104 client := github.NewClient(tc) 105 106 // list all repositories for the authenticated user 107 repos, _, err := client.Repositories.List(ctx, "", nil) 108 } 109 ``` 110 111 Note that when using an authenticated Client, all calls made by the client will 112 include the specified OAuth token. Therefore, authenticated clients should 113 almost never be shared between different users. 114 115 See the [oauth2 docs][] for complete instructions on using that library. 116 117 For API methods that require HTTP Basic Authentication, use the 118 [`BasicAuthTransport`](https://godoc.org/github.com/google/go-github/github#BasicAuthTransport). 119 120 #### As a GitHub App #### 121 122 GitHub Apps authentication can be provided by the [ghinstallation](https://github.com/bradleyfalzon/ghinstallation) 123 package. 124 125 > **Note**: Most endpoints (ex. [`GET /rate_limit`]) require access token authentication 126 > while a few others (ex. [`GET /app/hook/deliveries`]) require [JWT] authentication. 127 128 [`GET /rate_limit`]: https://docs.github.com/en/rest/rate-limit#get-rate-limit-status-for-the-authenticated-user 129 [`GET /app/hook/deliveries`]: https://docs.github.com/en/rest/apps/webhooks#list-deliveries-for-an-app-webhook 130 [JWT]: https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app 131 132 133 ```go 134 import ( 135 "net/http" 136 137 "github.com/bradleyfalzon/ghinstallation/v2" 138 "github.com/google/go-github/v50/github" 139 ) 140 141 func main() { 142 // Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99. 143 itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem") 144 145 // Or for endpoints that require JWT authentication 146 // itr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, 1, "2016-10-19.private-key.pem") 147 148 if err != nil { 149 // Handle error. 150 } 151 152 // Use installation transport with client. 153 client := github.NewClient(&http.Client{Transport: itr}) 154 155 // Use client... 156 } 157 ``` 158 159 *Note*: In order to interact with certain APIs, for example writing a file to a repo, one must generate an installation token 160 using the installation ID of the GitHub app and authenticate with the OAuth method mentioned above. See the examples. 161 162 ### Rate Limiting ### 163 164 GitHub imposes a rate limit on all API clients. Unauthenticated clients are 165 limited to 60 requests per hour, while authenticated clients can make up to 166 5,000 requests per hour. The Search API has a custom rate limit. Unauthenticated 167 clients are limited to 10 requests per minute, while authenticated clients 168 can make up to 30 requests per minute. To receive the higher rate limit when 169 making calls that are not issued on behalf of a user, 170 use `UnauthenticatedRateLimitedTransport`. 171 172 The returned `Response.Rate` value contains the rate limit information 173 from the most recent API call. If a recent enough response isn't 174 available, you can use `RateLimits` to fetch the most up-to-date rate 175 limit data for the client. 176 177 To detect an API rate limit error, you can check if its type is `*github.RateLimitError`: 178 179 ```go 180 repos, _, err := client.Repositories.List(ctx, "", nil) 181 if _, ok := err.(*github.RateLimitError); ok { 182 log.Println("hit rate limit") 183 } 184 ``` 185 186 Learn more about GitHub rate limiting at 187 https://docs.github.com/en/rest/rate-limit . 188 189 In addition to these rate limits, GitHub imposes a secondary rate limit on all API clients. 190 This rate limit prevents clients from making too many concurrent requests. 191 192 To detect an API secondary rate limit error, you can check if its type is `*github.AbuseRateLimitError`: 193 194 ```go 195 repos, _, err := client.Repositories.List(ctx, "", nil) 196 if _, ok := err.(*github.AbuseRateLimitError); ok { 197 log.Println("hit secondary rate limit") 198 } 199 ``` 200 201 You can use [go-github-ratelimit](https://github.com/gofri/go-github-ratelimit) to handle 202 secondary rate limit sleep-and-retry for you. 203 204 Learn more about GitHub secondary rate limiting at 205 https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits . 206 207 ### Accepted Status ### 208 209 Some endpoints may return a 202 Accepted status code, meaning that the 210 information required is not yet ready and was scheduled to be gathered on 211 the GitHub side. Methods known to behave like this are documented specifying 212 this behavior. 213 214 To detect this condition of error, you can check if its type is 215 `*github.AcceptedError`: 216 217 ```go 218 stats, _, err := client.Repositories.ListContributorsStats(ctx, org, repo) 219 if _, ok := err.(*github.AcceptedError); ok { 220 log.Println("scheduled on GitHub side") 221 } 222 ``` 223 224 ### Conditional Requests ### 225 226 The GitHub API has good support for conditional requests which will help 227 prevent you from burning through your rate limit, as well as help speed up your 228 application. `go-github` does not handle conditional requests directly, but is 229 instead designed to work with a caching `http.Transport`. We recommend using 230 https://github.com/gregjones/httpcache for that. For example: 231 232 ```go 233 import "github.com/gregjones/httpcache" 234 235 ts := oauth2.StaticTokenSource( 236 &oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")}, 237 ) 238 tc := &http.Client{ 239 Transport: &oauth2.Transport{ 240 Base: httpcache.NewMemoryCacheTransport(), 241 Source: ts, 242 }, 243 } 244 client := github.NewClient(tc) 245 ``` 246 247 Learn more about GitHub conditional requests at 248 https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests. 249 250 ### Creating and Updating Resources ### 251 252 All structs for GitHub resources use pointer values for all non-repeated fields. 253 This allows distinguishing between unset fields and those set to a zero-value. 254 Helper functions have been provided to easily create these pointers for string, 255 bool, and int values. For example: 256 257 ```go 258 // create a new private repository named "foo" 259 repo := &github.Repository{ 260 Name: github.String("foo"), 261 Private: github.Bool(true), 262 } 263 client.Repositories.Create(ctx, "", repo) 264 ``` 265 266 Users who have worked with protocol buffers should find this pattern familiar. 267 268 ### Pagination ### 269 270 All requests for resource collections (repos, pull requests, issues, etc.) 271 support pagination. Pagination options are described in the 272 `github.ListOptions` struct and passed to the list methods directly or as an 273 embedded type of a more specific list options struct (for example 274 `github.PullRequestListOptions`). Pages information is available via the 275 `github.Response` struct. 276 277 ```go 278 client := github.NewClient(nil) 279 280 opt := &github.RepositoryListByOrgOptions{ 281 ListOptions: github.ListOptions{PerPage: 10}, 282 } 283 // get all pages of results 284 var allRepos []*github.Repository 285 for { 286 repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt) 287 if err != nil { 288 return err 289 } 290 allRepos = append(allRepos, repos...) 291 if resp.NextPage == 0 { 292 break 293 } 294 opt.Page = resp.NextPage 295 } 296 ``` 297 298 ### Webhooks ### 299 300 `go-github` provides structs for almost all [GitHub webhook events][] as well as functions to validate them and unmarshal JSON payloads from `http.Request` structs. 301 302 ```go 303 func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) { 304 payload, err := github.ValidatePayload(r, s.webhookSecretKey) 305 if err != nil { ... } 306 event, err := github.ParseWebHook(github.WebHookType(r), payload) 307 if err != nil { ... } 308 switch event := event.(type) { 309 case *github.CommitCommentEvent: 310 processCommitCommentEvent(event) 311 case *github.CreateEvent: 312 processCreateEvent(event) 313 ... 314 } 315 } 316 ``` 317 318 Furthermore, there are libraries like [cbrgm/githubevents][] that build upon the example above and provide functions to subscribe callbacks to specific events. 319 320 For complete usage of go-github, see the full [package docs][]. 321 322 [GitHub API v3]: https://docs.github.com/en/rest 323 [oauth2]: https://github.com/golang/oauth2 324 [oauth2 docs]: https://godoc.org/golang.org/x/oauth2 325 [personal API token]: https://github.com/blog/1509-personal-api-tokens 326 [package docs]: https://pkg.go.dev/github.com/google/go-github/v50/github 327 [GraphQL API v4]: https://developer.github.com/v4/ 328 [shurcooL/githubv4]: https://github.com/shurcooL/githubv4 329 [GitHub webhook events]: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads 330 [cbrgm/githubevents]: https://github.com/cbrgm/githubevents 331 332 ### Testing code that uses `go-github` 333 334 The repo [migueleliasweb/go-github-mock](https://github.com/migueleliasweb/go-github-mock) provides a way to mock responses. Check the repo for more details. 335 336 ### Integration Tests ### 337 338 You can run integration tests from the `test` directory. See the integration tests [README](test/README.md). 339 340 ## Contributing ## 341 I would like to cover the entire GitHub API and contributions are of course always welcome. The 342 calling pattern is pretty well established, so adding new methods is relatively 343 straightforward. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details. 344 345 ## Versioning ## 346 347 In general, go-github follows [semver](https://semver.org/) as closely as we 348 can for tagging releases of the package. For self-contained libraries, the 349 application of semantic versioning is relatively straightforward and generally 350 understood. But because go-github is a client library for the GitHub API, which 351 itself changes behavior, and because we are typically pretty aggressive about 352 implementing preview features of the GitHub API, we've adopted the following 353 versioning policy: 354 355 * We increment the **major version** with any incompatible change to 356 non-preview functionality, including changes to the exported Go API surface 357 or behavior of the API. 358 * We increment the **minor version** with any backwards-compatible changes to 359 functionality, as well as any changes to preview functionality in the GitHub 360 API. GitHub makes no guarantee about the stability of preview functionality, 361 so neither do we consider it a stable part of the go-github API. 362 * We increment the **patch version** with any backwards-compatible bug fixes. 363 364 Preview functionality may take the form of entire methods or simply additional 365 data returned from an otherwise non-preview method. Refer to the GitHub API 366 documentation for details on preview functionality. 367 368 ### Calendar Versioning ### 369 370 As of 2022-11-28, GitHub [has announced](https://github.blog/2022-11-28-to-infinity-and-beyond-enabling-the-future-of-githubs-rest-api-with-api-versioning/) 371 that they are starting to version their v3 API based on "calendar-versioning". 372 373 In practice, our goal is to make per-method version overrides (at 374 least in the core library) rare and temporary. 375 376 Our understanding of the GitHub docs is that they will be revving the 377 entire API to each new date-based version, even if only a few methods 378 have breaking changes. Other methods will accept the new version with 379 their existing functionality. So when a new date-based version of the 380 GitHub API is released, we (the repo maintainers) plan to: 381 382 * update each method that had breaking changes, overriding their 383 per-method API version header. This may happen in one or multiple 384 commits and PRs, and is all done in the main branch. 385 386 * once all of the methods with breaking changes have been updated, 387 have a final commit that bumps the default API version, and remove 388 all of the per-method overrides. That would now get a major version 389 bump when the next go-github release is made. 390 391 ### Version Compatibility Table ### 392 393 The following table identifies which version of the GitHub API is 394 supported by this (and past) versions of this repo (go-github). 395 Versions prior to 48.2.0 are not listed. 396 397 | go-github Version | GitHub v3 API Version | 398 | ----------------- | --------------------- | 399 | 50.2.0 | 2022-11-28 | 400 | 50.1.0 | 2022-11-28 | 401 | 50.0.0 | 2022-11-28 | 402 | 49.1.0 | 2022-11-28 | 403 | 49.0.0 | 2022-11-28 | 404 | 48.2.0 | 2022-11-28 | 405 406 ## License ## 407 408 This library is distributed under the BSD-style license found in the [LICENSE](./LICENSE) 409 file.