Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 13 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ For more sample code snippets, head over to the

### Authentication ###

Use the `github.WithAuthToken` options method to configure your client to authenticate using an
OAuth token (for example, a [personal access token][]). This is what is needed
for a majority of use cases aside from GitHub Apps.
Use the `github.WithAuthToken` options method to configure your client to authenticate
using an OAuth token (for example, a [personal access token][]).
This is what is needed for a majority of use cases aside from GitHub Apps.

```go
client, err := github.NewClient(github.WithAuthToken("... your access token ..."))
Expand All @@ -112,23 +112,19 @@ if err != nil {
}
```

To support more advanced use cases; you can use the `github.WithTransport` option to provide a
custom `http.RoundTripper` that handles authentication for you, or the `github.WithHTTPClient`
option to provide a custom `http.Client`. As an example; you can use the `oauth2.Transport`
from the [golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2) package to handle OAuth
token refreshing for you.
To support more advanced use cases; you can use the `github.WithTokenSource` option to provide a
`oauth2.TokenSource` that handles authentication for you.

Note that when using an authenticated Client, all calls made by the client will
include the specified OAuth token. Therefore, authenticated clients should
almost never be shared between different users.

For API methods that require HTTP Basic Authentication, use the
[`BasicAuthTransport`](https://pkg.go.dev/github.com/google/go-github/v93/github#BasicAuthTransport).
`github.WithBasicAuth` option.

#### As a GitHub App ####

GitHub Apps authentication can be provided by different pkgs like [bradleyfalzon/ghinstallation](https://github.com/bradleyfalzon/ghinstallation)
or [jferrl/go-githubauth](https://github.com/jferrl/go-githubauth).
GitHub Apps authentication can be provided by [jferrl/go-githubauth](https://github.com/jferrl/go-githubauth).

> **Note**: Most endpoints (ex. [`GET /rate_limit`]) require access token authentication
> while a few others (ex. [`GET /app/hook/deliveries`]) require [JWT] authentication.
Expand All @@ -137,40 +133,8 @@ or [jferrl/go-githubauth](https://github.com/jferrl/go-githubauth).
[`GET /app/hook/deliveries`]: https://docs.github.com/en/rest/apps/webhooks#list-deliveries-for-an-app-webhook
[JWT]: https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps#authenticating-as-a-github-app

`ghinstallation` provides `Transport`, which implements `http.RoundTripper` to provide authentication as an installation for GitHub Apps.

Here is an example of how to authenticate as a GitHub App using the `ghinstallation` package:

```go
import (
"net/http"

"github.com/bradleyfalzon/ghinstallation/v2"
"github.com/google/go-github/v93/github"
)

func main() {
// Wrap the shared transport for use with the integration ID 1 authenticating with installation ID 99.
itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "2016-10-19.private-key.pem")

// Or for endpoints that require JWT authentication
// itr, err := ghinstallation.NewAppsTransportKeyFromFile(http.DefaultTransport, 1, "2016-10-19.private-key.pem")

if err != nil {
// Handle error.
}

// Use installation transport with client.
client, err := github.NewClient(github.WithTransport(itr))
if err != nil {
// Handle error.
}

// Use client...
}
```

`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.
`go-githubauth` implements a set of functions that can create `oauth2.TokenSource` implementations.
The `oauth2.TokenSource` can be configured for the `github.Client` using the `github.WithTokenSource` option.

`NewApplicationTokenSource` accepts either the App's client ID (a `string`, which GitHub now recommends) or its legacy app ID (an `int64`).

Expand Down Expand Up @@ -208,12 +172,7 @@ func main() {

installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)

// oauth2.NewClient uses oauth2.ReuseTokenSource to reuse the token until it expires.
// The token will be automatically refreshed when it expires.
// InstallationTokenSource has the mechanism to refresh the token when it expires.
httpClient := oauth2.NewClient(context.Background(), installationTokenSource)

client, err := github.NewClient(github.WithHTTPClient(httpClient))
client, err := github.NewClient(github.WithTokenSource(installationTokenSource))
if err != nil {
// Handle error.
}
Expand Down Expand Up @@ -290,8 +249,8 @@ set the client `DisableRateLimitCheck` to `true` so the client doesn't track the

If the client is an [OAuth app](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api#primary-rate-limit-for-oauth-apps)
you can use the apps higher rate limit to request public data by using the
`UnauthenticatedRateLimitedTransport` to make calls as the app instead of as
the user.
`github.WithBasicAuth` option to configure the client to make calls as the
app instead of as the user.

### Accepted Status ###

Expand Down Expand Up @@ -328,7 +287,7 @@ import (
_ "github.com/bartventer/httpcache/store/memcache" // Register the in-memory backend
)

client, err := github.NewClient(github.WithHTTPClient(httpcache.NewClient("memcache://")), github.WithAuthToken(os.Getenv("GITHUB_TOKEN")))
client, err := github.NewClient(github.WithTransport(httpcache.NewTransport("memcache://")), github.WithAuthToken(os.Getenv("GITHUB_TOKEN")))
if err != nil {
// Handle error.
}
Expand Down
63 changes: 0 additions & 63 deletions example/basicauth/main.go

This file was deleted.

6 changes: 3 additions & 3 deletions example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ go 1.26.0

require (
github.com/ProtonMail/go-crypto v1.5.2
github.com/bradleyfalzon/ghinstallation/v2 v2.19.0
github.com/gofri/go-github-pagination v1.0.1
github.com/gofri/go-github-ratelimit/v2 v2.0.2
github.com/google/go-github/otel/v93 v93.0.0
github.com/google/go-github/v93 v93.0.0
github.com/jferrl/go-githubauth v1.9.1
github.com/sigstore/sigstore-go v1.2.2
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.47.0
go.opentelemetry.io/otel/sdk v1.47.0
Expand Down Expand Up @@ -50,10 +50,9 @@ require (
github.com/go-openapi/swag/yamlutils v0.26.1 // indirect
github.com/go-openapi/validate v0.26.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/google/certificate-transparency-go v1.3.3 // indirect
github.com/google/go-containerregistry v0.21.7 // indirect
github.com/google/go-github/v88 v88.0.0 // indirect
github.com/google/go-querystring v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
Expand Down Expand Up @@ -81,6 +80,7 @@ require (
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/mod v0.41.0 // indirect
golang.org/x/net v0.58.0 // indirect
golang.org/x/oauth2 v0.37.0 // indirect
golang.org/x/sync v0.23.0 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.42.0 // indirect
Expand Down
12 changes: 4 additions & 8 deletions example/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ github.com/aws/smithy-go v1.26.0 h1:9ouqbi+NyKP7fV3Te7UElCwdAb6Y8uk7LGwPE5tVe/s=
github.com/aws/smithy-go v1.26.0/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bradleyfalzon/ghinstallation/v2 v2.19.0 h1:KQfD+43pRw9NUJhGycGrFr9vF1MubZacksKol1gomFI=
github.com/bradleyfalzon/ghinstallation/v2 v2.19.0/go.mod h1:fe5ECIhCdEnxwLiBlNTxx9CP455wt42BELnlDVMvaAA=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
Expand Down Expand Up @@ -162,8 +160,6 @@ github.com/gofri/go-github-pagination v1.0.1 h1:j5uJRx65i/Ta2M0QSgiPcyokY69JnCQg
github.com/gofri/go-github-pagination v1.0.1/go.mod h1:Qij55Fb4fNPjam3SB+8cLnqp4pgR8RGMyIspYXcyHX0=
github.com/gofri/go-github-ratelimit/v2 v2.0.2 h1:gS8wAS1jTmlWGdTjAM7KIpsLjwY1S0S/gKK5hthfSXM=
github.com/gofri/go-github-ratelimit/v2 v2.0.2/go.mod h1:YBQt4gTbdcbMjJFT05YFEaECwH78P5b0IwrnbLiHGdE=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
Expand All @@ -175,8 +171,6 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.21.7 h1:/vPFuVXDjtFREsVArW+0h1CIl5urnOhzei4X2DMW9IU=
github.com/google/go-containerregistry v0.21.7/go.mod h1:kjSbt7/zMsKLWfnHrIvKvhXHUw91jbe9DNjPPJ32gXE=
github.com/google/go-github/v88 v88.0.0 h1:dZA9IKkPK1eXZj4ypngnpRj5FwdpTv4whix2PrQMP7M=
github.com/google/go-github/v88 v88.0.0/go.mod h1:rufTDgn2N45wjhukLTyxmvc9nilSp3mr3Rgtt6b1MPw=
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
Expand Down Expand Up @@ -225,6 +219,8 @@ github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7P
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU=
github.com/jellydator/ttlcache/v3 v3.4.0 h1:YS4P125qQS0tNhtL6aeYkheEaB/m8HCqdMMP4mnWdTY=
github.com/jellydator/ttlcache/v3 v3.4.0/go.mod h1:Hw9EgjymziQD3yGsQdf1FqFdpp7YjFMd4Srg5EJlgD4=
github.com/jferrl/go-githubauth v1.9.1 h1:gDBgNgPxU4gL0yWKf6FOwKCdLb3ICHPVMQrPEq+xq0I=
github.com/jferrl/go-githubauth v1.9.1/go.mod h1:HkuzaWMeDf+S09Dq/5wlBwPeho9ZZm3MixLdD2WTqO0=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/letsencrypt/boulder v0.20260309.0 h1:kZynrxK3QfqLGx6hhoz+Rfs3hgltJs1p9Mp+4+VwnY0=
Expand Down Expand Up @@ -342,8 +338,8 @@ golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98=
golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
Expand Down
43 changes: 22 additions & 21 deletions example/newfilewithappauth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,38 @@
package main

import (
"bufio"
"context"
"fmt"
"log"
"net/http"
"os"
"time"
"strings"

"github.com/bradleyfalzon/ghinstallation/v2"
"github.com/google/go-github/v93/github"
"github.com/jferrl/go-githubauth"
)

func main() {
const gitHost = "https://git.api.com"
gitHost := "https://git.api.com"

privatePem, err := os.ReadFile("path/to/pem")
r := bufio.NewReader(os.Stdin)
fmt.Print("GitHub App Client ID: ")
clientID, _ := r.ReadString('\n')

fmt.Print("Path to GitHub App Private Key (.pem): ")
pemPath, _ := r.ReadString('\n')
privateKey, err := os.ReadFile(strings.TrimSpace(pemPath))
if err != nil {
log.Fatalf("failed to read pem: %v", err)
log.Fatalf("failed to read private key: %v", err)
}

itr, err := ghinstallation.NewAppsTransport(http.DefaultTransport, 10, privatePem)
appTokenSource, err := githubauth.NewApplicationTokenSource(strings.TrimSpace(clientID), privateKey)
if err != nil {
log.Fatalf("failed to create app transport: %v", err)
log.Fatalf("failed to create app token source: %v", err)
}
itr.BaseURL = gitHost

// create git client with app transport
client, err := github.NewClient(github.WithHTTPClient(&http.Client{
Transport: itr,
Timeout: time.Second * 30,
}), github.WithEnterpriseURLs(gitHost, gitHost))
client, err := github.NewClient(github.WithTokenSource(appTokenSource), github.WithURLs(&gitHost, &gitHost))
if err != nil {
log.Fatalf("failed to create git client for app: %v", err)
}
Expand All @@ -52,18 +55,16 @@ func main() {
var installID int64
for _, val := range installations {
installID = val.GetID()
break
}

token, _, err := client.Apps.CreateInstallationToken(
context.Background(),
installID,
&github.InstallationTokenOptions{},
)
if err != nil {
log.Fatalf("failed to create installation token: %v", err)
if installID == 0 {
log.Fatal("no installation found")
}

apiClient, err := github.NewClient(github.WithAuthToken(token.GetToken()), github.WithEnterpriseURLs(gitHost, gitHost))
installationTokenSource := githubauth.NewInstallationTokenSource(installID, appTokenSource, githubauth.WithBaseURL(gitHost))

apiClient, err := github.NewClient(github.WithTokenSource(installationTokenSource), github.WithURLs(&gitHost, &gitHost))
if err != nil {
log.Fatalf("failed to create new git client with token: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions example/ratelimit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ func main() {
}),
)

paginator := githubpagination.NewClient(rateLimiter,
paginator := githubpagination.New(rateLimiter,
githubpagination.WithPerPage(100), // default to 100 results per page
)
client, err := github.NewClient(github.WithHTTPClient(paginator))
client, err := github.NewClient(github.WithTransport(paginator))
if err != nil {
log.Fatalf("Error creating GitHub client: %v", err)
}
Expand Down
Loading
Loading