X Tutup
Skip to content

Commit a79a0bb

Browse files
committed
Add support for GH_TOKEN and GH_ENTERPRISE_TOKEN
1 parent 6e1e62f commit a79a0bb

File tree

5 files changed

+214
-59
lines changed

5 files changed

+214
-59
lines changed

cmd/gh/main.go

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,15 @@ func main() {
136136

137137
cs := cmdFactory.IOStreams.ColorScheme()
138138

139-
authCheckEnabled := os.Getenv("GITHUB_TOKEN") == "" &&
140-
os.Getenv("GITHUB_ENTERPRISE_TOKEN") == "" &&
141-
cmd != nil && cmdutil.IsAuthCheckEnabled(cmd)
142-
if authCheckEnabled {
143-
if !cmdutil.CheckAuth(cfg) {
144-
fmt.Fprintln(stderr, cs.Bold("Welcome to GitHub CLI!"))
145-
fmt.Fprintln(stderr)
146-
fmt.Fprintln(stderr, "To authenticate, please run `gh auth login`.")
147-
fmt.Fprintln(stderr, "You can also set the GITHUB_TOKEN environment variable, if preferred.")
148-
os.Exit(4)
149-
}
139+
// _, _, tokenPresent := config.AuthTokenFromEnv(ghinstance.OverridableDefault())
140+
// authCheckEnabled := !tokenPresent && cmd != nil && cmdutil.IsAuthCheckEnabled(cmd)
141+
authCheckEnabled := cmd != nil && cmdutil.IsAuthCheckEnabled(cmd)
142+
if authCheckEnabled && !cmdutil.CheckAuth(cfg) {
143+
fmt.Fprintln(stderr, cs.Bold("Welcome to GitHub CLI!"))
144+
fmt.Fprintln(stderr)
145+
fmt.Fprintln(stderr, "To authenticate, please run `gh auth login`.")
146+
fmt.Fprintln(stderr, "You can also set the one of the oauth token environment variables, if preferred.")
147+
os.Exit(4)
150148
}
151149

152150
rootCmd.SetArgs(expandedArgs)
@@ -248,8 +246,8 @@ func basicClient(currentVersion string) (*api.Client, error) {
248246
}
249247
opts = append(opts, api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", currentVersion)))
250248

251-
token := os.Getenv("GITHUB_TOKEN")
252-
if token == "" {
249+
token, _, ok := config.AuthTokenFromEnv(ghinstance.Default())
250+
if !ok {
253251
if c, err := config.ParseDefaultConfig(); err == nil {
254252
token, _ = c.Get(ghinstance.Default(), "oauth_token")
255253
}

internal/config/from_env.go

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88
)
99

1010
const (
11+
GH_TOKEN = "GH_TOKEN"
1112
GITHUB_TOKEN = "GITHUB_TOKEN"
13+
GH_ENTERPRISE_TOKEN = "GH_ENTERPRISE_TOKEN"
1214
GITHUB_ENTERPRISE_TOKEN = "GITHUB_ENTERPRISE_TOKEN"
1315
)
1416

@@ -28,7 +30,8 @@ func (c *envConfig) Hosts() ([]string, error) {
2830
hasDefault = true
2931
}
3032
}
31-
if (err != nil || !hasDefault) && os.Getenv(GITHUB_TOKEN) != "" {
33+
_, _, found := AuthTokenFromEnv(ghinstance.Default())
34+
if (err != nil || !hasDefault) && found {
3235
hosts = append([]string{ghinstance.Default()}, hosts...)
3336
return hosts, nil
3437
}
@@ -42,13 +45,8 @@ func (c *envConfig) Get(hostname, key string) (string, error) {
4245

4346
func (c *envConfig) GetWithSource(hostname, key string) (string, string, error) {
4447
if hostname != "" && key == "oauth_token" {
45-
envName := GITHUB_TOKEN
46-
if ghinstance.IsEnterprise(hostname) {
47-
envName = GITHUB_ENTERPRISE_TOKEN
48-
}
49-
50-
if value := os.Getenv(envName); value != "" {
51-
return value, envName, nil
48+
if value, name, found := AuthTokenFromEnv(hostname); found {
49+
return value, name, nil
5250
}
5351
}
5452

@@ -57,15 +55,28 @@ func (c *envConfig) GetWithSource(hostname, key string) (string, string, error)
5755

5856
func (c *envConfig) CheckWriteable(hostname, key string) error {
5957
if hostname != "" && key == "oauth_token" {
60-
envName := GITHUB_TOKEN
61-
if ghinstance.IsEnterprise(hostname) {
62-
envName = GITHUB_ENTERPRISE_TOKEN
58+
if _, name, found := AuthTokenFromEnv(hostname); found {
59+
return fmt.Errorf("read-only token in %s cannot be modified", name)
6360
}
61+
}
62+
63+
return c.Config.CheckWriteable(hostname, key)
64+
}
6465

65-
if os.Getenv(envName) != "" {
66-
return fmt.Errorf("read-only token in %s cannot be modified", envName)
66+
func AuthTokenFromEnv(hostname string) (string, string, bool) {
67+
if ghinstance.IsEnterprise(hostname) {
68+
if token, found := os.LookupEnv(GH_ENTERPRISE_TOKEN); found {
69+
return token, GH_ENTERPRISE_TOKEN, found
6770
}
71+
72+
token, found := os.LookupEnv(GITHUB_ENTERPRISE_TOKEN)
73+
return token, GITHUB_ENTERPRISE_TOKEN, found
6874
}
6975

70-
return c.Config.CheckWriteable(hostname, key)
76+
if token, found := os.LookupEnv(GH_TOKEN); found {
77+
return token, GH_TOKEN, found
78+
}
79+
80+
token, found := os.LookupEnv(GITHUB_TOKEN)
81+
return token, GITHUB_TOKEN, found
7182
}

internal/config/from_env_test.go

Lines changed: 171 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ import (
1111
func TestInheritEnv(t *testing.T) {
1212
orig_GITHUB_TOKEN := os.Getenv("GITHUB_TOKEN")
1313
orig_GITHUB_ENTERPRISE_TOKEN := os.Getenv("GITHUB_ENTERPRISE_TOKEN")
14+
orig_GH_TOKEN := os.Getenv("GH_TOKEN")
15+
orig_GH_ENTERPRISE_TOKEN := os.Getenv("GH_ENTERPRISE_TOKEN")
1416
t.Cleanup(func() {
1517
os.Setenv("GITHUB_TOKEN", orig_GITHUB_TOKEN)
1618
os.Setenv("GITHUB_ENTERPRISE_TOKEN", orig_GITHUB_ENTERPRISE_TOKEN)
19+
os.Setenv("GH_TOKEN", orig_GH_TOKEN)
20+
os.Setenv("GH_ENTERPRISE_TOKEN", orig_GH_ENTERPRISE_TOKEN)
1721
})
1822

1923
type wants struct {
@@ -28,15 +32,15 @@ func TestInheritEnv(t *testing.T) {
2832
baseConfig string
2933
GITHUB_TOKEN string
3034
GITHUB_ENTERPRISE_TOKEN string
35+
GH_TOKEN string
36+
GH_ENTERPRISE_TOKEN string
3137
hostname string
3238
wants wants
3339
}{
3440
{
35-
name: "blank",
36-
baseConfig: ``,
37-
GITHUB_TOKEN: "",
38-
GITHUB_ENTERPRISE_TOKEN: "",
39-
hostname: "github.com",
41+
name: "blank",
42+
baseConfig: ``,
43+
hostname: "github.com",
4044
wants: wants{
4145
hosts: []string(nil),
4246
token: "",
@@ -45,11 +49,10 @@ func TestInheritEnv(t *testing.T) {
4549
},
4650
},
4751
{
48-
name: "GITHUB_TOKEN over blank config",
49-
baseConfig: ``,
50-
GITHUB_TOKEN: "OTOKEN",
51-
GITHUB_ENTERPRISE_TOKEN: "",
52-
hostname: "github.com",
52+
name: "GITHUB_TOKEN over blank config",
53+
baseConfig: ``,
54+
GITHUB_TOKEN: "OTOKEN",
55+
hostname: "github.com",
5356
wants: wants{
5457
hosts: []string{"github.com"},
5558
token: "OTOKEN",
@@ -58,11 +61,34 @@ func TestInheritEnv(t *testing.T) {
5861
},
5962
},
6063
{
61-
name: "GITHUB_TOKEN not applicable to GHE",
62-
baseConfig: ``,
63-
GITHUB_TOKEN: "OTOKEN",
64-
GITHUB_ENTERPRISE_TOKEN: "",
65-
hostname: "example.org",
64+
name: "GH_TOKEN over blank config",
65+
baseConfig: ``,
66+
GH_TOKEN: "OTOKEN",
67+
hostname: "github.com",
68+
wants: wants{
69+
hosts: []string{"github.com"},
70+
token: "OTOKEN",
71+
source: "GH_TOKEN",
72+
writeable: false,
73+
},
74+
},
75+
{
76+
name: "GITHUB_TOKEN not applicable to GHE",
77+
baseConfig: ``,
78+
GITHUB_TOKEN: "OTOKEN",
79+
hostname: "example.org",
80+
wants: wants{
81+
hosts: []string{"github.com"},
82+
token: "",
83+
source: "~/.config/gh/config.yml",
84+
writeable: true,
85+
},
86+
},
87+
{
88+
name: "GH_TOKEN not applicable to GHE",
89+
baseConfig: ``,
90+
GH_TOKEN: "OTOKEN",
91+
hostname: "example.org",
6692
wants: wants{
6793
hosts: []string{"github.com"},
6894
token: "",
@@ -73,7 +99,6 @@ func TestInheritEnv(t *testing.T) {
7399
{
74100
name: "GITHUB_ENTERPRISE_TOKEN over blank config",
75101
baseConfig: ``,
76-
GITHUB_TOKEN: "",
77102
GITHUB_ENTERPRISE_TOKEN: "ENTOKEN",
78103
hostname: "example.org",
79104
wants: wants{
@@ -83,16 +108,26 @@ func TestInheritEnv(t *testing.T) {
83108
writeable: false,
84109
},
85110
},
111+
{
112+
name: "GH_ENTERPRISE_TOKEN over blank config",
113+
baseConfig: ``,
114+
GH_ENTERPRISE_TOKEN: "ENTOKEN",
115+
hostname: "example.org",
116+
wants: wants{
117+
hosts: []string(nil),
118+
token: "ENTOKEN",
119+
source: "GH_ENTERPRISE_TOKEN",
120+
writeable: false,
121+
},
122+
},
86123
{
87124
name: "token from file",
88125
baseConfig: heredoc.Doc(`
89126
hosts:
90127
github.com:
91128
oauth_token: OTOKEN
92129
`),
93-
GITHUB_TOKEN: "",
94-
GITHUB_ENTERPRISE_TOKEN: "",
95-
hostname: "github.com",
130+
hostname: "github.com",
96131
wants: wants{
97132
hosts: []string{"github.com"},
98133
token: "OTOKEN",
@@ -107,38 +142,147 @@ func TestInheritEnv(t *testing.T) {
107142
github.com:
108143
oauth_token: OTOKEN
109144
`),
110-
GITHUB_TOKEN: "ENVTOKEN",
111-
GITHUB_ENTERPRISE_TOKEN: "",
112-
hostname: "github.com",
145+
GITHUB_TOKEN: "ENVTOKEN",
146+
hostname: "github.com",
113147
wants: wants{
114148
hosts: []string{"github.com"},
115149
token: "ENVTOKEN",
116150
source: "GITHUB_TOKEN",
117151
writeable: false,
118152
},
119153
},
154+
{
155+
name: "GH_TOKEN shadows token from file",
156+
baseConfig: heredoc.Doc(`
157+
hosts:
158+
github.com:
159+
oauth_token: OTOKEN
160+
`),
161+
GH_TOKEN: "ENVTOKEN",
162+
hostname: "github.com",
163+
wants: wants{
164+
hosts: []string{"github.com"},
165+
token: "ENVTOKEN",
166+
source: "GH_TOKEN",
167+
writeable: false,
168+
},
169+
},
170+
{
171+
name: "GITHUB_ENTERPRISE_TOKEN shadows token from file",
172+
baseConfig: heredoc.Doc(`
173+
hosts:
174+
example.org:
175+
oauth_token: OTOKEN
176+
`),
177+
GITHUB_ENTERPRISE_TOKEN: "ENVTOKEN",
178+
hostname: "example.org",
179+
wants: wants{
180+
hosts: []string{"example.org"},
181+
token: "ENVTOKEN",
182+
source: "GITHUB_ENTERPRISE_TOKEN",
183+
writeable: false,
184+
},
185+
},
186+
{
187+
name: "GH_ENTERPRISE_TOKEN shadows token from file",
188+
baseConfig: heredoc.Doc(`
189+
hosts:
190+
example.org:
191+
oauth_token: OTOKEN
192+
`),
193+
GH_ENTERPRISE_TOKEN: "ENVTOKEN",
194+
hostname: "example.org",
195+
wants: wants{
196+
hosts: []string{"example.org"},
197+
token: "ENVTOKEN",
198+
source: "GH_ENTERPRISE_TOKEN",
199+
writeable: false,
200+
},
201+
},
202+
{
203+
name: "GH_TOKEN shadows token from GITHUB_TOKEN",
204+
baseConfig: ``,
205+
GH_TOKEN: "GHTOKEN",
206+
GITHUB_TOKEN: "GITHUBTOKEN",
207+
hostname: "github.com",
208+
wants: wants{
209+
hosts: []string{"github.com"},
210+
token: "GHTOKEN",
211+
source: "GH_TOKEN",
212+
writeable: false,
213+
},
214+
},
215+
{
216+
name: "GH_ENTERPRISE_TOKEN shadows token from GITHUB_ENTERPRISE_TOKEN",
217+
baseConfig: ``,
218+
GH_ENTERPRISE_TOKEN: "GHTOKEN",
219+
GITHUB_ENTERPRISE_TOKEN: "GITHUBTOKEN",
220+
hostname: "example.org",
221+
wants: wants{
222+
hosts: []string(nil),
223+
token: "GHTOKEN",
224+
source: "GH_ENTERPRISE_TOKEN",
225+
writeable: false,
226+
},
227+
},
120228
{
121229
name: "GITHUB_TOKEN adds host entry",
122230
baseConfig: heredoc.Doc(`
123231
hosts:
124232
example.org:
125233
oauth_token: OTOKEN
126234
`),
127-
GITHUB_TOKEN: "ENVTOKEN",
128-
GITHUB_ENTERPRISE_TOKEN: "",
129-
hostname: "github.com",
235+
GITHUB_TOKEN: "ENVTOKEN",
236+
hostname: "github.com",
130237
wants: wants{
131238
hosts: []string{"github.com", "example.org"},
132239
token: "ENVTOKEN",
133240
source: "GITHUB_TOKEN",
134241
writeable: false,
135242
},
136243
},
244+
{
245+
name: "GH_TOKEN adds host entry",
246+
baseConfig: heredoc.Doc(`
247+
hosts:
248+
example.org:
249+
oauth_token: OTOKEN
250+
`),
251+
GH_TOKEN: "ENVTOKEN",
252+
hostname: "github.com",
253+
wants: wants{
254+
hosts: []string{"github.com", "example.org"},
255+
token: "ENVTOKEN",
256+
source: "GH_TOKEN",
257+
writeable: false,
258+
},
259+
},
137260
}
138261
for _, tt := range tests {
139262
t.Run(tt.name, func(t *testing.T) {
140-
os.Setenv("GITHUB_TOKEN", tt.GITHUB_TOKEN)
141-
os.Setenv("GITHUB_ENTERPRISE_TOKEN", tt.GITHUB_ENTERPRISE_TOKEN)
263+
if tt.GITHUB_TOKEN != "" {
264+
os.Setenv("GITHUB_TOKEN", tt.GITHUB_TOKEN)
265+
} else {
266+
os.Unsetenv("GITHUB_TOKEN")
267+
}
268+
269+
if tt.GITHUB_ENTERPRISE_TOKEN != "" {
270+
os.Setenv("GITHUB_ENTERPRISE_TOKEN", tt.GITHUB_ENTERPRISE_TOKEN)
271+
} else {
272+
os.Unsetenv("GITHUB_ENTERPRISE_TOKEN")
273+
}
274+
275+
if tt.GH_TOKEN != "" {
276+
os.Setenv("GH_TOKEN", tt.GH_TOKEN)
277+
} else {
278+
os.Unsetenv("GH_TOKEN")
279+
}
280+
281+
if tt.GH_ENTERPRISE_TOKEN != "" {
282+
os.Setenv("GH_ENTERPRISE_TOKEN", tt.GH_ENTERPRISE_TOKEN)
283+
} else {
284+
os.Unsetenv("GH_ENTERPRISE_TOKEN")
285+
}
142286

143287
baseCfg := NewFromString(tt.baseConfig)
144288
cfg := InheritEnv(baseCfg)

0 commit comments

Comments
 (0)
X Tutup