X Tutup
Skip to content

Commit 3a088e4

Browse files
author
Nate Smith
authored
Merge pull request cli#5069 from hirasawayuki/fix-pr-checks-cmd
Fix duplicates check results returned by `gh pr checks`
2 parents e17964c + b0fd9c6 commit 3a088e4

File tree

3 files changed

+253
-14
lines changed

3 files changed

+253
-14
lines changed

api/queries_pr.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,7 @@ type PullRequest struct {
8080
Commit struct {
8181
StatusCheckRollup struct {
8282
Contexts struct {
83-
Nodes []struct {
84-
TypeName string `json:"__typename"`
85-
Name string `json:"name"`
86-
Context string `json:"context,omitempty"`
87-
State string `json:"state,omitempty"`
88-
Status string `json:"status"`
89-
Conclusion string `json:"conclusion"`
90-
StartedAt time.Time `json:"startedAt"`
91-
CompletedAt time.Time `json:"completedAt"`
92-
DetailsURL string `json:"detailsUrl"`
93-
TargetURL string `json:"targetUrl,omitempty"`
94-
}
83+
Nodes []CheckContext
9584
PageInfo struct {
9685
HasNextPage bool
9786
EndCursor string
@@ -113,6 +102,19 @@ type PullRequest struct {
113102
ReviewRequests ReviewRequests
114103
}
115104

105+
type CheckContext struct {
106+
TypeName string `json:"__typename"`
107+
Name string `json:"name"`
108+
Context string `json:"context,omitempty"`
109+
State string `json:"state,omitempty"`
110+
Status string `json:"status"`
111+
Conclusion string `json:"conclusion"`
112+
StartedAt time.Time `json:"startedAt"`
113+
CompletedAt time.Time `json:"completedAt"`
114+
DetailsURL string `json:"detailsUrl"`
115+
TargetURL string `json:"targetUrl,omitempty"`
116+
}
117+
116118
type PRRepository struct {
117119
ID string `json:"id"`
118120
Name string `json:"name"`

pkg/cmd/pr/checks/checks.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
"github.com/MakeNowJust/heredoc"
9+
"github.com/cli/cli/v2/api"
910
"github.com/cli/cli/v2/internal/ghrepo"
1011
"github.com/cli/cli/v2/pkg/cmd/pr/shared"
1112
"github.com/cli/cli/v2/pkg/cmdutil"
@@ -41,7 +42,7 @@ func NewCmdChecks(f *cmdutil.Factory, runF func(*ChecksOptions) error) *cobra.Co
4142
Show CI status for a single pull request.
4243
4344
Without an argument, the pull request that belongs to the current branch
44-
is selected.
45+
is selected.
4546
`),
4647
Args: cobra.MaximumNArgs(1),
4748
RunE: func(cmd *cobra.Command, args []string) error {
@@ -118,7 +119,8 @@ func checksRun(opts *ChecksOptions) error {
118119

119120
outputs := []output{}
120121

121-
for _, c := range pr.StatusCheckRollup.Nodes[0].Commit.StatusCheckRollup.Contexts.Nodes {
122+
checkContexts := pr.StatusCheckRollup.Nodes[0].Commit.StatusCheckRollup.Contexts.Nodes
123+
for _, c := range eliminateDuplicates(checkContexts) {
122124
mark := "✓"
123125
bucket := "pass"
124126
state := c.State
@@ -245,3 +247,26 @@ func checksRun(opts *ChecksOptions) error {
245247

246248
return nil
247249
}
250+
251+
func eliminateDuplicates(checkContexts []api.CheckContext) []api.CheckContext {
252+
// To return the most recent check, sort in descending order by StartedAt.
253+
sort.Slice(checkContexts, func(i, j int) bool { return checkContexts[i].StartedAt.After(checkContexts[j].StartedAt) })
254+
255+
m := make(map[string]struct{})
256+
unique := make([]api.CheckContext, 0, len(checkContexts))
257+
258+
// Eliminate duplicates using Name or Context.
259+
for _, ctx := range checkContexts {
260+
key := ctx.Name
261+
if key == "" {
262+
key = ctx.Context
263+
}
264+
if _, ok := m[key]; ok {
265+
continue
266+
}
267+
unique = append(unique, ctx)
268+
m[key] = struct{}{}
269+
}
270+
271+
return unique
272+
}

pkg/cmd/pr/checks/checks_test.go

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"encoding/json"
66
"io"
77
"os"
8+
"reflect"
89
"testing"
10+
"time"
911

1012
"github.com/cli/cli/v2/api"
1113
"github.com/cli/cli/v2/internal/ghrepo"
@@ -239,3 +241,213 @@ func TestChecksRun_web(t *testing.T) {
239241
})
240242
}
241243
}
244+
245+
func TestEliminateDupulicates(t *testing.T) {
246+
tests := []struct {
247+
name string
248+
checkContexts []api.CheckContext
249+
want []api.CheckContext
250+
}{
251+
{
252+
name: "duplicate CheckRun (lint)",
253+
checkContexts: []api.CheckContext{
254+
{
255+
TypeName: "CheckRun",
256+
Name: "build (ubuntu-latest)",
257+
Status: "COMPLETED",
258+
Conclusion: "SUCCESS",
259+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
260+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
261+
DetailsURL: "https://github.com/cli/cli/runs/1",
262+
},
263+
{
264+
TypeName: "CheckRun",
265+
Name: "lint",
266+
Status: "COMPLETED",
267+
Conclusion: "FAILURE",
268+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
269+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
270+
DetailsURL: "https://github.com/cli/cli/runs/2",
271+
},
272+
{
273+
TypeName: "CheckRun",
274+
Name: "lint",
275+
Status: "COMPLETED",
276+
Conclusion: "SUCCESS",
277+
StartedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
278+
CompletedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
279+
DetailsURL: "https://github.com/cli/cli/runs/3",
280+
},
281+
},
282+
want: []api.CheckContext{
283+
{
284+
TypeName: "CheckRun",
285+
Name: "lint",
286+
Status: "COMPLETED",
287+
Conclusion: "SUCCESS",
288+
StartedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
289+
CompletedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
290+
DetailsURL: "https://github.com/cli/cli/runs/3",
291+
},
292+
{
293+
TypeName: "CheckRun",
294+
Name: "build (ubuntu-latest)",
295+
Status: "COMPLETED",
296+
Conclusion: "SUCCESS",
297+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
298+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
299+
DetailsURL: "https://github.com/cli/cli/runs/1",
300+
},
301+
},
302+
},
303+
{
304+
name: "duplicate StatusContext (Windows GPU)",
305+
checkContexts: []api.CheckContext{
306+
{
307+
TypeName: "StatusContext",
308+
Name: "",
309+
Context: "Windows GPU",
310+
State: "FAILURE",
311+
Status: "",
312+
Conclusion: "",
313+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
314+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
315+
DetailsURL: "",
316+
TargetURL: "https://github.com/cli/cli/2",
317+
},
318+
{
319+
TypeName: "StatusContext",
320+
Name: "",
321+
Context: "Windows GPU",
322+
State: "SUCCESS",
323+
Status: "",
324+
Conclusion: "",
325+
StartedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
326+
CompletedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
327+
DetailsURL: "",
328+
TargetURL: "https://github.com/cli/cli/3",
329+
},
330+
{
331+
TypeName: "StatusContext",
332+
Name: "",
333+
Context: "Linux GPU",
334+
State: "SUCCESS",
335+
Status: "",
336+
Conclusion: "",
337+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
338+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
339+
DetailsURL: "",
340+
TargetURL: "https://github.com/cli/cli/1",
341+
},
342+
},
343+
want: []api.CheckContext{
344+
{
345+
TypeName: "StatusContext",
346+
Name: "",
347+
Context: "Windows GPU",
348+
State: "SUCCESS",
349+
Status: "",
350+
Conclusion: "",
351+
StartedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
352+
CompletedAt: time.Date(2022, 2, 2, 2, 2, 2, 2, time.UTC),
353+
DetailsURL: "",
354+
TargetURL: "https://github.com/cli/cli/3",
355+
},
356+
{
357+
TypeName: "StatusContext",
358+
Name: "",
359+
Context: "Linux GPU",
360+
State: "SUCCESS",
361+
Status: "",
362+
Conclusion: "",
363+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
364+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
365+
DetailsURL: "",
366+
TargetURL: "https://github.com/cli/cli/1",
367+
},
368+
},
369+
},
370+
{
371+
name: "unique CheckContext",
372+
checkContexts: []api.CheckContext{
373+
{
374+
TypeName: "CheckRun",
375+
Name: "build (ubuntu-latest)",
376+
Status: "COMPLETED",
377+
Conclusion: "SUCCESS",
378+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
379+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
380+
DetailsURL: "https://github.com/cli/cli/runs/1",
381+
},
382+
{
383+
TypeName: "StatusContext",
384+
Name: "",
385+
Context: "Windows GPU",
386+
State: "SUCCESS",
387+
Status: "",
388+
Conclusion: "",
389+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
390+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
391+
DetailsURL: "",
392+
TargetURL: "https://github.com/cli/cli/2",
393+
},
394+
{
395+
TypeName: "StatusContext",
396+
Name: "",
397+
Context: "Linux GPU",
398+
State: "SUCCESS",
399+
Status: "",
400+
Conclusion: "",
401+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
402+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
403+
DetailsURL: "",
404+
TargetURL: "https://github.com/cli/cli/3",
405+
},
406+
},
407+
want: []api.CheckContext{
408+
{
409+
TypeName: "CheckRun",
410+
Name: "build (ubuntu-latest)",
411+
Status: "COMPLETED",
412+
Conclusion: "SUCCESS",
413+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
414+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
415+
DetailsURL: "https://github.com/cli/cli/runs/1",
416+
},
417+
{
418+
TypeName: "StatusContext",
419+
Name: "",
420+
Context: "Windows GPU",
421+
State: "SUCCESS",
422+
Status: "",
423+
Conclusion: "",
424+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
425+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
426+
DetailsURL: "",
427+
TargetURL: "https://github.com/cli/cli/2",
428+
},
429+
{
430+
TypeName: "StatusContext",
431+
Name: "",
432+
Context: "Linux GPU",
433+
State: "SUCCESS",
434+
Status: "",
435+
Conclusion: "",
436+
StartedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
437+
CompletedAt: time.Date(2022, 1, 1, 1, 1, 1, 1, time.UTC),
438+
DetailsURL: "",
439+
TargetURL: "https://github.com/cli/cli/3",
440+
},
441+
},
442+
},
443+
}
444+
445+
for _, tt := range tests {
446+
t.Run(tt.name, func(t *testing.T) {
447+
got := eliminateDuplicates(tt.checkContexts)
448+
if !reflect.DeepEqual(tt.want, got) {
449+
t.Errorf("got eliminateDuplicates %+v, want %+v\n", got, tt.want)
450+
}
451+
})
452+
}
453+
}

0 commit comments

Comments
 (0)
X Tutup