Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pr-status): add build status to pr-status list table #129

Merged
Merged
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,16 @@ Viewing a detailed list of status per repo:
```
$ turbolift pr-status --list
...
Repository State Reviews URL
redacted/redacted OPEN REVIEW_REQUIRED https://github.redacted/redacted/redacted/pull/262
redacted/redacted OPEN REVIEW_REQUIRED https://github.redacted/redacted/redacted/pull/515
redacted/redacted OPEN REVIEW_REQUIRED https://github.redacted/redacted/redacted/pull/342
redacted/redacted MERGED APPROVED https://github.redacted/redacted/redacted/pull/407
redacted/redacted MERGED REVIEW_REQUIRED https://github.redacted/redacted/redacted/pull/220
redacted/redacted OPEN REVIEW_REQUIRED https://github.redacted/redacted/redacted/pull/105
redacted/redacted MERGED APPROVED https://github.redacted/redacted/redacted/pull/532
redacted/redacted MERGED APPROVED https://github.redacted/redacted/redacted/pull/268
redacted/redacted OPEN REVIEW_REQUIRED https://github.redacted/redacted/redacted/pull/438
Repository State Reviews Build status URL
redacted/redacted OPEN REVIEW_REQUIRED SUCCESS https://github.redacted/redacted/redacted/pull/262
redacted/redacted OPEN REVIEW_REQUIRED SUCCESS https://github.redacted/redacted/redacted/pull/515
redacted/redacted OPEN REVIEW_REQUIRED SUCCESS https://github.redacted/redacted/redacted/pull/342
redacted/redacted MERGED APPROVED SUCCESS https://github.redacted/redacted/redacted/pull/407
redacted/redacted MERGED REVIEW_REQUIRED SUCCESS https://github.redacted/redacted/redacted/pull/220
redacted/redacted OPEN REVIEW_REQUIRED FAILURE https://github.redacted/redacted/redacted/pull/105
redacted/redacted MERGED APPROVED SUCCESS https://github.redacted/redacted/redacted/pull/532
redacted/redacted MERGED APPROVED SUCCESS https://github.redacted/redacted/redacted/pull/268
redacted/redacted OPEN REVIEW_REQUIRED FAILURE https://github.redacted/redacted/redacted/pull/438
...
```

Expand Down
21 changes: 19 additions & 2 deletions cmd/prstatus/prstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func run(c *cobra.Command, _ []string) {
statuses := make(map[string]int)
reactions := make(map[string]int)

detailsTable := table.New("Repository", "State", "Reviews", "URL")
detailsTable := table.New("Repository", "State", "Reviews", "Checks status", "URL")
detailsTable.WithHeaderFormatter(color.New(color.Underline).SprintfFunc())
detailsTable.WithFirstColumnFormatter(color.New(color.FgCyan).SprintfFunc())
detailsTable.WithWriter(logger.Writer())
Expand Down Expand Up @@ -118,7 +118,24 @@ func run(c *cobra.Command, _ []string) {
reactions[reaction.Content] += reaction.Users.TotalCount
}

detailsTable.AddRow(repo.FullRepoName, prStatus.State, prStatus.ReviewDecision, prStatus.Url)
failedCheck := false
pendingCheck := false
for _, check := range prStatus.StatusCheckRollup {
Dan7-7-7 marked this conversation as resolved.
Show resolved Hide resolved
if strings.Contains(check.State, "FAILURE") {
failedCheck = true
} else if strings.Contains(check.State, "PENDING") {
pendingCheck = true
}
}

checksStatus := "SUCCESS"
if failedCheck {
checksStatus = "FAILURE"
} else if pendingCheck {
checksStatus = "PENDING"
}

detailsTable.AddRow(repo.FullRepoName, prStatus.State, prStatus.ReviewDecision, checksStatus, prStatus.Url)

checkStatusActivity.EndWithSuccess()
}
Expand Down
101 changes: 93 additions & 8 deletions cmd/prstatus/prstatus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,20 @@ func TestItLogsSummaryInformation(t *testing.T) {
func TestItLogsDetailedInformation(t *testing.T) {
prepareFakeResponses()

testsupport.PrepareTempCampaign(true, "org/repo1", "org/repo2", "org/repo3")
testsupport.PrepareTempCampaign(true, "org/repo1", "org/repo2", "org/repo3", "org/repo4", "org/repo5", "org/repo6")

out, err := runCommand(true)
assert.NoError(t, err)
// Should still show summary info
assert.Regexp(t, "Open\\s+1", out)
assert.Regexp(t, "👍\\s+4", out)

assert.Regexp(t, "org/repo1\\s+OPEN\\s+REVIEW_REQUIRED", out)
assert.Regexp(t, "org/repo2\\s+MERGED\\s+APPROVED", out)
assert.Regexp(t, "org/repo3\\s+CLOSED", out)
assert.Regexp(t, "Open\\s+4", out)
assert.Regexp(t, "👍\\s+13", out)

assert.Regexp(t, "org/repo1\\s+OPEN\\s+REVIEW_REQUIRED\\s+FAILURE", out)
assert.Regexp(t, "org/repo2\\s+MERGED\\s+APPROVED\\s+SUCCESS", out)
assert.Regexp(t, "org/repo3\\s+CLOSED\\s+FAILURE", out)
assert.Regexp(t, "org/repo4\\s+OPEN\\s+REVIEW_REQUIRED\\s+PENDING", out)
assert.Regexp(t, "org/repo5\\s+OPEN\\s+REVIEW_REQUIRED\\s+FAILURE", out)
assert.Regexp(t, "org/repo6\\s+OPEN\\s+REVIEW_REQUIRED\\s+PENDING", out)
}

func TestItSkipsUnclonedRepos(t *testing.T) {
Expand Down Expand Up @@ -119,6 +122,14 @@ func prepareFakeResponses() {
dummyData := map[string]*github.PrStatus{
"work/org/repo1": {
State: "OPEN",
StatusCheckRollup: []github.StatusCheckRollup{
{
State: "FAILURE",
},
{
State: "SUCCESS",
},
},
ReactionGroups: []github.ReactionGroup{
{
Content: "THUMBS_UP",
Expand All @@ -137,6 +148,14 @@ func prepareFakeResponses() {
},
"work/org/repo2": {
State: "MERGED",
StatusCheckRollup: []github.StatusCheckRollup{
{
State: "SUCCESS",
},
{
State: "SUCCESS",
},
},
ReactionGroups: []github.ReactionGroup{
{
Content: "THUMBS_UP",
Expand All @@ -148,7 +167,13 @@ func prepareFakeResponses() {
ReviewDecision: "APPROVED",
},
"work/org/repo3": {
State: "CLOSED",
State: "CLOSED",
Mergeable: "UNKNOWN",
StatusCheckRollup: []github.StatusCheckRollup{
{
State: "FAILURE",
},
},
ReactionGroups: []github.ReactionGroup{
{
Content: "THUMBS_DOWN",
Expand All @@ -158,6 +183,66 @@ func prepareFakeResponses() {
},
},
},
"work/org/repo4": {
State: "OPEN",
StatusCheckRollup: []github.StatusCheckRollup{
{
State: "SUCCESS",
},
{
State: "PENDING",
},
},
ReactionGroups: []github.ReactionGroup{
{
Content: "THUMBS_UP",
Users: github.ReactionGroupUsers{
TotalCount: 3,
},
},
},
ReviewDecision: "REVIEW_REQUIRED",
},
"work/org/repo5": {
State: "OPEN",
StatusCheckRollup: []github.StatusCheckRollup{
{
State: "FAILURE",
},
{
State: "PENDING",
},
},
ReactionGroups: []github.ReactionGroup{
{
Content: "THUMBS_UP",
Users: github.ReactionGroupUsers{
TotalCount: 3,
},
},
},
ReviewDecision: "REVIEW_REQUIRED",
},
"work/org/repo6": {
State: "OPEN",
StatusCheckRollup: []github.StatusCheckRollup{
{
State: "PENDING",
},
{
State: "PENDING",
},
},
ReactionGroups: []github.ReactionGroup{
{
Content: "THUMBS_UP",
Users: github.ReactionGroupUsers{
TotalCount: 3,
},
},
},
ReviewDecision: "REVIEW_REQUIRED",
},
}
fakeGitHub := github.NewFakeGitHub(nil, func(workingDir string) (interface{}, error) {
if workingDir == "work/org/repoWithError" {
Expand Down
25 changes: 15 additions & 10 deletions internal/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,16 @@ type PrStatusResponse struct { // https://github.com/cli/cli/blob/4b415f80d79e57
}

type PrStatus struct {
Closed bool `json:"closed"`
HeadRefName string `json:"headRefName"`
Mergeable string `json:"mergeable"`
Number int `json:"number"`
ReactionGroups []ReactionGroup `json:"reactionGroups"`
ReviewDecision string `json:"reviewDecision"`
State string `json:"state"`
Title string `json:"title"`
Url string `json:"url"`
Closed bool `json:"closed"`
HeadRefName string `json:"headRefName"`
Mergeable string `json:"mergeable"`
Number int `json:"number"`
ReactionGroups []ReactionGroup `json:"reactionGroups"`
ReviewDecision string `json:"reviewDecision"`
State string `json:"state"`
StatusCheckRollup []StatusCheckRollup `json:"statusCheckRollup"`
Title string `json:"title"`
Url string `json:"url"`
}

type ReactionGroupUsers struct {
Expand All @@ -128,6 +129,10 @@ type ReactionGroup struct {
Users ReactionGroupUsers
}

type StatusCheckRollup struct {
State string
}

// GetPR is a helper function to retrieve the PR associated with the branch Name
type NoPRFoundError struct {
Path string
Expand All @@ -139,7 +144,7 @@ func (e *NoPRFoundError) Error() string {
}

func (r *RealGitHub) GetPR(output io.Writer, workingDir string, branchName string) (*PrStatus, error) {
s, err := execInstance.ExecuteAndCapture(output, workingDir, "gh", "pr", "status", "--json", "closed,headRefName,mergeable,number,reactionGroups,reviewDecision,state,title,url")
s, err := execInstance.ExecuteAndCapture(output, workingDir, "gh", "pr", "status", "--json", "closed,headRefName,mergeable,number,reactionGroups,reviewDecision,state,statusCheckRollup,title,url")
if err != nil {
return nil, err
}
Expand Down
Loading