Skip to content

Commit b493ec1

Browse files
authored
Merge pull request #21 from mdb/render-header
render the run header in output
2 parents fb5911b + 9847dba commit b493ec1

10 files changed

+350
-145
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
SOURCE=./...
22
GOFMT_FILES?=$$(find . -type f -name '*.go')
3-
VERSION?=0.0.4
3+
VERSION?=0.1.0
44

55
default: build
66

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Install a locally built `gh-dispatch` for use as `gh dispatch`:
5757
make install
5858
```
5959

60-
Run acceptance tests against a local `gh-dispatch` installation:
60+
Run acceptance tests against a local `gh-dispatch` installation, verifying the local `gh-dispatch` is able to trigger dispatch events and render the expected output:
6161

6262
```
6363
make acc-test

demo.gif

131 KB
Loading

demo.tape

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Set FontSize 28
4646
Set Width 1200
4747
Set Height 650
4848

49-
Type 'gh dispatch repository --repo "mdb/gh-dispatch" --event-type "hello" --client-payload "{\"name\": \"mike\"}" --workflow "Hello"'
49+
Type 'gh dispatch repository --event-type "hello" --client-payload "{\"name\": \"mike\"}" --workflow "Hello"'
5050

5151
Sleep 500ms
5252

internal/dispatch/fixtures_test.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
package dispatch
22

33
var (
4+
currentUserResponse string = `{
5+
"data": {
6+
"viewer": {
7+
"login": "mdb"
8+
}
9+
}
10+
}`
11+
412
getWorkflowsResponse string = `{
513
"total_count": 1,
614
"workflows": [{
@@ -10,17 +18,20 @@ var (
1018
}`
1119

1220
getWorkflowResponse string = `{
13-
"id": 456
21+
"id": 456,
22+
"name": "foo"
1423
}`
1524

1625
getWorkflowRunsResponse string = `{
1726
"total_count": 1,
1827
"workflow_runs": [{
1928
"id": 123,
2029
"workflow_id": 456,
30+
"event": "%s",
2131
"name": "foo",
2232
"status": "queued",
23-
"conclusion": null
33+
"conclusion": null,
34+
"jobs_url": "https://api.github.com/repos/%s/actions/runs/123/jobs"
2435
}]
2536
}`
2637

internal/dispatch/repository.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import (
44
"bytes"
55
"encoding/json"
66
"fmt"
7-
"net/http"
7+
"strings"
88

99
"github.com/MakeNowJust/heredoc"
10+
cliapi "github.com/cli/cli/v2/api"
11+
runShared "github.com/cli/cli/v2/pkg/cmd/run/shared"
1012
"github.com/cli/cli/v2/pkg/cmd/workflow/shared"
1113
"github.com/cli/cli/v2/pkg/iostreams"
12-
"github.com/cli/go-gh"
13-
"github.com/cli/go-gh/pkg/api"
1414
"github.com/spf13/cobra"
1515
)
1616

@@ -59,18 +59,25 @@ func NewCmdRepository() *cobra.Command {
5959
--workflow Hello
6060
`),
6161
RunE: func(cmd *cobra.Command, args []string) error {
62-
repo, _ := cmd.Flags().GetString("repo")
62+
r, _ := cmd.Flags().GetString("repo")
63+
repoParts := strings.Split(r, "/")
64+
repo := &ghRepo{
65+
Owner: repoParts[0],
66+
Name: repoParts[1],
67+
}
6368

6469
b := []byte(repositoryClientPayload)
6570
var repoClientPayload interface{}
6671
json.Unmarshal(b, &repoClientPayload)
6772

6873
ios := iostreams.System()
69-
74+
ghClient, _ := cliapi.NewHTTPClient(cliapi.HTTPClientOptions{
75+
Config: &Conf{},
76+
})
7077
dOptions := dispatchOptions{
71-
repo: repo,
72-
httpTransport: http.DefaultTransport,
73-
io: ios,
78+
repo: repo,
79+
httpClient: ghClient,
80+
io: ios,
7481
}
7582

7683
return repositoryDispatchRun(&repositoryDispatchOptions{
@@ -102,22 +109,16 @@ func repositoryDispatchRun(opts *repositoryDispatchOptions) error {
102109
return err
103110
}
104111

105-
client, err := gh.RESTClient(&api.ClientOptions{
106-
Transport: opts.httpTransport,
107-
AuthToken: opts.authToken,
108-
})
109-
if err != nil {
110-
return err
111-
}
112+
ghClient := cliapi.NewClientFromHTTP(opts.httpClient)
112113

113114
var in interface{}
114-
err = client.Post(fmt.Sprintf("repos/%s/dispatches", opts.repo), &buf, &in)
115+
err = ghClient.REST(opts.repo.RepoHost(), "POST", fmt.Sprintf("repos/%s/dispatches", opts.repo.RepoFullName()), &buf, &in)
115116
if err != nil {
116117
return err
117118
}
118119

119120
var wfs shared.WorkflowsPayload
120-
err = client.Get(fmt.Sprintf("repos/%s/actions/workflows", opts.repo), &wfs)
121+
err = ghClient.REST(opts.repo.RepoHost(), "GET", fmt.Sprintf("repos/%s/actions/workflows", opts.repo.RepoFullName()), nil, &wfs)
121122
if err != nil {
122123
return err
123124
}
@@ -130,15 +131,15 @@ func repositoryDispatchRun(opts *repositoryDispatchOptions) error {
130131
}
131132
}
132133

133-
runID, err := getRunID(client, opts.repo, "repository_dispatch", workflowID)
134+
runID, err := getRunID(ghClient, opts.repo, "repository_dispatch", workflowID)
134135
if err != nil {
135136
return err
136137
}
137138

138-
run, err := getRun(client, opts.repo, runID)
139+
run, err := runShared.GetRun(ghClient, opts.repo, fmt.Sprintf("%d", runID))
139140
if err != nil {
140141
return fmt.Errorf("failed to get run: %w", err)
141142
}
142143

143-
return render(opts.io, client, opts.repo, run)
144+
return render(opts.io, ghClient, opts.repo, run)
144145
}

internal/dispatch/repository_test.go

Lines changed: 113 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package dispatch
22

33
import (
44
"fmt"
5+
"net/http"
56
"net/url"
67
"testing"
78

@@ -11,7 +12,13 @@ import (
1112
)
1213

1314
func TestRepositoryDispatchRun(t *testing.T) {
14-
repo := "OWNER/REPO"
15+
ghRepo := &ghRepo{
16+
Name: "REPO",
17+
Owner: "OWNER",
18+
}
19+
repo := ghRepo.RepoFullName()
20+
event := "repository_dispatch"
21+
1522
tests := []struct {
1623
name string
1724
opts *repositoryDispatchOptions
@@ -35,36 +42,76 @@ func TestRepositoryDispatchRun(t *testing.T) {
3542
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows", repo)),
3643
httpmock.StringResponse(getWorkflowsResponse))
3744

45+
reg.Register(
46+
httpmock.GraphQL("query UserCurrent{viewer{login}}"),
47+
httpmock.StringResponse(currentUserResponse))
48+
3849
v := url.Values{}
39-
v.Set("event", "repository_dispatch")
50+
v.Set("per_page", "50")
51+
52+
reg.Register(
53+
httpmock.QueryMatcher("GET", fmt.Sprintf("repos/%s/actions/workflows/456/runs", repo), v),
54+
httpmock.StringResponse(fmt.Sprintf(getWorkflowRunsResponse, event, repo)))
55+
56+
q := url.Values{}
57+
q.Set("per_page", "100")
58+
q.Set("page", "1")
59+
60+
reg.Register(
61+
httpmock.QueryMatcher("GET", fmt.Sprintf("repos/%s/actions/workflows", repo), q),
62+
httpmock.StringResponse(fmt.Sprintf(getWorkflowRunsResponse, event, repo)))
4063

4164
reg.Register(
42-
httpmock.QueryMatcher("GET", fmt.Sprintf("repos/%s/actions/runs", repo), v),
43-
httpmock.StringResponse(getWorkflowRunsResponse))
65+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows/456", repo)),
66+
httpmock.StringResponse(getWorkflowResponse))
67+
68+
reg.Register(
69+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows/456", repo)),
70+
httpmock.StringResponse(getWorkflowResponse))
4471

4572
reg.Register(
4673
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123", repo)),
4774
httpmock.StringResponse(`{
48-
"id": 123
75+
"id": 123,
76+
"workflow_id": 456,
77+
"event": "repository_dispatch"
4978
}`))
5079

80+
reg.Register(
81+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows/456", repo)),
82+
httpmock.StringResponse(getWorkflowResponse))
83+
5184
reg.Register(
5285
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123", repo)),
53-
httpmock.StringResponse(`{
86+
httpmock.StringResponse(fmt.Sprintf(`{
5487
"id": 123,
88+
"workflow_id": 456,
5589
"status": "completed",
56-
"conclusion": "success"
57-
}`))
90+
"event": "repository_dispatch",
91+
"conclusion": "success",
92+
"jobs_url": "https://api.github.com/repos/%s/actions/runs/123/jobs"
93+
}`, repo)))
5894

5995
reg.Register(
60-
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123/attempts/1/jobs", repo)),
96+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123/jobs", repo)),
6197
httpmock.StringResponse(getJobsResponse))
6298

6399
reg.Register(
64100
httpmock.REST("GET", fmt.Sprintf("repos/%s/check-runs/123/annotations", repo)),
65101
httpmock.StringResponse("[]"))
66102
},
67-
wantOut: "Refreshing run status every 2 seconds. Press Ctrl+C to quit.\n\nhttps://github.com/OWNER/REPO/actions/runs/123\n\n\nJOBS\n✓ build in 1m59s (ID 123)\n ✓ Run actions/checkout@v2\n ✓ Test\n",
103+
wantOut: `Refreshing run status every 2 seconds. Press Ctrl+C to quit.
104+
105+
https://github.com/OWNER/REPO/actions/runs/123
106+
107+
✓ foo · 123
108+
Triggered via repository_dispatch
109+
110+
JOBS
111+
✓ build in 1m59s (ID 123)
112+
✓ Run actions/checkout@v2
113+
✓ Test
114+
`,
68115
}, {
69116
name: "unsuccessful workflow run",
70117
opts: &repositoryDispatchOptions{
@@ -81,36 +128,79 @@ func TestRepositoryDispatchRun(t *testing.T) {
81128
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows", repo)),
82129
httpmock.StringResponse(getWorkflowsResponse))
83130

131+
reg.Register(
132+
httpmock.GraphQL("query UserCurrent{viewer{login}}"),
133+
httpmock.StringResponse(currentUserResponse))
134+
84135
v := url.Values{}
85-
v.Set("event", "repository_dispatch")
136+
v.Set("per_page", "50")
137+
138+
reg.Register(
139+
httpmock.QueryMatcher("GET", fmt.Sprintf("repos/%s/actions/workflows/456/runs", repo), v),
140+
httpmock.StringResponse(fmt.Sprintf(getWorkflowRunsResponse, event, repo)))
141+
142+
q := url.Values{}
143+
q.Set("per_page", "100")
144+
q.Set("page", "1")
145+
146+
// TODO: is this correct? is it the correct response?
147+
reg.Register(
148+
httpmock.QueryMatcher("GET", fmt.Sprintf("repos/%s/actions/workflows", repo), q),
149+
httpmock.StringResponse(fmt.Sprintf(getWorkflowRunsResponse, event, repo)))
150+
151+
// TODO: is this correct? is it the correct response?
152+
reg.Register(
153+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows/456", repo)),
154+
httpmock.StringResponse(getWorkflowResponse))
86155

156+
// TODO: is this correct? is it the correct response?
87157
reg.Register(
88-
httpmock.QueryMatcher("GET", fmt.Sprintf("repos/%s/actions/runs", repo), v),
89-
httpmock.StringResponse(getWorkflowRunsResponse))
158+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows/456", repo)),
159+
httpmock.StringResponse(getWorkflowResponse))
90160

91161
reg.Register(
92162
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123", repo)),
93163
httpmock.StringResponse(`{
94-
"id": 123
164+
"id": 123,
165+
"workflow_id": 456,
166+
"event": "repository_dispatch"
95167
}`))
96168

169+
reg.Register(
170+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/workflows/456", repo)),
171+
httpmock.StringResponse(getWorkflowResponse))
172+
97173
reg.Register(
98174
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123", repo)),
99-
httpmock.StringResponse(`{
175+
httpmock.StringResponse(fmt.Sprintf(`{
100176
"id": 123,
177+
"workflow_id": 456,
101178
"status": "completed",
102-
"conclusion": "failure"
103-
}`))
179+
"event": "repository_dispatch",
180+
"conclusion": "failure",
181+
"jobs_url": "https://api.github.com/repos/%s/actions/runs/123/jobs"
182+
}`, repo)))
104183

105184
reg.Register(
106-
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123/attempts/1/jobs", repo)),
185+
httpmock.REST("GET", fmt.Sprintf("repos/%s/actions/runs/123/jobs", repo)),
107186
httpmock.StringResponse(getFailingJobsResponse))
108187

109188
reg.Register(
110189
httpmock.REST("GET", fmt.Sprintf("repos/%s/check-runs/123/annotations", repo)),
111190
httpmock.StringResponse("[]"))
112191
},
113-
wantOut: "Refreshing run status every 2 seconds. Press Ctrl+C to quit.\n\nhttps://github.com/OWNER/REPO/actions/runs/123\n\n\nJOBS\n✓ build in 1m59s (ID 123)\n ✓ Run actions/checkout@v2\n X Test\n",
192+
wantOut: `Refreshing run status every 2 seconds. Press Ctrl+C to quit.
193+
194+
https://github.com/OWNER/REPO/actions/runs/123
195+
196+
X foo · 123
197+
Triggered via repository_dispatch
198+
199+
JOBS
200+
✓ build in 1m59s (ID 123)
201+
✓ Run actions/checkout@v2
202+
X Test
203+
`,
114204
wantErr: true,
115205
errMsg: "SilentError",
116206
}, {
@@ -136,10 +226,11 @@ func TestRepositoryDispatchRun(t *testing.T) {
136226
ios.SetStdoutTTY(false)
137227
ios.SetAlternateScreenBufferEnabled(false)
138228

139-
tt.opts.repo = repo
229+
tt.opts.repo = ghRepo
140230
tt.opts.io = ios
141-
tt.opts.httpTransport = reg
142-
tt.opts.authToken = "123"
231+
tt.opts.httpClient = &http.Client{
232+
Transport: reg,
233+
}
143234

144235
t.Run(tt.name, func(t *testing.T) {
145236
err := repositoryDispatchRun(tt.opts)

0 commit comments

Comments
 (0)