github.com/google/go-github/v64@v64.0.0/README.md (about)

     1  # go-github #
     2  
     3  [![go-github release (latest SemVer)](https://img.shields.io/github/v/release/google/go-github?sort=semver)](https://github.com/google/go-github/releases)
     4  [![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v64/github)
     5  [![Test Status](https://github.com/google/go-github/workflows/tests/badge.svg)](https://github.com/google/go-github/actions?query=workflow%3Atests)
     6  [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github)
     7  [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github)
     8  [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/796/badge)](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/v64
    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/v64/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/v64@master
    44  ```
    45  
    46  ## Usage ##
    47  
    48  ```go
    49  import "github.com/google/go-github/v64/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 different pkgs like [ghinstallation](https://github.com/bradleyfalzon/ghinstallation) or [go-githubauth](https://github.com/jferrl/go-githubauth).
   105  
   106  > **Note**: Most endpoints (ex. [`GET /rate_limit`]) require access token authentication
   107  > while a few others (ex. [`GET /app/hook/deliveries`]) require [JWT] authentication.
   108  
   109  [`GET /rate_limit`]: https://docs.github.com/en/rest/rate-limit#get-rate-limit-status-for-the-authenticated-user
   110  [`GET /app/hook/deliveries`]: https://docs.github.com/en/rest/apps/webhooks#list-deliveries-for-an-app-webhook
   111  [JWT]: https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app
   112  
   113  `ghinstallation` provides `Transport`, which implements `http.RoundTripper` to provide authentication as an installation for GitHub Apps.
   114  
   115  Here is an example of how to authenticate as a GitHub App using the `ghinstallation` package:
   116  
   117  ```go
   118  import (
   119  	"net/http"
   120  
   121  	"github.com/bradleyfalzon/ghinstallation/v2"
   122  	"github.com/google/go-github/v64/github"
   123  )
   124  
   125  func main() {
   126  	// Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99.
   127  	itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem")
   128  
   129  	// Or for endpoints that require JWT authentication
   130  	// itr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, 1, "2016-10-19.private-key.pem")
   131  
   132  	if err != nil {
   133  		// Handle error.
   134  	}
   135  
   136  	// Use installation transport with client.
   137  	client := github.NewClient(&http.Client{Transport: itr})
   138  
   139  	// Use client...
   140  }
   141  ```
   142  
   143  `go-githubauth` implements a set of `oauth2.TokenSource` to be used with `oauth2.Client`. An `oauth2.Client` can be injected into the `github.Client` to authenticate requests.
   144  
   145  Other example using `go-githubauth`:
   146  
   147  ```go
   148  package main
   149  
   150  import (
   151   "context"
   152   "fmt"
   153   "os"
   154   "strconv"
   155  
   156   "github.com/google/go-github/v64/github"
   157   "github.com/jferrl/go-githubauth"
   158   "golang.org/x/oauth2"
   159  )
   160  
   161  func main() {
   162   privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
   163  
   164   appTokenSource, err := githubauth.NewApplicationTokenSource(1112, privateKey)
   165   if err != nil {
   166    fmt.Println("Error creating application token source:", err)
   167    return
   168   }
   169  
   170   installationTokenSource := githubauth.NewInstallationTokenSource(1113, appTokenSource)
   171  
   172   // oauth2.NewClient uses oauth2.ReuseTokenSource to reuse the token until it expires.
   173   // The token will be automatically refreshed when it expires.
   174   // InstallationTokenSource has the mechanism to refresh the token when it expires.
   175   httpClient := oauth2.NewClient(context.Background(), installationTokenSource)
   176  
   177   client := github.NewClient(httpClient)
   178  }
   179  ```
   180  
   181  *Note*: In order to interact with certain APIs, for example writing a file to a repo, one must generate an installation token
   182  using the installation ID of the GitHub app and authenticate with the OAuth method mentioned above. See the examples.
   183  
   184  ### Rate Limiting ###
   185  
   186  GitHub imposes a rate limit on all API clients. Unauthenticated clients are
   187  limited to 60 requests per hour, while authenticated clients can make up to
   188  5,000 requests per hour. The Search API has a custom rate limit. Unauthenticated
   189  clients are limited to 10 requests per minute, while authenticated clients
   190  can make up to 30 requests per minute. To receive the higher rate limit when
   191  making calls that are not issued on behalf of a user,
   192  use `UnauthenticatedRateLimitedTransport`.
   193  
   194  The returned `Response.Rate` value contains the rate limit information
   195  from the most recent API call. If a recent enough response isn't
   196  available, you can use `RateLimits` to fetch the most up-to-date rate
   197  limit data for the client.
   198  
   199  To detect an API rate limit error, you can check if its type is `*github.RateLimitError`:
   200  
   201  ```go
   202  repos, _, err := client.Repositories.List(ctx, "", nil)
   203  if _, ok := err.(*github.RateLimitError); ok {
   204  	log.Println("hit rate limit")
   205  }
   206  ```
   207  
   208  Learn more about GitHub rate limiting at
   209  https://docs.github.com/en/rest/rate-limit .
   210  
   211  In addition to these rate limits, GitHub imposes a secondary rate limit on all API clients.
   212  This rate limit prevents clients from making too many concurrent requests.
   213  
   214  To detect an API secondary rate limit error, you can check if its type is `*github.AbuseRateLimitError`:
   215  
   216  ```go
   217  repos, _, err := client.Repositories.List(ctx, "", nil)
   218  if _, ok := err.(*github.AbuseRateLimitError); ok {
   219  	log.Println("hit secondary rate limit")
   220  }
   221  ```
   222  
   223  Alternatively, you can block until the rate limit is reset by using the `context.WithValue` method:
   224  
   225  ```go
   226  repos, _, err := client.Repositories.List(context.WithValue(ctx, github.SleepUntilPrimaryRateLimitResetWhenRateLimited, true), "", nil)
   227  ```
   228  
   229  You can use [go-github-ratelimit](https://github.com/gofri/go-github-ratelimit) to handle
   230  secondary rate limit sleep-and-retry for you.
   231  
   232  Learn more about GitHub secondary rate limiting at
   233  https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28#about-secondary-rate-limits .
   234  
   235  ### Accepted Status ###
   236  
   237  Some endpoints may return a 202 Accepted status code, meaning that the
   238  information required is not yet ready and was scheduled to be gathered on
   239  the GitHub side. Methods known to behave like this are documented specifying
   240  this behavior.
   241  
   242  To detect this condition of error, you can check if its type is
   243  `*github.AcceptedError`:
   244  
   245  ```go
   246  stats, _, err := client.Repositories.ListContributorsStats(ctx, org, repo)
   247  if _, ok := err.(*github.AcceptedError); ok {
   248  	log.Println("scheduled on GitHub side")
   249  }
   250  ```
   251  
   252  ### Conditional Requests ###
   253  
   254  The GitHub API has good support for conditional requests which will help
   255  prevent you from burning through your rate limit, as well as help speed up your
   256  application. `go-github` does not handle conditional requests directly, but is
   257  instead designed to work with a caching `http.Transport`. We recommend using
   258  https://github.com/gregjones/httpcache for that. For example:
   259  
   260  ```go
   261  import "github.com/gregjones/httpcache"
   262  
   263  	client := github.NewClient(
   264  		httpcache.NewMemoryCacheTransport().Client()
   265      ).WithAuthToken(os.Getenv("GITHUB_TOKEN"))
   266  ```
   267  
   268  Learn more about GitHub conditional requests at
   269  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
   270  
   271  ### Creating and Updating Resources ###
   272  
   273  All structs for GitHub resources use pointer values for all non-repeated fields.
   274  This allows distinguishing between unset fields and those set to a zero-value.
   275  Helper functions have been provided to easily create these pointers for string,
   276  bool, and int values. For example:
   277  
   278  ```go
   279  // create a new private repository named "foo"
   280  repo := &github.Repository{
   281  	Name:    github.String("foo"),
   282  	Private: github.Bool(true),
   283  }
   284  client.Repositories.Create(ctx, "", repo)
   285  ```
   286  
   287  Users who have worked with protocol buffers should find this pattern familiar.
   288  
   289  ### Pagination ###
   290  
   291  All requests for resource collections (repos, pull requests, issues, etc.)
   292  support pagination. Pagination options are described in the
   293  `github.ListOptions` struct and passed to the list methods directly or as an
   294  embedded type of a more specific list options struct (for example
   295  `github.PullRequestListOptions`). Pages information is available via the
   296  `github.Response` struct.
   297  
   298  ```go
   299  client := github.NewClient(nil)
   300  
   301  opt := &github.RepositoryListByOrgOptions{
   302  	ListOptions: github.ListOptions{PerPage: 10},
   303  }
   304  // get all pages of results
   305  var allRepos []*github.Repository
   306  for {
   307  	repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt)
   308  	if err != nil {
   309  		return err
   310  	}
   311  	allRepos = append(allRepos, repos...)
   312  	if resp.NextPage == 0 {
   313  		break
   314  	}
   315  	opt.Page = resp.NextPage
   316  }
   317  ```
   318  
   319  #### Iterators (**experimental**)
   320  
   321  Go v1.23 introduces the new `iter` package.  
   322  
   323  With the `enrichman/gh-iter` package, it is possible to create iterators for `go-github`. The iterator will handle pagination for you, looping through all the available results.
   324  
   325  ```go
   326  client := github.NewClient(nil)
   327  var allRepos []*github.Repository
   328  
   329  // create an iterator and start looping through all the results
   330  repos := ghiter.NewFromFn1(client.Repositories.ListByOrg, "github")
   331  for repo := range repos.All() {
   332  	allRepos = append(allRepos, repo)
   333  }
   334  ```
   335  
   336  For complete usage of `enrichman/gh-iter`, see the full [package docs](https://github.com/enrichman/gh-iter).
   337  
   338  ### Webhooks ###
   339  
   340  `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.
   341  
   342  ```go
   343  func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
   344  	payload, err := github.ValidatePayload(r, s.webhookSecretKey)
   345  	if err != nil { ... }
   346  	event, err := github.ParseWebHook(github.WebHookType(r), payload)
   347  	if err != nil { ... }
   348  	switch event := event.(type) {
   349  	case *github.CommitCommentEvent:
   350  		processCommitCommentEvent(event)
   351  	case *github.CreateEvent:
   352  		processCreateEvent(event)
   353  	...
   354  	}
   355  }
   356  ```
   357  
   358  Furthermore, there are libraries like [cbrgm/githubevents][] that build upon the example above and provide functions to subscribe callbacks to specific events.
   359  
   360  For complete usage of go-github, see the full [package docs][].
   361  
   362  [GitHub API v3]: https://docs.github.com/en/rest
   363  [personal access token]: https://github.com/blog/1509-personal-api-tokens
   364  [package docs]: https://pkg.go.dev/github.com/google/go-github/v64/github
   365  [GraphQL API v4]: https://developer.github.com/v4/
   366  [shurcooL/githubv4]: https://github.com/shurcooL/githubv4
   367  [GitHub webhook events]: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads
   368  [cbrgm/githubevents]: https://github.com/cbrgm/githubevents
   369  
   370  ### Testing code that uses `go-github`
   371  
   372  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.
   373  
   374  ### Integration Tests ###
   375  
   376  You can run integration tests from the `test` directory. See the integration tests [README](test/README.md).
   377  
   378  ## Contributing ##
   379  I would like to cover the entire GitHub API and contributions are of course always welcome. The
   380  calling pattern is pretty well established, so adding new methods is relatively
   381  straightforward. See [`CONTRIBUTING.md`](CONTRIBUTING.md) for details.
   382  
   383  ## Versioning ##
   384  
   385  In general, go-github follows [semver](https://semver.org/) as closely as we
   386  can for tagging releases of the package. For self-contained libraries, the
   387  application of semantic versioning is relatively straightforward and generally
   388  understood. But because go-github is a client library for the GitHub API, which
   389  itself changes behavior, and because we are typically pretty aggressive about
   390  implementing preview features of the GitHub API, we've adopted the following
   391  versioning policy:
   392  
   393  * We increment the **major version** with any incompatible change to
   394  	non-preview functionality, including changes to the exported Go API surface
   395  	or behavior of the API.
   396  * We increment the **minor version** with any backwards-compatible changes to
   397  	functionality, as well as any changes to preview functionality in the GitHub
   398  	API. GitHub makes no guarantee about the stability of preview functionality,
   399  	so neither do we consider it a stable part of the go-github API.
   400  * We increment the **patch version** with any backwards-compatible bug fixes.
   401  
   402  Preview functionality may take the form of entire methods or simply additional
   403  data returned from an otherwise non-preview method. Refer to the GitHub API
   404  documentation for details on preview functionality.
   405  
   406  ### Calendar Versioning ###
   407  
   408  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/)
   409  that they are starting to version their v3 API based on "calendar-versioning".
   410  
   411  In practice, our goal is to make per-method version overrides (at
   412  least in the core library) rare and temporary.
   413  
   414  Our understanding of the GitHub docs is that they will be revving the
   415  entire API to each new date-based version, even if only a few methods
   416  have breaking changes. Other methods will accept the new version with
   417  their existing functionality. So when a new date-based version of the
   418  GitHub API is released, we (the repo maintainers) plan to:
   419  
   420  * update each method that had breaking changes, overriding their
   421    per-method API version header. This may happen in one or multiple
   422    commits and PRs, and is all done in the main branch.
   423  
   424  * once all of the methods with breaking changes have been updated,
   425    have a final commit that bumps the default API version, and remove
   426    all of the per-method overrides. That would now get a major version
   427    bump when the next go-github release is made.
   428  
   429  ### Version Compatibility Table ###
   430  
   431  The following table identifies which version of the GitHub API is
   432  supported by this (and past) versions of this repo (go-github).
   433  Versions prior to 48.2.0 are not listed.
   434  
   435  | go-github Version | GitHub v3 API Version |
   436  | ----------------- | --------------------- |
   437  | 64.0.0            | 2022-11-28            |
   438  | 63.0.0            | 2022-11-28            |
   439  | 62.0.0            | 2022-11-28            |
   440  | 61.0.0            | 2022-11-28            |
   441  | 60.0.0            | 2022-11-28            |
   442  | 59.0.0            | 2022-11-28            |
   443  | 58.0.0            | 2022-11-28            |
   444  | 57.0.0            | 2022-11-28            |
   445  | 56.0.0            | 2022-11-28            |
   446  | 55.0.0            | 2022-11-28            |
   447  | 54.0.0            | 2022-11-28            |
   448  | 53.2.0            | 2022-11-28            |
   449  | 53.1.0            | 2022-11-28            |
   450  | 53.0.0            | 2022-11-28            |
   451  | 52.0.0            | 2022-11-28            |
   452  | 51.0.0            | 2022-11-28            |
   453  | 50.2.0            | 2022-11-28            |
   454  | 50.1.0            | 2022-11-28            |
   455  | 50.0.0            | 2022-11-28            |
   456  | 49.1.0            | 2022-11-28            |
   457  | 49.0.0            | 2022-11-28            |
   458  | 48.2.0            | 2022-11-28            |
   459  
   460  ## License ##
   461  
   462  This library is distributed under the BSD-style license found in the [LICENSE](./LICENSE)
   463  file.