Show PR CI status #306

Merged
6543 merged 8 commits from noerw/tea:issue-117-pr-status into master 2020-12-16 17:16:51 +00:00
3 changed files with 78 additions and 18 deletions

View File

@ -60,6 +60,11 @@ func runPullDetail(cmd *cli.Context, index string) error {
fmt.Printf("error while loading reviews: %v\n", err)
}
print.PullDetails(pr, reviews)
ci, _, err := client.GetCombinedStatus(ctx.Owner, ctx.Repo, pr.Head.Sha)
if err != nil {
fmt.Printf("error while loading CI: %v\n", err)
}
print.PullDetails(pr, reviews, ci)
return nil
}

View File

@ -7,12 +7,21 @@ package print
import (
"fmt"
"strconv"
"strings"
"code.gitea.io/sdk/gitea"
)
var ciStatusSymbols = map[gitea.StatusState]string{
gitea.StatusSuccess: "✓ ",
gitea.StatusPending: "⭮ ",
gitea.StatusWarning: "⚠ ",
gitea.StatusError: "✘ ",
gitea.StatusFailure: "❌ ",
}
// PullDetails print an pull rendered to stdout
func PullDetails(pr *gitea.PullRequest, reviews []*gitea.PullReview) {
func PullDetails(pr *gitea.PullRequest, reviews []*gitea.PullReview, ciStatus *gitea.CombinedStatus) {
base := pr.Base.Name
noerw marked this conversation as resolved Outdated
Outdated
Review

Pull wip?

Pull wip?
head := pr.Head.Name
if pr.Head.RepoID != pr.Base.RepoID {
@ -23,11 +32,16 @@ func PullDetails(pr *gitea.PullRequest, reviews []*gitea.PullReview) {
}
}
state := pr.State
if pr.Merged != nil {
state = "merged"
}
out := fmt.Sprintf(
"# #%d %s (%s)\n@%s created %s\t**%s** <- **%s**\n\n%s\n",
"# #%d %s (%s)\n@%s created %s\t**%s** <- **%s**\n\n%s\n\n",
pr.Index,
pr.Title,
pr.State,
state,
pr.Poster.UserName,
FormatTime(*pr.Created),
base,
@ -35,29 +49,70 @@ func PullDetails(pr *gitea.PullRequest, reviews []*gitea.PullReview) {
pr.Body,
)
if len(reviews) != 0 {
out += "\n"
revMap := make(map[string]gitea.ReviewStateType)
for _, review := range reviews {
switch review.State {
case gitea.ReviewStateApproved,
gitea.ReviewStateRequestChanges,
gitea.ReviewStateRequestReview:
revMap[review.Reviewer.UserName] = review.State
6543 marked this conversation as resolved Outdated
Outdated
Review

this remove dedublicate review states!!

before:

@lunny: APPROVED @6543: APPROVED

now:

* REQUEST_REVIEW by @lunny, @6543
* APPROVED by @lunny, @lunny, @6543

I like the new look, but you still have to only get latest state for each user

this remove dedublicate review states!! before: ``` @lunny: APPROVED @6543: APPROVED ``` now: ```md * REQUEST_REVIEW by @lunny, @6543 * APPROVED by @lunny, @lunny, @6543 ``` I like the new look, but you still have to only get latest state for each user
Outdated
Review

example was: tea pr 309

example was: `tea pr 309`
Outdated
Review

Oh right. And I thought I was fixing a bug: Thought you were aiming to deduplicate Approved/Rejected states. IMO we should deduplicate both.

I just tried to filter by review.Stale, but that's never true. wtf is this for?

Oh right. And I thought I was fixing a bug: Thought you were aiming to deduplicate Approved/Rejected states. IMO we should deduplicate both. I just tried to filter by `review.Stale`, but that's never true. wtf is this for?
Outdated
Review

Stale is a idication if the review took place on a different state as the pull is now (pull diff has changed since reviewed)

Stale is a idication if the review took place on a different state as the pull is now (pull diff has changed since reviewed)
Outdated
Review

fixed, output is now

  • APPROVED by @lunny, @6543     
fixed, output is now ``` • APPROVED by @lunny, @6543 ```
if ciStatus != nil || len(reviews) != 0 || pr.State == gitea.StateOpen {
out += "---\n"
}
out += formatReviews(reviews)
if ciStatus != nil {
var summary, errors string
for _, s := range ciStatus.Statuses {
summary += ciStatusSymbols[s.State]
if s.State != gitea.StatusSuccess {
errors += fmt.Sprintf(" - [**%s**:\t%s](%s)\n", s.Context, s.Description, s.TargetURL)
}
}
for k, v := range revMap {
out += fmt.Sprintf("\n @%s: %s", k, v)
if len(ciStatus.Statuses) != 0 {
out += fmt.Sprintf("- CI: %s\n%s", summary, errors)
}
}
if pr.State == gitea.StateOpen && pr.Mergeable {
out += "\nNo Conflicts"
if pr.State == gitea.StateOpen {
if pr.Mergeable {
out += "- No Conflicts\n"
} else {
out += "- **Conflicting files**\n"
}
}
outputMarkdown(out)
}
func formatReviews(reviews []*gitea.PullReview) string {
result := ""
if len(reviews) == 0 {
return result
}
// deduplicate reviews by user (via review time & userID),
reviewByUser := make(map[int64]*gitea.PullReview)
for _, review := range reviews {
switch review.State {
case gitea.ReviewStateApproved,
gitea.ReviewStateRequestChanges,
gitea.ReviewStateRequestReview:
if r, ok := reviewByUser[review.Reviewer.ID]; !ok || review.Submitted.After(r.Submitted) {
reviewByUser[review.Reviewer.ID] = review
}
}
}
// group reviews by type
usersByState := make(map[gitea.ReviewStateType][]string)
for _, r := range reviewByUser {
u := r.Reviewer.UserName
users := usersByState[r.State]
usersByState[r.State] = append(users, u)
}
// stringify
for state, user := range usersByState {
result += fmt.Sprintf("- %s by @%s\n", state, strings.Join(user, ", @"))
}
return result
}
// PullsList prints a listing of pulls
func PullsList(prs []*gitea.PullRequest, output string) {
t := tableWithHeader(

View File

@ -76,7 +76,7 @@ func CreatePull(login *config.Login, repoOwner, repoName, base, head, title, des
return fmt.Errorf("Could not create PR from %s to %s:%s: %s", head, repoOwner, base, err)
}
print.PullDetails(pr, nil)
print.PullDetails(pr, nil, nil)
fmt.Println(pr.HTMLURL)