github.com/google/go-github/v57@v57.0.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/v57/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/v57 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/v57/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/v57@master 44 ``` 45 46 ## Usage ## 47 48 ```go 49 import "github.com/google/go-github/v57/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 Use the `WithAuthToken` method to configure your client to authenticate using an 88 OAuth token (for example, a [personal access token][]). This is what is needed 89 for a majority of use cases aside from GitHub Apps. 90 91 ```go 92 client := github.NewClient(nil).WithAuthToken("... your access token ...") 93 ``` 94 95 Note that when using an authenticated Client, all calls made by the client will 96 include the specified OAuth token. Therefore, authenticated clients should 97 almost never be shared between different users. 98 99 For API methods that require HTTP Basic Authentication, use the 100 [`BasicAuthTransport`](https://godoc.org/github.com/google/go-github/github#BasicAuthTransport). 101 102 #### As a GitHub App #### 103 104 GitHub Apps authentication can be provided by the [ghinstallation](https://github.com/bradleyfalzon/ghinstallation) 105 package. 106 107 > **Note**: Most endpoints (ex. [`GET /rate_limit`]) require access token authentication 108 > while a few others (ex. [`GET /app/hook/deliveries`]) require [JWT] authentication. 109 110 [`GET /rate_limit`]: https://docs.github.com/en/rest/rate-limit#get-rate-limit-status-for-the-authenticated-user 111 [`GET /app/hook/deliveries`]: https://docs.github.com/en/rest/apps/webhooks#list-deliveries-for-an-app-webhook 112 [JWT]: https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app 113 114 115 ```go 116 import ( 117 "net/http" 118 119 "github.com/bradleyfalzon/ghinstallation/v2" 120 "github.com/google/go-github/v57/github" 121 ) 122 123 func main() { 124 // Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99. 125 itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem") 126 127 // Or for endpoints that require JWT authentication 128 // itr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, 1, "2016-10-19.private-key.pem") 129 130 if err != nil { 131 // Handle error. 132 } 133 134 // Use installation transport with client. 135 client := github.NewClient(&http.Client{Transport: itr}) 136 137 // Use client... 138 } 139 ``` 140 141 *Note*: In order to interact with certain APIs, for example writing a file to a repo, one must generate an installation token 142 using the installation ID of the GitHub app and authenticate with the OAuth method mentioned above. See the examples. 143 144 ### Rate Limiting ### 145 146 GitHub imposes a rate limit on all API clients. Unauthenticated clients are 147 limited to 60 requests per hour, while authenticated clients can make up to 148 5,000 requests per hour. The Search API has a custom rate limit. Unauthenticated 149 clients are limited to 10 requests per minute, while authenticated clients 150 can make up to 30 requests per minute. To receive the higher rate limit when 151 making calls that are not issued on behalf of a user, 152 use `UnauthenticatedRateLimitedTransport`. 153 154 The returned `Response.Rate` value contains the rate limit information 155 from the most recent API call. If a recent enough response isn't 156 available, you can use `RateLimits` to fetch the most up-to-date rate 157 limit data for the client. 158 159 To detect an API rate limit error, you can check if its type is `*github.RateLimitError`: 160 161 ```go 162 repos, _, err := client.Repositories.List(ctx, "", nil) 163 if _, ok := err.(*github.RateLimitError); ok { 164 log.Println("hit rate limit") 165 } 166 ``` 167 168 Learn more about GitHub rate limiting at 169 https://docs.github.com/en/rest/rate-limit . 170 171 In addition to these rate limits, GitHub imposes a secondary rate limit on all API clients. 172 This rate limit prevents clients from making too many concurrent requests. 173 174 To detect an API secondary rate limit error, you can check if its type is `*github.AbuseRateLimitError`: 175 176 ```go 177 repos, _, err := client.Repositories.List(ctx, "", nil) 178 if _, ok := err.(*github.AbuseRateLimitError); ok { 179 log.Println("hit secondary rate limit") 180 } 181 ``` 182 183 You can use [go-github-ratelimit](https://github.com/gofri/go-github-ratelimit) to handle 184 secondary rate limit sleep-and-retry for you. 185 186 Learn more about GitHub secondary rate limiting at 187 https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits . 188 189 ### Accepted Status ### 190 191 Some endpoints may return a 202 Accepted status code, meaning that the 192 information required is not yet ready and was scheduled to be gathered on 193 the GitHub side. Methods known to behave like this are documented specifying 194 this behavior. 195 196 To detect this condition of error, you can check if its type is 197 `*github.AcceptedError`: 198 199 ```go 200 stats, _, err := client.Repositories.ListContributorsStats(ctx, org, repo) 201 if _, ok := err.(*github.AcceptedError); ok { 202 log.Println("scheduled on GitHub side") 203 } 204 ``` 205 206 ### Conditional Requests ### 207 208 The GitHub API has good support for conditional requests which will help 209 prevent you from burning through your rate limit, as well as help speed up your 210 application. `go-github` does not handle conditional requests directly, but is 211 instead designed to work with a caching `http.Transport`. We recommend using 212 https://github.com/gregjones/httpcache for that. For example: 213 214 ```go 215 import "github.com/gregjones/httpcache" 216 217 client := github.NewClient( 218 httpcache.NewMemoryCacheTransport().Client() 219 ).WithAuthToken(os.Getenv("GITHUB_TOKEN")) 220 ``` 221 222 Learn more about GitHub conditional requests at 223 https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests. 224 225 ### Creating and Updating Resources ### 226 227 All structs for GitHub resources use pointer values for all non-repeated fields. 228 This allows distinguishing between unset fields and those set to a zero-value. 229 Helper functions have been provided to easily create these pointers for string, 230 bool, and int values. For example: 231 232 ```go 233 // create a new private repository named "foo" 234 repo := &github.Repository{ 235 Name: github.String("foo"), 236 Private: github.Bool(true), 237 } 238 client.Repositories.Create(ctx, "", repo) 239 ``` 240 241 Users who have worked with protocol buffers should find this pattern familiar. 242 243 ### Pagination ### 244 245 All requests for resource collections (repos, pull requests, issues, etc.) 246 support pagination. Pagination options are described in the 247 `github.ListOptions` struct and passed to the list methods directly or as an 248 embedded type of a more specific list options struct (for example 249 `github.PullRequestListOptions`). Pages information is available via the 250 `github.Response` struct. 251 252 ```go 253 client := github.NewClient(nil) 254 255 opt := &github.RepositoryListByOrgOptions{ 256 ListOptions: github.ListOptions{PerPage: 10}, 257 } 258 // get all pages of results 259 var allRepos []*github.Repository 260 for { 261 repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt) 262 if err != nil { 263 return err 264 } 265 allRepos = append(allRepos, repos...) 266 if resp.NextPage == 0 { 267 break 268 } 269 opt.Page = resp.NextPage 270 } 271 ``` 272 273 ### Webhooks ### 274 275 `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. 276 277 ```go 278 func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) { 279 payload, err := github.ValidatePayload(r, s.webhookSecretKey) 280 if err != nil { ... } 281 event, err := github.ParseWebHook(github.WebHookType(r), payload) 282 if err != nil { ... } 283 switch event := event.(type) { 284 case *github.CommitCommentEvent: 285 processCommitCommentEvent(event) 286 case *github.CreateEvent: 287 processCreateEvent(event) 288 ... 289 } 290 } 291 ``` 292 293 Furthermore, there are libraries like [cbrgm/githubevents][] that build upon the example above and provide functions to subscribe callbacks to specific events. 294 295 For complete usage of go-github, see the full [package docs][]. 296 297 [GitHub API v3]: https://docs.github.com/en/rest 298 [personal access token]: https://github.com/blog/1509-personal-api-tokens 299 [package docs]: https://pkg.go.dev/github.com/google/go-github/v57/github 300 [GraphQL API v4]: https://developer.github.com/v4/ 301 [shurcooL/githubv4]: https://github.com/shurcooL/githubv4 302 [GitHub webhook events]: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads 303 [cbrgm/githubevents]: https://github.com/cbrgm/githubevents 304 305 ### Testing code that uses `go-github` 306 307 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. 308 309 ### Integration Tests ### 310 311 You can run integration tests from the `test` directory. See the integration tests [README](test/README.md). 312 313 ## Contributing ## 314 I would like to cover the entire GitHub API and contributions are of course always welcome. The 315 calling pattern is pretty well established, so adding new methods is relatively 316 straightforward. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details. 317 318 ## Versioning ## 319 320 In general, go-github follows [semver](https://semver.org/) as closely as we 321 can for tagging releases of the package. For self-contained libraries, the 322 application of semantic versioning is relatively straightforward and generally 323 understood. But because go-github is a client library for the GitHub API, which 324 itself changes behavior, and because we are typically pretty aggressive about 325 implementing preview features of the GitHub API, we've adopted the following 326 versioning policy: 327 328 * We increment the **major version** with any incompatible change to 329 non-preview functionality, including changes to the exported Go API surface 330 or behavior of the API. 331 * We increment the **minor version** with any backwards-compatible changes to 332 functionality, as well as any changes to preview functionality in the GitHub 333 API. GitHub makes no guarantee about the stability of preview functionality, 334 so neither do we consider it a stable part of the go-github API. 335 * We increment the **patch version** with any backwards-compatible bug fixes. 336 337 Preview functionality may take the form of entire methods or simply additional 338 data returned from an otherwise non-preview method. Refer to the GitHub API 339 documentation for details on preview functionality. 340 341 ### Calendar Versioning ### 342 343 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/) 344 that they are starting to version their v3 API based on "calendar-versioning". 345 346 In practice, our goal is to make per-method version overrides (at 347 least in the core library) rare and temporary. 348 349 Our understanding of the GitHub docs is that they will be revving the 350 entire API to each new date-based version, even if only a few methods 351 have breaking changes. Other methods will accept the new version with 352 their existing functionality. So when a new date-based version of the 353 GitHub API is released, we (the repo maintainers) plan to: 354 355 * update each method that had breaking changes, overriding their 356 per-method API version header. This may happen in one or multiple 357 commits and PRs, and is all done in the main branch. 358 359 * once all of the methods with breaking changes have been updated, 360 have a final commit that bumps the default API version, and remove 361 all of the per-method overrides. That would now get a major version 362 bump when the next go-github release is made. 363 364 ### Version Compatibility Table ### 365 366 The following table identifies which version of the GitHub API is 367 supported by this (and past) versions of this repo (go-github). 368 Versions prior to 48.2.0 are not listed. 369 370 | go-github Version | GitHub v3 API Version | 371 | ----------------- | --------------------- | 372 | 57.0.0 | 2022-11-28 | 373 | 56.0.0 | 2022-11-28 | 374 | 55.0.0 | 2022-11-28 | 375 | 54.0.0 | 2022-11-28 | 376 | 53.2.0 | 2022-11-28 | 377 | 53.1.0 | 2022-11-28 | 378 | 53.0.0 | 2022-11-28 | 379 | 52.0.0 | 2022-11-28 | 380 | 51.0.0 | 2022-11-28 | 381 | 50.2.0 | 2022-11-28 | 382 | 50.1.0 | 2022-11-28 | 383 | 50.0.0 | 2022-11-28 | 384 | 49.1.0 | 2022-11-28 | 385 | 49.0.0 | 2022-11-28 | 386 | 48.2.0 | 2022-11-28 | 387 388 ## License ## 389 390 This library is distributed under the BSD-style license found in the [LICENSE](./LICENSE) 391 file.