@@ -21,6 +21,9 @@ import (
21
21
"fmt"
22
22
"io"
23
23
"net/http"
24
+ "time"
25
+
26
+ "golang.org/x/oauth2"
24
27
)
25
28
26
29
// AppInstallation represents a specific installation of the app (on a repo,
@@ -67,6 +70,26 @@ func (i *AppInstallation) SelectedReposTokenSource(permissions map[string]string
67
70
})
68
71
}
69
72
73
+ // SelectedReposOAuth2TokenSource creates an [oauth2.TokenSource] which can be
74
+ // used in combination with [oauth2.NewClient] to create an authenticated HTTP
75
+ // client capable of being passed to the go-github library.
76
+ func (i * AppInstallation ) SelectedReposOAuth2TokenSource (ctx context.Context , permissions map [string ]string , repos ... string ) oauth2.TokenSource {
77
+ return oauth2 .ReuseTokenSource (nil , oauth2TokenSource (func () (* oauth2.Token , error ) {
78
+ token , err := i .AccessToken (ctx , & TokenRequest {
79
+ Permissions : permissions ,
80
+ Repositories : repos ,
81
+ })
82
+ if err != nil {
83
+ return nil , fmt .Errorf ("failed to get github access token for repos %q: %w" , repos , err )
84
+ }
85
+
86
+ return & oauth2.Token {
87
+ AccessToken : token ,
88
+ Expiry : time .Now ().Add (55 * time .Minute ), // GitHub's expiration is 1 hour
89
+ }, nil
90
+ }))
91
+ }
92
+
70
93
// AccessTokenAllRepos calls the GitHub API to generate a new access token for
71
94
// this application installation with the requested permissions and all granted
72
95
// repositories.
@@ -93,6 +116,25 @@ func (i *AppInstallation) AllReposTokenSource(permissions map[string]string) Tok
93
116
})
94
117
}
95
118
119
+ // AllReposOAuth2TokenSource creates an [oauth2.TokenSource] which can be used
120
+ // in combination with [oauth2.NewClient] to create an authenticated HTTP client
121
+ // capable of being passed to the go-github library.
122
+ func (i * AppInstallation ) AllReposOAuth2TokenSource (ctx context.Context , permissions map [string ]string ) oauth2.TokenSource {
123
+ return oauth2 .ReuseTokenSource (nil , oauth2TokenSource (func () (* oauth2.Token , error ) {
124
+ token , err := i .AccessTokenAllRepos (ctx , & TokenRequestAllRepos {
125
+ Permissions : permissions ,
126
+ })
127
+ if err != nil {
128
+ return nil , fmt .Errorf ("failed to get github access token for all repos: %w" , err )
129
+ }
130
+
131
+ return & oauth2.Token {
132
+ AccessToken : token ,
133
+ Expiry : time .Now ().Add (55 * time .Minute ), // GitHub's expiration is 1 hour
134
+ }, nil
135
+ }))
136
+ }
137
+
96
138
// githubAccessToken calls the GitHub API to generate a new access token with
97
139
// provided JSON payload bytes.
98
140
func (i * AppInstallation ) githubAccessToken (ctx context.Context , requestJSON []byte ) (string , error ) {
0 commit comments