diff --git a/api/queries_pr.go b/api/queries_pr.go index 18217a583..df96569d4 100644 --- a/api/queries_pr.go +++ b/api/queries_pr.go @@ -67,19 +67,7 @@ type PullRequest struct { Nodes []PullRequestCommit } StatusCheckRollup struct { - Nodes []struct { - Commit struct { - StatusCheckRollup struct { - Contexts struct { - Nodes []CheckContext - PageInfo struct { - HasNextPage bool - EndCursor string - } - } - } - } - } + Nodes []StatusCheckRollupNode } Assignees Assignees @@ -93,9 +81,30 @@ type PullRequest struct { ReviewRequests ReviewRequests } +type StatusCheckRollupNode struct { + Commit StatusCheckRollupCommit +} + +type StatusCheckRollupCommit struct { + StatusCheckRollup CommitStatusCheckRollup +} + +type CommitStatusCheckRollup struct { + Contexts CheckContexts +} + +type CheckContexts struct { + Nodes []CheckContext + PageInfo struct { + HasNextPage bool + EndCursor string + } +} + type CheckContext struct { TypeName string `json:"__typename"` Name string `json:"name"` + IsRequired bool `json:"isRequired"` CheckSuite struct { WorkflowRun struct { Workflow struct { diff --git a/api/query_builder.go b/api/query_builder.go index 16665cfd8..996a52a71 100644 --- a/api/query_builder.go +++ b/api/query_builder.go @@ -164,6 +164,45 @@ func StatusCheckRollupGraphQL(after string) string { }`), afterClause) } +func RequiredStatusCheckRollupGraphQL(prID, after string) string { + var afterClause string + if after != "" { + afterClause = ",after:" + after + } + return fmt.Sprintf(shortenQuery(` + statusCheckRollup: commits(last: 1) { + nodes { + commit { + statusCheckRollup { + contexts(first:100%[1]s) { + nodes { + __typename + ...on StatusContext { + context, + state, + targetUrl, + createdAt, + isRequired(pullRequestId: %[2]s) + }, + ...on CheckRun { + name, + checkSuite{workflowRun{workflow{name}}}, + status, + conclusion, + startedAt, + completedAt, + detailsUrl, + isRequired(pullRequestId: %[2]s) + } + }, + pageInfo{hasNextPage,endCursor} + } + } + } + } + }`), afterClause, prID) +} + var IssueFields = []string{ "assignees", "author", diff --git a/pkg/cmd/pr/checks/aggregate.go b/pkg/cmd/pr/checks/aggregate.go index 9247082b9..2a01b31d8 100644 --- a/pkg/cmd/pr/checks/aggregate.go +++ b/pkg/cmd/pr/checks/aggregate.go @@ -24,7 +24,7 @@ type checkCounts struct { Skipping int } -func aggregateChecks(pr *api.PullRequest) ([]check, checkCounts, error) { +func aggregateChecks(pr *api.PullRequest, requiredChecks bool) ([]check, checkCounts, error) { checks := []check{} counts := checkCounts{} @@ -39,6 +39,10 @@ func aggregateChecks(pr *api.PullRequest) ([]check, checkCounts, error) { checkContexts := pr.StatusCheckRollup.Nodes[0].Commit.StatusCheckRollup.Contexts.Nodes for _, c := range eliminateDuplicates(checkContexts) { + if requiredChecks && !c.IsRequired { + continue + } + state := c.State if state == "" { if c.Status == "COMPLETED" { @@ -83,6 +87,10 @@ func aggregateChecks(pr *api.PullRequest) ([]check, checkCounts, error) { checks = append(checks, item) } + if len(checks) == 0 && requiredChecks { + return checks, counts, fmt.Errorf("no required checks reported on the '%s' branch", pr.HeadRefName) + } + return checks, counts, nil } diff --git a/pkg/cmd/pr/checks/checks.go b/pkg/cmd/pr/checks/checks.go index 4bb536bc4..7e8294dbb 100644 --- a/pkg/cmd/pr/checks/checks.go +++ b/pkg/cmd/pr/checks/checks.go @@ -2,6 +2,7 @@ package checks import ( "fmt" + "net/http" "time" "github.com/MakeNowJust/heredoc" @@ -18,8 +19,9 @@ import ( const defaultInterval time.Duration = 10 * time.Second type ChecksOptions struct { - IO *iostreams.IOStreams - Browser browser.Browser + HttpClient func() (*http.Client, error) + IO *iostreams.IOStreams + Browser browser.Browser Finder shared.PRFinder @@ -27,14 +29,16 @@ type ChecksOptions struct { WebMode bool Interval time.Duration Watch bool + Required bool } func NewCmdChecks(f *cmdutil.Factory, runF func(*ChecksOptions) error) *cobra.Command { var interval int opts := &ChecksOptions{ - IO: f.IOStreams, - Browser: f.Browser, - Interval: defaultInterval, + HttpClient: f.HttpClient, + IO: f.IOStreams, + Browser: f.Browser, + Interval: defaultInterval, } cmd := &cobra.Command{ @@ -82,6 +86,7 @@ func NewCmdChecks(f *cmdutil.Factory, runF func(*ChecksOptions) error) *cobra.Co cmd.Flags().BoolVarP(&opts.WebMode, "web", "w", false, "Open the web browser to show details about checks") cmd.Flags().BoolVarP(&opts.Watch, "watch", "", false, "Watch checks until they finish") cmd.Flags().IntVarP(&interval, "interval", "i", 10, "Refresh interval in seconds when using `--watch` flag") + cmd.Flags().BoolVar(&opts.Required, "required", false, "Only show checks that are required") return cmd } @@ -111,6 +116,22 @@ func checksRun(opts *ChecksOptions) error { return checksRunWebMode(opts) } + findOptions := shared.FindOptions{ + Selector: opts.SelectorArg, + Fields: []string{"number", "headRefName"}, + } + + var pr *api.PullRequest + pr, repo, findErr := opts.Finder.Find(findOptions) + if findErr != nil { + return findErr + } + + client, clientErr := opts.HttpClient() + if clientErr != nil { + return clientErr + } + if opts.Watch { opts.IO.StartAlternateScreenBuffer() } else { @@ -127,19 +148,14 @@ func checksRun(opts *ChecksOptions) error { // Do not return err until we can StopAlternateScreenBuffer() var err error - for { - findOptions := shared.FindOptions{ - Selector: opts.SelectorArg, - Fields: []string{"number", "headRefName", "statusCheckRollup"}, - } - var pr *api.PullRequest - pr, _, err = opts.Finder.Find(findOptions) + for { + err = populateStatusChecks(client, repo, pr) if err != nil { break } - checks, counts, err = aggregateChecks(pr) + checks, counts, err = aggregateChecks(pr, opts.Required) if err != nil { break } @@ -183,3 +199,63 @@ func checksRun(opts *ChecksOptions) error { return nil } + +func populateStatusChecks(client *http.Client, repo ghrepo.Interface, pr *api.PullRequest) error { + apiClient := api.NewClientFromHTTP(client) + + type response struct { + Node *api.PullRequest + } + + query := fmt.Sprintf(` + query PullRequestStatusChecks($id: ID!, $endCursor: String!) { + node(id: $id) { + ...on PullRequest { + %s + } + } + }`, api.RequiredStatusCheckRollupGraphQL("$id", "$endCursor")) + + variables := map[string]interface{}{ + "id": pr.ID, + } + + statusCheckRollup := api.CheckContexts{} + endCursor := "" + + for { + variables["endCursor"] = endCursor + var resp response + err := apiClient.GraphQL(repo.RepoHost(), query, variables, &resp) + if err != nil { + return err + } + + if len(resp.Node.StatusCheckRollup.Nodes) == 0 { + return nil + } + + result := resp.Node.StatusCheckRollup.Nodes[0].Commit.StatusCheckRollup.Contexts + statusCheckRollup.Nodes = append( + statusCheckRollup.Nodes, + result.Nodes..., + ) + + if !result.PageInfo.HasNextPage { + break + } + endCursor = result.PageInfo.EndCursor + } + + statusCheckRollup.PageInfo.HasNextPage = false + + pr.StatusCheckRollup.Nodes = []api.StatusCheckRollupNode{{ + Commit: api.StatusCheckRollupCommit{ + StatusCheckRollup: api.CommitStatusCheckRollup{ + Contexts: statusCheckRollup, + }, + }, + }} + + return nil +} diff --git a/pkg/cmd/pr/checks/checks_test.go b/pkg/cmd/pr/checks/checks_test.go index b0802f3db..3e5c8394a 100644 --- a/pkg/cmd/pr/checks/checks_test.go +++ b/pkg/cmd/pr/checks/checks_test.go @@ -2,9 +2,7 @@ package checks import ( "bytes" - "encoding/json" - "io" - "os" + "net/http" "reflect" "testing" "time" @@ -15,10 +13,10 @@ import ( "github.com/cli/cli/v2/internal/run" "github.com/cli/cli/v2/pkg/cmd/pr/shared" "github.com/cli/cli/v2/pkg/cmdutil" + "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" "github.com/google/shlex" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestNewCmdChecks(t *testing.T) { @@ -64,6 +62,14 @@ func TestNewCmdChecks(t *testing.T) { cli: "--interval 5", wantsError: "cannot use `--interval` flag without `--watch` flag", }, + { + name: "required flag", + cli: "--required", + wants: ChecksOptions{ + Required: true, + Interval: time.Duration(10000000000), + }, + }, } for _, tt := range tests { @@ -95,107 +101,198 @@ func TestNewCmdChecks(t *testing.T) { assert.Equal(t, tt.wants.SelectorArg, gotOpts.SelectorArg) assert.Equal(t, tt.wants.Watch, gotOpts.Watch) assert.Equal(t, tt.wants.Interval, gotOpts.Interval) + assert.Equal(t, tt.wants.Required, gotOpts.Required) }) } } func Test_checksRun(t *testing.T) { tests := []struct { - name string - fixture string - prJSON string - tty bool - watch bool - wantOut string - wantErr string + name string + tty bool + watch bool + required bool + httpStubs func(*httpmock.Registry) + wantOut string + wantErr string }{ { - name: "no commits", - prJSON: `{ "number": 123 }`, - tty: true, + name: "no commits", + tty: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.StringResponse(`{"data":{"node":{}}}`), + ) + }, wantOut: "", wantErr: "no commit found on the pull request", }, { - name: "no checks", - prJSON: `{ "number": 123, "statusCheckRollup": { "nodes": [{"commit": {"oid": "abc"}}]}, "headRefName": "master" }`, - tty: true, + name: "no checks", + tty: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.StringResponse(`{"data":{"node":{"statusCheckRollup":{"nodes":[{"commit":{"oid": "abc"}}]}}}}`), + ) + }, wantOut: "", - wantErr: "no checks reported on the 'master' branch", + wantErr: "no checks reported on the 'trunk' branch", }, { - name: "some failing", - fixture: "./fixtures/someFailing.json", - tty: true, + name: "some failing", + tty: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/someFailing.json"), + ) + }, wantOut: "Some checks were not successful\n1 failing, 1 successful, 0 skipped, and 1 pending checks\n\nX sad tests 1m26s sweet link\n✓ cool tests 1m26s sweet link\n* slow tests 1m26s sweet link\n", wantErr: "SilentError", }, { - name: "some pending", - fixture: "./fixtures/somePending.json", - tty: true, + name: "some pending", + tty: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/somePending.json"), + ) + }, wantOut: "Some checks are still pending\n0 failing, 2 successful, 0 skipped, and 1 pending checks\n\n✓ cool tests 1m26s sweet link\n✓ rad tests 1m26s sweet link\n* slow tests 1m26s sweet link\n", wantErr: "SilentError", }, { - name: "all passing", - fixture: "./fixtures/allPassing.json", - tty: true, + name: "all passing", + tty: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/allPassing.json"), + ) + }, wantOut: "All checks were successful\n0 failing, 3 successful, 0 skipped, and 0 pending checks\n\n✓ awesome tests 1m26s sweet link\n✓ cool tests 1m26s sweet link\n✓ rad tests 1m26s sweet link\n", wantErr: "", }, { - name: "watch all passing", - fixture: "./fixtures/allPassing.json", - tty: true, - watch: true, + name: "watch all passing", + tty: true, + watch: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/allPassing.json"), + ) + }, wantOut: "\x1b[?1049hAll checks were successful\n0 failing, 3 successful, 0 skipped, and 0 pending checks\n\n✓ awesome tests 1m26s sweet link\n✓ cool tests 1m26s sweet link\n✓ rad tests 1m26s sweet link\n\x1b[?1049lAll checks were successful\n0 failing, 3 successful, 0 skipped, and 0 pending checks\n\n✓ awesome tests 1m26s sweet link\n✓ cool tests 1m26s sweet link\n✓ rad tests 1m26s sweet link\n", wantErr: "", }, { - name: "with statuses", - fixture: "./fixtures/withStatuses.json", - tty: true, + name: "with statuses", + tty: true, + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/withStatuses.json"), + ) + }, wantOut: "Some checks were not successful\n1 failing, 2 successful, 0 skipped, and 0 pending checks\n\nX a status sweet link\n✓ cool tests 1m26s sweet link\n✓ rad tests 1m26s sweet link\n", wantErr: "SilentError", }, { - name: "no checks", - prJSON: `{ "number": 123, "statusCheckRollup": { "nodes": [{"commit": {"oid": "abc"}}]}, "headRefName": "master" }`, + name: "no checks", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.StringResponse(`{"data":{"node":{"statusCheckRollup":{"nodes":[{"commit":{"oid": "abc"}}]}}}}`), + ) + }, wantOut: "", - wantErr: "no checks reported on the 'master' branch", + wantErr: "no checks reported on the 'trunk' branch", }, { - name: "some failing", - fixture: "./fixtures/someFailing.json", + name: "some failing", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/someFailing.json"), + ) + }, wantOut: "sad tests\tfail\t1m26s\tsweet link\ncool tests\tpass\t1m26s\tsweet link\nslow tests\tpending\t1m26s\tsweet link\n", wantErr: "SilentError", }, { - name: "some pending", - fixture: "./fixtures/somePending.json", + name: "some pending", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/somePending.json"), + ) + }, wantOut: "cool tests\tpass\t1m26s\tsweet link\nrad tests\tpass\t1m26s\tsweet link\nslow tests\tpending\t1m26s\tsweet link\n", wantErr: "SilentError", }, { - name: "all passing", - fixture: "./fixtures/allPassing.json", + name: "all passing", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/allPassing.json"), + ) + }, wantOut: "awesome tests\tpass\t1m26s\tsweet link\ncool tests\tpass\t1m26s\tsweet link\nrad tests\tpass\t1m26s\tsweet link\n", wantErr: "", }, { - name: "with statuses", - fixture: "./fixtures/withStatuses.json", + name: "with statuses", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/withStatuses.json"), + ) + }, wantOut: "a status\tfail\t0\tsweet link\ncool tests\tpass\t1m26s\tsweet link\nrad tests\tpass\t1m26s\tsweet link\n", wantErr: "SilentError", }, { - name: "some skipped", - fixture: "./fixtures/someSkipping.json", + name: "some skipped", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/someSkipping.json"), + ) + }, tty: true, wantOut: "All checks were successful\n0 failing, 1 successful, 2 skipped, and 0 pending checks\n\n✓ cool tests 1m26s sweet link\n- rad tests 1m26s sweet link\n- skip tests 1m26s sweet link\n", wantErr: "", }, + { + name: "only required", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/onlyRequired.json"), + ) + }, + tty: true, + wantOut: "All checks were successful\n0 failing, 1 successful, 0 skipped, and 0 pending checks\n\n✓ cool tests 1m26s sweet link\n", + wantErr: "", + required: true, + }, + { + name: "no required checks", + httpStubs: func(reg *httpmock.Registry) { + reg.Register( + httpmock.GraphQL(`query PullRequestStatusChecks\b`), + httpmock.FileResponse("./fixtures/someSkipping.json"), + ) + }, + wantOut: "", + wantErr: "no required checks reported on the 'trunk' branch", + required: true, + }, } for _, tt := range tests { @@ -204,24 +301,22 @@ func Test_checksRun(t *testing.T) { ios.SetStdoutTTY(tt.tty) ios.SetAlternateScreenBufferEnabled(tt.tty) - var response *api.PullRequest - var jsonReader io.Reader - if tt.fixture != "" { - ff, err := os.Open(tt.fixture) - require.NoError(t, err) - defer ff.Close() - jsonReader = ff - } else { - jsonReader = bytes.NewBufferString(tt.prJSON) + reg := &httpmock.Registry{} + defer reg.Verify(t) + if tt.httpStubs != nil { + tt.httpStubs(reg) } - dec := json.NewDecoder(jsonReader) - require.NoError(t, dec.Decode(&response)) + response := &api.PullRequest{Number: 123, HeadRefName: "trunk"} opts := &ChecksOptions{ + HttpClient: func() (*http.Client, error) { + return &http.Client{Transport: reg}, nil + }, IO: ios, SelectorArg: "123", Finder: shared.NewMockFinder("123", response, ghrepo.New("OWNER", "REPO")), Watch: tt.watch, + Required: tt.required, } err := checksRun(opts) diff --git a/pkg/cmd/pr/checks/fixtures/allPassing.json b/pkg/cmd/pr/checks/fixtures/allPassing.json index 8d1f33510..47df80c8e 100644 --- a/pkg/cmd/pr/checks/fixtures/allPassing.json +++ b/pkg/cmd/pr/checks/fixtures/allPassing.json @@ -1,42 +1,45 @@ -{ - "number": 123, - "statusCheckRollup": { - "nodes": [ - { - "commit": { - "oid": "abc", - "statusCheckRollup": { - "contexts": { - "nodes": [ - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "cool tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "rad tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "awesome tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" +{ + "data": { + "node": { + "statusCheckRollup": { + "nodes": [ + { + "commit": { + "oid": "abc", + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "cool tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "rad tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "awesome tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + } + ] } - ] + } } } - } + ] } - ] + } } } diff --git a/pkg/cmd/pr/checks/fixtures/onlyRequired.json b/pkg/cmd/pr/checks/fixtures/onlyRequired.json new file mode 100644 index 000000000..b4a8ddbdd --- /dev/null +++ b/pkg/cmd/pr/checks/fixtures/onlyRequired.json @@ -0,0 +1,48 @@ +{ + "data": { + "node": { + "statusCheckRollup": { + "nodes": [ + { + "commit": { + "oid": "abc", + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "cool tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link", + "isRequired": true + }, + { + "conclusion": "SKIPPED", + "status": "COMPLETED", + "name": "rad tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link", + "isRequired": false + }, + { + "conclusion": "SKIPPED", + "status": "COMPLETED", + "name": "skip tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link", + "isRequired": false + } + ] + } + } + } + } + ] + } + } + } +} diff --git a/pkg/cmd/pr/checks/fixtures/someFailing.json b/pkg/cmd/pr/checks/fixtures/someFailing.json index f407cd4b5..9814d5e76 100644 --- a/pkg/cmd/pr/checks/fixtures/someFailing.json +++ b/pkg/cmd/pr/checks/fixtures/someFailing.json @@ -1,42 +1,45 @@ -{ - "number": 123, - "statusCheckRollup": { - "nodes": [ - { - "commit": { - "oid": "abc", - "statusCheckRollup": { - "contexts": { - "nodes": [ - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "cool tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "FAILURE", - "status": "COMPLETED", - "name": "sad tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "", - "status": "IN_PROGRESS", - "name": "slow tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" +{ + "data": { + "node": { + "statusCheckRollup": { + "nodes": [ + { + "commit": { + "oid": "abc", + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "cool tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "FAILURE", + "status": "COMPLETED", + "name": "sad tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "", + "status": "IN_PROGRESS", + "name": "slow tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + } + ] } - ] + } } } - } + ] } - ] + } } } diff --git a/pkg/cmd/pr/checks/fixtures/somePending.json b/pkg/cmd/pr/checks/fixtures/somePending.json index 2d558f39e..a96ea4fda 100644 --- a/pkg/cmd/pr/checks/fixtures/somePending.json +++ b/pkg/cmd/pr/checks/fixtures/somePending.json @@ -1,42 +1,45 @@ -{ - "number": 123, - "statusCheckRollup": { - "nodes": [ - { - "commit": { - "oid": "abc", - "statusCheckRollup": { - "contexts": { - "nodes": [ - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "cool tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "rad tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "", - "status": "IN_PROGRESS", - "name": "slow tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" +{ + "data": { + "node": { + "statusCheckRollup": { + "nodes": [ + { + "commit": { + "oid": "abc", + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "cool tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "rad tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "", + "status": "IN_PROGRESS", + "name": "slow tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + } + ] } - ] + } } } - } + ] } - ] + } } } diff --git a/pkg/cmd/pr/checks/fixtures/someSkipping.json b/pkg/cmd/pr/checks/fixtures/someSkipping.json index 65ac5b98f..f267f3ddb 100644 --- a/pkg/cmd/pr/checks/fixtures/someSkipping.json +++ b/pkg/cmd/pr/checks/fixtures/someSkipping.json @@ -1,42 +1,45 @@ -{ - "number": 123, - "statusCheckRollup": { - "nodes": [ - { - "commit": { - "oid": "abc", - "statusCheckRollup": { - "contexts": { - "nodes": [ - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "cool tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "SKIPPED", - "status": "COMPLETED", - "name": "rad tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "SKIPPED", - "status": "COMPLETED", - "name": "skip tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" +{ + "data": { + "node": { + "statusCheckRollup": { + "nodes": [ + { + "commit": { + "oid": "abc", + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "cool tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "SKIPPED", + "status": "COMPLETED", + "name": "rad tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "SKIPPED", + "status": "COMPLETED", + "name": "skip tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + } + ] } - ] + } } } - } + ] } - ] + } } } diff --git a/pkg/cmd/pr/checks/fixtures/withStatuses.json b/pkg/cmd/pr/checks/fixtures/withStatuses.json index ddc7374ba..ed8300eb7 100644 --- a/pkg/cmd/pr/checks/fixtures/withStatuses.json +++ b/pkg/cmd/pr/checks/fixtures/withStatuses.json @@ -1,39 +1,42 @@ -{ - "number": 123, - "statusCheckRollup": { - "nodes": [ - { - "commit": { - "oid": "abc", - "statusCheckRollup": { - "contexts": { - "nodes": [ - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "cool tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "conclusion": "SUCCESS", - "status": "COMPLETED", - "name": "rad tests", - "completedAt": "2020-08-27T19:00:12Z", - "startedAt": "2020-08-27T18:58:46Z", - "detailsUrl": "sweet link" - }, - { - "state": "FAILURE", - "name": "a status", - "targetUrl": "sweet link" +{ + "data": { + "node": { + "statusCheckRollup": { + "nodes": [ + { + "commit": { + "oid": "abc", + "statusCheckRollup": { + "contexts": { + "nodes": [ + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "cool tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "conclusion": "SUCCESS", + "status": "COMPLETED", + "name": "rad tests", + "completedAt": "2020-08-27T19:00:12Z", + "startedAt": "2020-08-27T18:58:46Z", + "detailsUrl": "sweet link" + }, + { + "state": "FAILURE", + "name": "a status", + "targetUrl": "sweet link" + } + ] } - ] + } } } - } + ] } - ] + } } }