github.com/google/go-github/v49@v49.1.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/v49/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/v49 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/v49/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/v49@master 44 ``` 45 46 ## Usage ## 47 48 ```go 49 import "github.com/google/go-github/v49/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/v49/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 ### 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. 213 214 Learn more about GitHub conditional requests at 215 https://docs.github.com/en/rest/overview/resources-in-the-rest-api#conditional-requests. 216 217 ### Creating and Updating Resources ### 218 219 All structs for GitHub resources use pointer values for all non-repeated fields. 220 This allows distinguishing between unset fields and those set to a zero-value. 221 Helper functions have been provided to easily create these pointers for string, 222 bool, and int values. For example: 223 224 ```go 225 // create a new private repository named "foo" 226 repo := &github.Repository{ 227 Name: github.String("foo"), 228 Private: github.Bool(true), 229 } 230 client.Repositories.Create(ctx, "", repo) 231 ``` 232 233 Users who have worked with protocol buffers should find this pattern familiar. 234 235 ### Pagination ### 236 237 All requests for resource collections (repos, pull requests, issues, etc.) 238 support pagination. Pagination options are described in the 239 `github.ListOptions` struct and passed to the list methods directly or as an 240 embedded type of a more specific list options struct (for example 241 `github.PullRequestListOptions`). Pages information is available via the 242 `github.Response` struct. 243 244 ```go 245 client := github.NewClient(nil) 246 247 opt := &github.RepositoryListByOrgOptions{ 248 ListOptions: github.ListOptions{PerPage: 10}, 249 } 250 // get all pages of results 251 var allRepos []*github.Repository 252 for { 253 repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt) 254 if err != nil { 255 return err 256 } 257 allRepos = append(allRepos, repos...) 258 if resp.NextPage == 0 { 259 break 260 } 261 opt.Page = resp.NextPage 262 } 263 ``` 264 265 ### Webhooks ### 266 267 `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. 268 269 ```go 270 func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) { 271 payload, err := github.ValidatePayload(r, s.webhookSecretKey) 272 if err != nil { ... } 273 event, err := github.ParseWebHook(github.WebHookType(r), payload) 274 if err != nil { ... } 275 switch event := event.(type) { 276 case *github.CommitCommentEvent: 277 processCommitCommentEvent(event) 278 case *github.CreateEvent: 279 processCreateEvent(event) 280 ... 281 } 282 } 283 ``` 284 285 Furthermore, there are libraries like [cbrgm/githubevents][] that build upon the example above and provide functions to subscribe callbacks to specific events. 286 287 For complete usage of go-github, see the full [package docs][]. 288 289 [GitHub API v3]: https://docs.github.com/en/rest 290 [oauth2]: https://github.com/golang/oauth2 291 [oauth2 docs]: https://godoc.org/golang.org/x/oauth2 292 [personal API token]: https://github.com/blog/1509-personal-api-tokens 293 [package docs]: https://pkg.go.dev/github.com/google/go-github/v49/github 294 [GraphQL API v4]: https://developer.github.com/v4/ 295 [shurcooL/githubv4]: https://github.com/shurcooL/githubv4 296 [GitHub webhook events]: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads 297 [cbrgm/githubevents]: https://github.com/cbrgm/githubevents 298 299 ### Testing code that uses `go-github` 300 301 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. 302 303 ### Integration Tests ### 304 305 You can run integration tests from the `test` directory. See the integration tests [README](test/README.md). 306 307 ## Contributing ## 308 I would like to cover the entire GitHub API and contributions are of course always welcome. The 309 calling pattern is pretty well established, so adding new methods is relatively 310 straightforward. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details. 311 312 ## Versioning ## 313 314 In general, go-github follows [semver](https://semver.org/) as closely as we 315 can for tagging releases of the package. For self-contained libraries, the 316 application of semantic versioning is relatively straightforward and generally 317 understood. But because go-github is a client library for the GitHub API, which 318 itself changes behavior, and because we are typically pretty aggressive about 319 implementing preview features of the GitHub API, we've adopted the following 320 versioning policy: 321 322 * We increment the **major version** with any incompatible change to 323 non-preview functionality, including changes to the exported Go API surface 324 or behavior of the API. 325 * We increment the **minor version** with any backwards-compatible changes to 326 functionality, as well as any changes to preview functionality in the GitHub 327 API. GitHub makes no guarantee about the stability of preview functionality, 328 so neither do we consider it a stable part of the go-github API. 329 * We increment the **patch version** with any backwards-compatible bug fixes. 330 331 Preview functionality may take the form of entire methods or simply additional 332 data returned from an otherwise non-preview method. Refer to the GitHub API 333 documentation for details on preview functionality. 334 335 ### Calendar Versioning ### 336 337 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/) 338 that they are starting to version their v3 API based on "calendar-versioning". 339 340 In practice, our goal is to make per-method version overrides (at 341 least in the core library) rare and temporary. 342 343 Our understanding of the GitHub docs is that they will be revving the 344 entire API to each new date-based version, even if only a few methods 345 have breaking changes. Other methods will accept the new version with 346 their existing functionality. So when a new date-based version of the 347 GitHub API is released, we (the repo maintainers) plan to: 348 349 * update each method that had breaking changes, overriding their 350 per-method API version header. This may happen in one or multiple 351 commits and PRs, and is all done in the main branch. 352 353 * once all of the methods with breaking changes have been updated, 354 have a final commit that bumps the default API version, and remove 355 all of the per-method overrides. That would now get a major version 356 bump when the next go-github release is made. 357 358 ### Version Compatibility Table ### 359 360 The following table identifies which version of the GitHub API is 361 supported by this (and past) versions of this repo (go-github). 362 Versions prior to 48.2.0 are not listed. 363 364 | go-github Version | GitHub v3 API Version | 365 | ----------------- | --------------------- | 366 | 49.0.0 | 2022-11-28 | 367 | 48.2.0 | 2022-11-28 | 368 369 ## License ## 370 371 This library is distributed under the BSD-style license found in the [LICENSE](./LICENSE) 372 file.