Skip to content

Commit ae99ad4

Browse files
authored
Merge pull request cli#3461 from cli/jobs-url-enterprise
Fix requesting REST sub-resources on GHE
2 parents e99239c + ac348b0 commit ae99ad4

File tree

6 files changed

+49
-36
lines changed

6 files changed

+49
-36
lines changed

api/client.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ func graphQLClient(h *http.Client, hostname string) *graphql.Client {
194194

195195
// REST performs a REST request and parses the response.
196196
func (c Client) REST(hostname string, method string, p string, body io.Reader, data interface{}) error {
197-
url := ghinstance.RESTPrefix(hostname) + p
198-
req, err := http.NewRequest(method, url, body)
197+
req, err := http.NewRequest(method, restURL(hostname, p), body)
199198
if err != nil {
200199
return err
201200
}
@@ -230,6 +229,13 @@ func (c Client) REST(hostname string, method string, p string, body io.Reader, d
230229
return nil
231230
}
232231

232+
func restURL(hostname string, pathOrURL string) string {
233+
if strings.HasPrefix(pathOrURL, "https://") || strings.HasPrefix(pathOrURL, "http://") {
234+
return pathOrURL
235+
}
236+
return ghinstance.RESTPrefix(hostname) + pathOrURL
237+
}
238+
233239
func handleResponse(resp *http.Response, data interface{}) error {
234240
success := resp.StatusCode >= 200 && resp.StatusCode < 300
235241

api/client_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,26 @@ func TestRESTGetDelete(t *testing.T) {
8080
assert.NoError(t, err)
8181
}
8282

83+
func TestRESTWithFullURL(t *testing.T) {
84+
http := &httpmock.Registry{}
85+
client := NewClient(ReplaceTripper(http))
86+
87+
http.Register(
88+
httpmock.REST("GET", "api/v3/user/repos"),
89+
httpmock.StatusStringResponse(200, "{}"))
90+
http.Register(
91+
httpmock.REST("GET", "user/repos"),
92+
httpmock.StatusStringResponse(200, "{}"))
93+
94+
err := client.REST("example.com", "GET", "user/repos", nil, nil)
95+
assert.NoError(t, err)
96+
err = client.REST("example.com", "GET", "https://another.net/user/repos", nil, nil)
97+
assert.NoError(t, err)
98+
99+
assert.Equal(t, "example.com", http.Requests[0].URL.Hostname())
100+
assert.Equal(t, "another.net", http.Requests[1].URL.Hostname())
101+
}
102+
83103
func TestRESTError(t *testing.T) {
84104
fakehttp := &httpmock.Registry{}
85105
client := NewClient(ReplaceTripper(fakehttp))

pkg/cmd/run/shared/shared.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,7 @@ type JobsPayload struct {
243243

244244
func GetJobs(client *api.Client, repo ghrepo.Interface, run Run) ([]Job, error) {
245245
var result JobsPayload
246-
parsed, err := url.Parse(run.JobsURL)
247-
if err != nil {
248-
return nil, err
249-
}
250-
251-
err = client.REST(repo.RepoHost(), "GET", parsed.Path[1:], nil, &result)
252-
if err != nil {
246+
if err := client.REST(repo.RepoHost(), "GET", run.JobsURL, nil, &result); err != nil {
253247
return nil, err
254248
}
255249
return result.Jobs, nil

pkg/cmd/run/shared/test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ func TestRun(name string, id int64, s Status, c Conclusion) Run {
2626
Conclusion: c,
2727
Event: "push",
2828
HeadBranch: "trunk",
29-
JobsURL: fmt.Sprintf("/runs/%d/jobs", id),
29+
JobsURL: fmt.Sprintf("https://api.github.com/runs/%d/jobs", id),
3030
HeadCommit: Commit{
3131
Message: "cool commit",
3232
},
3333
HeadSha: "1234567890",
34-
URL: fmt.Sprintf("runs/%d", id),
34+
URL: fmt.Sprintf("https://github.com/runs/%d", id),
3535
HeadRepository: Repo{
3636
Owner: struct{ Login string }{Login: "OWNER"},
3737
Name: "REPO",
@@ -68,7 +68,7 @@ var SuccessfulJob Job = Job{
6868
Name: "cool job",
6969
StartedAt: created(),
7070
CompletedAt: updated(),
71-
URL: "jobs/10",
71+
URL: "https://github.com/jobs/10",
7272
RunID: 3,
7373
Steps: []Step{
7474
{
@@ -93,7 +93,7 @@ var FailedJob Job = Job{
9393
Name: "sad job",
9494
StartedAt: created(),
9595
CompletedAt: updated(),
96-
URL: "jobs/20",
96+
URL: "https://github.com/jobs/20",
9797
RunID: 1234,
9898
Steps: []Step{
9999
{

pkg/cmd/run/view/view_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func TestViewRun(t *testing.T) {
207207
httpmock.REST("GET", "repos/OWNER/REPO/check-runs/10/annotations"),
208208
httpmock.JSONResponse([]shared.Annotation{}))
209209
},
210-
wantOut: "\n✓ trunk successful #2898 · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: runs/3\n",
210+
wantOut: "\n✓ trunk successful #2898 · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: https://github.com/runs/3\n",
211211
},
212212
{
213213
name: "exit status, failed run",
@@ -236,7 +236,7 @@ func TestViewRun(t *testing.T) {
236236
httpmock.REST("GET", "repos/OWNER/REPO/check-runs/20/annotations"),
237237
httpmock.JSONResponse(shared.FailedJobAnnotations))
238238
},
239-
wantOut: "\nX trunk failed · 1234\nTriggered via push about 59 minutes ago\n\nJOBS\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nTo see what failed, try: gh run view 1234 --log-failed\nView this run on GitHub: runs/1234\n",
239+
wantOut: "\nX trunk failed · 1234\nTriggered via push about 59 minutes ago\n\nJOBS\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nTo see what failed, try: gh run view 1234 --log-failed\nView this run on GitHub: https://github.com/runs/1234\n",
240240
wantErr: true,
241241
},
242242
{
@@ -278,7 +278,7 @@ func TestViewRun(t *testing.T) {
278278
artifact-3
279279
280280
For more information about a job, try: gh run view --job=<job-id>
281-
View this run on GitHub: runs/3
281+
View this run on GitHub: https://github.com/runs/3
282282
`),
283283
},
284284
{
@@ -308,7 +308,7 @@ func TestViewRun(t *testing.T) {
308308
httpmock.REST("GET", "repos/OWNER/REPO/check-runs/10/annotations"),
309309
httpmock.JSONResponse([]shared.Annotation{}))
310310
},
311-
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: runs/3\n",
311+
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: https://github.com/runs/3\n",
312312
},
313313
{
314314
name: "verbose",
@@ -343,7 +343,7 @@ func TestViewRun(t *testing.T) {
343343
httpmock.REST("GET", "repos/OWNER/REPO/check-runs/20/annotations"),
344344
httpmock.JSONResponse(shared.FailedJobAnnotations))
345345
},
346-
wantOut: "\nX trunk failed · 1234\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nTo see what failed, try: gh run view 1234 --log-failed\nView this run on GitHub: runs/1234\n",
346+
wantOut: "\nX trunk failed · 1234\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nTo see what failed, try: gh run view 1234 --log-failed\nView this run on GitHub: https://github.com/runs/1234\n",
347347
},
348348
{
349349
name: "prompts for choice, one job",
@@ -380,7 +380,7 @@ func TestViewRun(t *testing.T) {
380380
opts: &ViewOptions{
381381
Prompt: true,
382382
},
383-
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: runs/3\n",
383+
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: https://github.com/runs/3\n",
384384
},
385385
{
386386
name: "interactive with log",
@@ -664,7 +664,7 @@ func TestViewRun(t *testing.T) {
664664
httpmock.REST("GET", "repos/OWNER/REPO/check-runs/10/annotations"),
665665
httpmock.JSONResponse([]shared.Annotation{}))
666666
},
667-
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\nTo see the full job log, try: gh run view --log --job=10\nView this run on GitHub: runs/3\n",
667+
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\nTo see the full job log, try: gh run view --log --job=10\nView this run on GitHub: https://github.com/runs/3\n",
668668
},
669669
{
670670
name: "interactive, multiple jobs, choose all jobs",
@@ -703,7 +703,7 @@ func TestViewRun(t *testing.T) {
703703
as.StubOne(2)
704704
as.StubOne(0)
705705
},
706-
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: runs/3\n",
706+
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\nJOBS\n✓ cool job in 4m34s (ID 10)\nX sad job in 4m34s (ID 20)\n ✓ barf the quux\n X quux the barf\n\nANNOTATIONS\nX the job is sad\nsad job: blaze.py#420\n\n\nFor more information about a job, try: gh run view --job=<job-id>\nView this run on GitHub: https://github.com/runs/3\n",
707707
},
708708
{
709709
name: "interactive, multiple jobs, choose specific jobs",
@@ -736,7 +736,7 @@ func TestViewRun(t *testing.T) {
736736
as.StubOne(2)
737737
as.StubOne(1)
738738
},
739-
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\nTo see the full job log, try: gh run view --log --job=10\nView this run on GitHub: runs/3\n",
739+
wantOut: "\n✓ trunk successful · 3\nTriggered via push about 59 minutes ago\n\n✓ cool job in 4m34s (ID 10)\n ✓ fob the barz\n ✓ barz the fob\n\nTo see the full job log, try: gh run view --log --job=10\nView this run on GitHub: https://github.com/runs/3\n",
740740
},
741741
{
742742
name: "web run",
@@ -750,8 +750,8 @@ func TestViewRun(t *testing.T) {
750750
httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/3"),
751751
httpmock.JSONResponse(shared.SuccessfulRun))
752752
},
753-
browsedURL: "runs/3",
754-
wantOut: "Opening runs/3 in your browser.\n",
753+
browsedURL: "https://github.com/runs/3",
754+
wantOut: "Opening github.com/runs/3 in your browser.\n",
755755
},
756756
{
757757
name: "web job",
@@ -768,8 +768,8 @@ func TestViewRun(t *testing.T) {
768768
httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/3"),
769769
httpmock.JSONResponse(shared.SuccessfulRun))
770770
},
771-
browsedURL: "jobs/10?check_suite_focus=true",
772-
wantOut: "Opening jobs/10 in your browser.\n",
771+
browsedURL: "https://github.com/jobs/10?check_suite_focus=true",
772+
wantOut: "Opening github.com/jobs/10 in your browser.\n",
773773
},
774774
{
775775
name: "hide job header, failure",
@@ -788,7 +788,7 @@ func TestViewRun(t *testing.T) {
788788
httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/123/artifacts"),
789789
httpmock.StringResponse(`{}`))
790790
},
791-
wantOut: "\nX trunk failed no job · 123\nTriggered via push about 59 minutes ago\n\nX This run likely failed because of a workflow file issue.\n\nFor more information, see: runs/123\n",
791+
wantOut: "\nX trunk failed no job · 123\nTriggered via push about 59 minutes ago\n\nX This run likely failed because of a workflow file issue.\n\nFor more information, see: https://github.com/runs/123\n",
792792
},
793793
{
794794
name: "hide job header, startup_failure",
@@ -807,7 +807,7 @@ func TestViewRun(t *testing.T) {
807807
httpmock.REST("GET", "repos/OWNER/REPO/actions/runs/123/artifacts"),
808808
httpmock.StringResponse(`{}`))
809809
},
810-
wantOut: "\nX trunk failed no job · 123\nTriggered via push about 59 minutes ago\n\nX This run likely failed because of a workflow file issue.\n\nFor more information, see: runs/123\n",
810+
wantOut: "\nX trunk failed no job · 123\nTriggered via push about 59 minutes ago\n\nX This run likely failed because of a workflow file issue.\n\nFor more information, see: https://github.com/runs/123\n",
811811
},
812812
}
813813

pkg/cmd/secret/list/list.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package list
33
import (
44
"fmt"
55
"net/http"
6-
"net/url"
76
"strings"
87
"time"
98

@@ -160,14 +159,8 @@ func getOrgSecrets(client *api.Client, host, orgName string) ([]*Secret, error)
160159
if secret.SelectedReposURL == "" {
161160
continue
162161
}
163-
u, err := url.Parse(secret.SelectedReposURL)
164-
if err != nil {
165-
return nil, fmt.Errorf("failed determining selected repositories for %s: %w", secret.Name, err)
166-
}
167-
168162
var result responseData
169-
err = client.REST(u.Host, "GET", u.Path[1:], nil, &result)
170-
if err != nil {
163+
if err := client.REST(host, "GET", secret.SelectedReposURL, nil, &result); err != nil {
171164
return nil, fmt.Errorf("failed determining selected repositories for %s: %w", secret.Name, err)
172165
}
173166
secret.NumSelectedRepos = result.TotalCount

0 commit comments

Comments
 (0)