Skip to content

Commit ff85dd3

Browse files
lunnyzeripath
authored andcommitted
Add commit statuses reports on pull request view (#6845)
* Add commit statuses reports on pull view * Add some translations * improve the UI * fix fmt * fix tests * add a new test git repo to fix tests * fix bug when headRepo or headBranch missing * fix tests * fix tests * fix consistency * fix tests * fix tests * change the test repo * fix tests * fix tests * fix migration * keep db size consistency * fix translation * change commit hash status table unique index * remove unused table * use char instead varchar * make hashCommitStatusContext private * split merge section with status check on pull view ui * fix tests; fix arc-green theme on pull ui
1 parent 1e46eed commit ff85dd3

File tree

23 files changed

+236
-85
lines changed

23 files changed

+236
-85
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0abcb056019adb8336cf9db3ad9d9cf80cd4b141

integrations/pull_merge_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func TestCantMergeWorkInProgress(t *testing.T) {
159159
req := NewRequest(t, "GET", resp.Header().Get("Location"))
160160
resp = session.MakeRequest(t, req, http.StatusOK)
161161
htmlDoc := NewHTMLParser(t, resp.Body)
162-
text := strings.TrimSpace(htmlDoc.doc.Find(".merge.segment > .text.grey").Text())
162+
text := strings.TrimSpace(htmlDoc.doc.Find(".merge-section.segment > .text.grey").Text())
163163
assert.NotEmpty(t, text, "Can't find WIP text")
164164

165165
// remove <strong /> from lang

models/status.go renamed to models/commit_status.go

Lines changed: 33 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@ package models
66

77
import (
88
"container/list"
9+
"crypto/sha1"
910
"fmt"
1011
"strings"
1112

12-
"code.gitea.io/gitea/modules/git"
1313
"code.gitea.io/gitea/modules/log"
1414
"code.gitea.io/gitea/modules/setting"
1515
api "code.gitea.io/gitea/modules/structs"
1616
"code.gitea.io/gitea/modules/util"
17-
18-
"github.com/go-xorm/xorm"
1917
)
2018

2119
// CommitStatusState holds the state of a Status
@@ -61,6 +59,7 @@ type CommitStatus struct {
6159
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
6260
TargetURL string `xorm:"TEXT"`
6361
Description string `xorm:"TEXT"`
62+
ContextHash string `xorm:"char(40) index"`
6463
Context string `xorm:"TEXT"`
6564
Creator *User `xorm:"-"`
6665
CreatorID int64
@@ -146,7 +145,7 @@ func GetLatestCommitStatus(repo *Repository, sha string, page int) ([]*CommitSta
146145
Table(&CommitStatus{}).
147146
Where("repo_id = ?", repo.ID).And("sha = ?", sha).
148147
Select("max( id ) as id").
149-
GroupBy("context").OrderBy("max( id ) desc").Find(&ids)
148+
GroupBy("context_hash").OrderBy("max( id ) desc").Find(&ids)
150149
if err != nil {
151150
return nil, err
152151
}
@@ -157,27 +156,6 @@ func GetLatestCommitStatus(repo *Repository, sha string, page int) ([]*CommitSta
157156
return statuses, x.In("id", ids).Find(&statuses)
158157
}
159158

160-
// GetCommitStatus populates a given status for a given commit.
161-
// NOTE: If ID or Index isn't given, and only Context, TargetURL and/or Description
162-
// is given, the CommitStatus created _last_ will be returned.
163-
func GetCommitStatus(repo *Repository, sha string, status *CommitStatus) (*CommitStatus, error) {
164-
conds := &CommitStatus{
165-
Context: status.Context,
166-
State: status.State,
167-
TargetURL: status.TargetURL,
168-
Description: status.Description,
169-
}
170-
has, err := x.Where("repo_id = ?", repo.ID).And("sha = ?", sha).Desc("created_unix").Get(conds)
171-
if err != nil {
172-
return nil, fmt.Errorf("GetCommitStatus[%s, %s]: %v", repo.RepoPath(), sha, err)
173-
}
174-
if !has {
175-
return nil, fmt.Errorf("GetCommitStatus[%s, %s]: not found", repo.RepoPath(), sha)
176-
}
177-
178-
return conds, nil
179-
}
180-
181159
// NewCommitStatusOptions holds options for creating a CommitStatus
182160
type NewCommitStatusOptions struct {
183161
Repo *Repository
@@ -186,31 +164,31 @@ type NewCommitStatusOptions struct {
186164
CommitStatus *CommitStatus
187165
}
188166

189-
func newCommitStatus(sess *xorm.Session, opts NewCommitStatusOptions) error {
190-
opts.CommitStatus.Description = strings.TrimSpace(opts.CommitStatus.Description)
191-
opts.CommitStatus.Context = strings.TrimSpace(opts.CommitStatus.Context)
192-
opts.CommitStatus.TargetURL = strings.TrimSpace(opts.CommitStatus.TargetURL)
193-
opts.CommitStatus.SHA = opts.SHA
194-
opts.CommitStatus.CreatorID = opts.Creator.ID
195-
167+
// NewCommitStatus save commit statuses into database
168+
func NewCommitStatus(opts NewCommitStatusOptions) error {
196169
if opts.Repo == nil {
197-
return fmt.Errorf("newCommitStatus[nil, %s]: no repository specified", opts.SHA)
170+
return fmt.Errorf("NewCommitStatus[nil, %s]: no repository specified", opts.SHA)
198171
}
199-
opts.CommitStatus.RepoID = opts.Repo.ID
200-
repoPath := opts.Repo.repoPath(sess)
201172

173+
repoPath := opts.Repo.RepoPath()
202174
if opts.Creator == nil {
203-
return fmt.Errorf("newCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA)
175+
return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA)
204176
}
205177

206-
gitRepo, err := git.OpenRepository(repoPath)
207-
if err != nil {
208-
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
209-
}
210-
if _, err := gitRepo.GetCommit(opts.SHA); err != nil {
211-
return fmt.Errorf("GetCommit[%s]: %v", opts.SHA, err)
178+
sess := x.NewSession()
179+
defer sess.Close()
180+
181+
if err := sess.Begin(); err != nil {
182+
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", opts.Repo.ID, opts.Creator.ID, opts.SHA, err)
212183
}
213184

185+
opts.CommitStatus.Description = strings.TrimSpace(opts.CommitStatus.Description)
186+
opts.CommitStatus.Context = strings.TrimSpace(opts.CommitStatus.Context)
187+
opts.CommitStatus.TargetURL = strings.TrimSpace(opts.CommitStatus.TargetURL)
188+
opts.CommitStatus.SHA = opts.SHA
189+
opts.CommitStatus.CreatorID = opts.Creator.ID
190+
opts.CommitStatus.RepoID = opts.Repo.ID
191+
214192
// Get the next Status Index
215193
var nextIndex int64
216194
lastCommitStatus := &CommitStatus{
@@ -220,46 +198,25 @@ func newCommitStatus(sess *xorm.Session, opts NewCommitStatusOptions) error {
220198
has, err := sess.Desc("index").Limit(1).Get(lastCommitStatus)
221199
if err != nil {
222200
if err := sess.Rollback(); err != nil {
223-
log.Error("newCommitStatus: sess.Rollback: %v", err)
201+
log.Error("NewCommitStatus: sess.Rollback: %v", err)
224202
}
225-
return fmt.Errorf("newCommitStatus[%s, %s]: %v", repoPath, opts.SHA, err)
203+
return fmt.Errorf("NewCommitStatus[%s, %s]: %v", repoPath, opts.SHA, err)
226204
}
227205
if has {
228-
log.Debug("newCommitStatus[%s, %s]: found", repoPath, opts.SHA)
206+
log.Debug("NewCommitStatus[%s, %s]: found", repoPath, opts.SHA)
229207
nextIndex = lastCommitStatus.Index
230208
}
231209
opts.CommitStatus.Index = nextIndex + 1
232-
log.Debug("newCommitStatus[%s, %s]: %d", repoPath, opts.SHA, opts.CommitStatus.Index)
210+
log.Debug("NewCommitStatus[%s, %s]: %d", repoPath, opts.SHA, opts.CommitStatus.Index)
211+
212+
opts.CommitStatus.ContextHash = hashCommitStatusContext(opts.CommitStatus.Context)
233213

234214
// Insert new CommitStatus
235215
if _, err = sess.Insert(opts.CommitStatus); err != nil {
236216
if err := sess.Rollback(); err != nil {
237-
log.Error("newCommitStatus: sess.Rollback: %v", err)
217+
log.Error("Insert CommitStatus: sess.Rollback: %v", err)
238218
}
239-
return fmt.Errorf("newCommitStatus[%s, %s]: %v", repoPath, opts.SHA, err)
240-
}
241-
242-
return nil
243-
}
244-
245-
// NewCommitStatus creates a new CommitStatus given a bunch of parameters
246-
// NOTE: All text-values will be trimmed from whitespaces.
247-
// Requires: Repo, Creator, SHA
248-
func NewCommitStatus(repo *Repository, creator *User, sha string, status *CommitStatus) error {
249-
sess := x.NewSession()
250-
defer sess.Close()
251-
252-
if err := sess.Begin(); err != nil {
253-
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err)
254-
}
255-
256-
if err := newCommitStatus(sess, NewCommitStatusOptions{
257-
Repo: repo,
258-
Creator: creator,
259-
SHA: sha,
260-
CommitStatus: status,
261-
}); err != nil {
262-
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err)
219+
return fmt.Errorf("Insert CommitStatus[%s, %s]: %v", repoPath, opts.SHA, err)
263220
}
264221

265222
return sess.Commit()
@@ -295,3 +252,8 @@ func ParseCommitsWithStatus(oldCommits *list.List, repo *Repository) *list.List
295252
}
296253
return newCommits
297254
}
255+
256+
// hashCommitStatusContext hash context
257+
func hashCommitStatusContext(context string) string {
258+
return fmt.Sprintf("%x", sha1.Sum([]byte(context)))
259+
}
File renamed without changes.

models/fixtures/issue.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,14 @@
8686
created_unix: 946684830
8787
updated_unix: 978307200
8888

89+
-
90+
id: 8
91+
repo_id: 10
92+
index: 1
93+
poster_id: 11
94+
name: pr2
95+
content: a pull request
96+
is_closed: false
97+
is_pull: true
98+
created_unix: 946684820
99+
updated_unix: 978307180

models/fixtures/pull_request.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,17 @@
2626
base_branch: master
2727
merge_base: fedcba9876543210
2828
has_merged: false
29+
30+
-
31+
id: 3
32+
type: 0 # gitea pull request
33+
status: 2 # mergable
34+
issue_id: 8
35+
index: 1
36+
head_repo_id: 11
37+
base_repo_id: 10
38+
head_user_name: user13
39+
head_branch: branch2
40+
base_branch: master
41+
merge_base: 0abcb056019adb83
42+
has_merged: false

models/fixtures/repository.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
is_private: false
119119
num_issues: 0
120120
num_closed_issues: 0
121-
num_pulls: 0
121+
num_pulls: 1
122122
num_closed_pulls: 0
123123
is_mirror: false
124124
num_forks: 1
@@ -496,4 +496,4 @@
496496
num_stars: 0
497497
num_forks: 0
498498
num_issues: 0
499-
is_mirror: false
499+
is_mirror: false

models/migrations/migrations.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ var migrations = []Migration{
229229
NewMigration("add http method to webhook", addHTTPMethodToWebhook),
230230
// v87 -> v88
231231
NewMigration("add avatar field to repository", addAvatarFieldToRepository),
232+
// v88 -> v89
233+
NewMigration("add commit status context field to commit_status", addCommitStatusContext),
232234
}
233235

234236
// Migrate database to current version

models/migrations/v87.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2019 Gitea. All rights reserved.
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
22
// Use of this source code is governed by a MIT-style
33
// license that can be found in the LICENSE file.
44

models/migrations/v88.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package migrations
6+
7+
import (
8+
"crypto/sha1"
9+
"fmt"
10+
11+
"github.com/go-xorm/xorm"
12+
)
13+
14+
func hashContext(context string) string {
15+
return fmt.Sprintf("%x", sha1.Sum([]byte(context)))
16+
}
17+
18+
func addCommitStatusContext(x *xorm.Engine) error {
19+
type CommitStatus struct {
20+
ID int64 `xorm:"pk autoincr"`
21+
ContextHash string `xorm:"char(40) index"`
22+
Context string `xorm:"TEXT"`
23+
}
24+
25+
if err := x.Sync2(new(CommitStatus)); err != nil {
26+
return err
27+
}
28+
29+
sess := x.NewSession()
30+
defer sess.Close()
31+
32+
var start = 0
33+
for {
34+
var statuses = make([]*CommitStatus, 0, 100)
35+
err := sess.OrderBy("id").Limit(100, start).Find(&statuses)
36+
if err != nil {
37+
return err
38+
}
39+
if len(statuses) == 0 {
40+
break
41+
}
42+
43+
if err = sess.Begin(); err != nil {
44+
return err
45+
}
46+
47+
for _, status := range statuses {
48+
status.ContextHash = hashContext(status.Context)
49+
if _, err := sess.ID(status.ID).Cols("context_hash").Update(status); err != nil {
50+
return err
51+
}
52+
}
53+
54+
if err := sess.Commit(); err != nil {
55+
return err
56+
}
57+
58+
if len(statuses) < 100 {
59+
break
60+
}
61+
62+
start += len(statuses)
63+
}
64+
65+
return nil
66+
}

modules/repofiles/commit_status.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2019 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package repofiles
6+
7+
import (
8+
"fmt"
9+
10+
"code.gitea.io/gitea/models"
11+
"code.gitea.io/gitea/modules/git"
12+
)
13+
14+
// CreateCommitStatus creates a new CommitStatus given a bunch of parameters
15+
// NOTE: All text-values will be trimmed from whitespaces.
16+
// Requires: Repo, Creator, SHA
17+
func CreateCommitStatus(repo *models.Repository, creator *models.User, sha string, status *models.CommitStatus) error {
18+
repoPath := repo.RepoPath()
19+
20+
// confirm that commit is exist
21+
gitRepo, err := git.OpenRepository(repoPath)
22+
if err != nil {
23+
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
24+
}
25+
if _, err := gitRepo.GetCommit(sha); err != nil {
26+
return fmt.Errorf("GetCommit[%s]: %v", sha, err)
27+
}
28+
29+
if err := models.NewCommitStatus(models.NewCommitStatusOptions{
30+
Repo: repo,
31+
Creator: creator,
32+
SHA: sha,
33+
CommitStatus: status,
34+
}); err != nil {
35+
return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %v", repo.ID, creator.ID, sha, err)
36+
}
37+
38+
return nil
39+
}

options/locale/locale_en-US.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,9 @@ pulls.rebase_merge_commit_pull_request = Rebase and Merge (--no-ff)
981981
pulls.squash_merge_pull_request = Squash and Merge
982982
pulls.invalid_merge_option = You cannot use this merge option for this pull request.
983983
pulls.open_unmerged_pull_exists = `You cannot perform a reopen operation because there is a pending pull request (#%d) with identical properties.`
984+
pulls.status_checking = Some checks are pending
985+
pulls.status_checks_success = All checks were successful
986+
pulls.status_checks_error = Some checks failed
984987
985988
milestones.new = New Milestone
986989
milestones.open_tab = %d Open

public/css/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ footer .ui.left,footer .ui.right{line-height:40px}
535535
.repository.view.issue .comment-list .comment .content>.header:before{border-right-color:#d3d3d4;border-width:9px;margin-top:-9px}
536536
.repository.view.issue .comment-list .comment .content>.header:after{border-right-color:#f7f7f7;border-width:8px;margin-top:-8px}
537537
.repository.view.issue .comment-list .comment .content>.header .text{max-width:78%;padding-top:10px;padding-bottom:10px}
538+
.repository.view.issue .comment-list .comment .content>.merge-section{border-top:1px solid #d4d4d5;background-color:#f7f7f7}
538539
.repository.view.issue .comment-list .comment .content .markdown{font-size:14px}
539540
.repository.view.issue .comment-list .comment .content .no-content{color:#767676;font-style:italic}
540541
.repository.view.issue .comment-list .comment .content>.bottom.segment{background:#f3f4f5}

public/css/theme-arc-green.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ footer{background:#2e323e;border-top:1px solid #313131}
111111
.ui.attached.segment{border:1px solid #404552}
112112
.repository.view.issue .comment-list .comment .content>.bottom.segment{background:#353945}
113113
.repository.view.issue .comment-list .comment .content .header{color:#dbdbdb;background-color:#404552;border-bottom:1px solid #353944}
114+
.repository.view.issue .comment-list .comment .content .merge-section{background-color:#404552;border-top:1px solid #353944}
114115
.ui .text.grey a{color:#dbdbdb!important}
115116
.ui.comments .comment .actions a{color:#dbdbdb}
116117
.repository.view.issue .comment-list .comment .content .header:after{border-right-color:#404552}

public/less/_repository.less

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,11 @@
813813
}
814814
}
815815

816+
> .merge-section {
817+
border-top: 1px solid #d4d4d5;
818+
background-color: #f7f7f7;
819+
}
820+
816821
.markdown {
817822
font-size: 14px;
818823
}

0 commit comments

Comments
 (0)