From bf5af87eef8913004df63aef58f71628f9c057d0 Mon Sep 17 00:00:00 2001 From: Elias Norberg Date: Tue, 2 Apr 2019 21:54:29 +0200 Subject: [PATCH] Show last commit status in pull request lists (#6465) --- integrations/pull_status_test.go | 93 ++++++++++++++++++++++++++++ models/pull.go | 25 ++++++++ routers/repo/issue.go | 8 +++ routers/user/home.go | 6 ++ templates/repo/issue/list.tmpl | 6 ++ templates/user/dashboard/issues.tmpl | 6 ++ 6 files changed, 144 insertions(+) create mode 100644 integrations/pull_status_test.go diff --git a/integrations/pull_status_test.go b/integrations/pull_status_test.go new file mode 100644 index 00000000000..ad8bb236ef8 --- /dev/null +++ b/integrations/pull_status_test.go @@ -0,0 +1,93 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. +package integrations + +import ( + "fmt" + "net/http" + "path" + "testing" + + "code.gitea.io/gitea/models" + api "code.gitea.io/sdk/gitea" + + "github.com/stretchr/testify/assert" +) + +func TestPullCreate_CommitStatus(t *testing.T) { + prepareTestEnv(t) + session := loginUser(t, "user1") + testRepoFork(t, session, "user2", "repo1", "user1", "repo1") + testEditFileToNewBranch(t, session, "user1", "repo1", "master", "status1", "README.md", "status1") + + url := path.Join("user1", "repo1", "compare", "master...status1") + req := NewRequestWithValues(t, "POST", url, + map[string]string{ + "_csrf": GetCSRF(t, session, url), + "title": "pull request from status1", + }, + ) + session.MakeRequest(t, req, http.StatusFound) + + req = NewRequest(t, "GET", "/user1/repo1/pulls") + resp := session.MakeRequest(t, req, http.StatusOK) + doc := NewHTMLParser(t, resp.Body) + + // Request repository commits page + req = NewRequest(t, "GET", "/user1/repo1/pulls/1/commits") + resp = session.MakeRequest(t, req, http.StatusOK) + doc = NewHTMLParser(t, resp.Body) + + // Get first commit URL + commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href") + assert.True(t, exists) + assert.NotEmpty(t, commitURL) + + commitID := path.Base(commitURL) + + statusList := []models.CommitStatusState{ + models.CommitStatusPending, + models.CommitStatusError, + models.CommitStatusFailure, + models.CommitStatusWarning, + models.CommitStatusSuccess, + } + + statesIcons := map[models.CommitStatusState]string{ + models.CommitStatusPending: "circle icon yellow", + models.CommitStatusSuccess: "check icon green", + models.CommitStatusError: "warning icon red", + models.CommitStatusFailure: "remove icon red", + models.CommitStatusWarning: "warning sign icon yellow", + } + + // Update commit status, and check if icon is updated as well + for _, status := range statusList { + + // Call API to add status for commit + token := getTokenForLoggedInUser(t, session) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/user1/repo1/statuses/%s?token=%s", commitID, token), + api.CreateStatusOption{ + State: api.StatusState(status), + TargetURL: "http://test.ci/", + Description: "", + Context: "testci", + }, + ) + session.MakeRequest(t, req, http.StatusCreated) + + req = NewRequestf(t, "GET", "/user1/repo1/pulls/1/commits") + resp = session.MakeRequest(t, req, http.StatusOK) + doc = NewHTMLParser(t, resp.Body) + + commitURL, exists = doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href") + assert.True(t, exists) + assert.NotEmpty(t, commitURL) + assert.EqualValues(t, commitID, path.Base(commitURL)) + + cls, ok := doc.doc.Find("#commits-table tbody tr td.message i.commit-status").Last().Attr("class") + assert.True(t, ok) + assert.EqualValues(t, "commit-status "+statesIcons[status], cls) + } +} diff --git a/models/pull.go b/models/pull.go index ccd81553176..88f9b1f6e8a 100644 --- a/models/pull.go +++ b/models/pull.go @@ -292,6 +292,31 @@ func (pr *PullRequest) CanAutoMerge() bool { return pr.Status == PullRequestStatusMergeable } +// GetLastCommitStatus returns the last commit status for this pull request. +func (pr *PullRequest) GetLastCommitStatus() (status *CommitStatus, err error) { + if err = pr.GetHeadRepo(); err != nil { + return nil, err + } + + headGitRepo, err := git.OpenRepository(pr.HeadRepo.RepoPath()) + if err != nil { + return nil, err + } + + repo := pr.HeadRepo + lastCommitID, err := headGitRepo.GetBranchCommitID(pr.HeadBranch) + if err != nil { + return nil, err + } + + var statusList []*CommitStatus + statusList, err = GetLatestCommitStatus(repo, lastCommitID, 0) + if err != nil { + return nil, err + } + return CalcCommitStatus(statusList), nil +} + // MergeStyle represents the approach to merge commits into base branch. type MergeStyle string diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 45033e67c2e..42f3ddf4e85 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -214,6 +214,8 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB } } + var commitStatus = make(map[int64]*models.CommitStatus, len(issues)) + // Get posters. for i := range issues { // Check read status @@ -223,8 +225,14 @@ func issues(ctx *context.Context, milestoneID int64, isPullOption util.OptionalB ctx.ServerError("GetIsRead", err) return } + + if isPullOption == util.OptionalBoolTrue { + commitStatus[issues[i].PullRequest.ID], _ = issues[i].PullRequest.GetLastCommitStatus() + } } + ctx.Data["Issues"] = issues + ctx.Data["CommitStatus"] = commitStatus // Get assignees. ctx.Data["Assignees"], err = repo.GetAssignees() diff --git a/routers/user/home.go b/routers/user/home.go index c4e169befd9..740a9edc4e5 100644 --- a/routers/user/home.go +++ b/routers/user/home.go @@ -319,8 +319,13 @@ func Issues(ctx *context.Context) { return } + var commitStatus = make(map[int64]*models.CommitStatus, len(issues)) for _, issue := range issues { issue.Repo = showReposMap[issue.RepoID] + + if isPullList { + commitStatus[issue.PullRequest.ID], _ = issue.PullRequest.GetLastCommitStatus() + } } issueStats, err := models.GetUserIssueStats(models.UserIssueStatsOptions{ @@ -344,6 +349,7 @@ func Issues(ctx *context.Context) { } ctx.Data["Issues"] = issues + ctx.Data["CommitStatus"] = commitStatus ctx.Data["Repos"] = showRepos ctx.Data["Counts"] = counts ctx.Data["Page"] = paginater.New(total, setting.UI.IssuePagingNum, page, 5) diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl index 78352acb50b..88716484d2f 100644 --- a/templates/repo/issue/list.tmpl +++ b/templates/repo/issue/list.tmpl @@ -203,6 +203,12 @@
#{{.Index}}
{{.Title}} + {{if .IsPull }} + {{if (index $.CommitStatus .ID)}} + {{template "repo/commit_status" (index $.CommitStatus .ID)}} + {{end}} + {{end}} + {{if .Ref}} {{.Ref}} {{end}} diff --git a/templates/user/dashboard/issues.tmpl b/templates/user/dashboard/issues.tmpl index 93286df578f..0caa9a60dd7 100644 --- a/templates/user/dashboard/issues.tmpl +++ b/templates/user/dashboard/issues.tmpl @@ -66,6 +66,12 @@
{{if not $.RepoID}}{{.Repo.FullName}}{{end}}#{{.Index}}
{{.Title}} + {{if .IsPull }} + {{if (index $.CommitStatus .ID)}} + {{template "repo/commit_status" (index $.CommitStatus .ID)}} + {{end}} + {{end}} + {{with .Labels}} {{/* If we have any labels, we should show them with a 2.5 line height, this way they don't look