Skip to content

Commit 6a55749

Browse files
authored
Fix incorrect pull request counter (go-gitea#35819) (go-gitea#35841)
Fix go-gitea#35781, go-gitea#27472 Backport go-gitea#35819 The PR will not correct the wrong numbers automatically. There is a cron task `check_repo_stats` which will be run when Gitea start or midnight. It will correct the numbers.
1 parent 8116742 commit 6a55749

File tree

16 files changed

+204
-21
lines changed

16 files changed

+204
-21
lines changed

models/actions/main_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ func TestMain(m *testing.M) {
1313
unittest.MainTest(m, &unittest.TestOptions{
1414
FixtureFiles: []string{
1515
"action_runner_token.yml",
16+
"action_run.yml",
17+
"repository.yml",
1618
},
1719
})
1820
}

models/actions/run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ func (run *ActionRun) IsSchedule() bool {
184184
func updateRepoRunsNumbers(ctx context.Context, repo *repo_model.Repository) error {
185185
_, err := db.GetEngine(ctx).ID(repo.ID).
186186
NoAutoTime().
187+
Cols("num_action_runs", "num_closed_action_runs").
187188
SetExpr("num_action_runs",
188189
builder.Select("count(*)").From("action_run").
189190
Where(builder.Eq{"repo_id": repo.ID}),

models/actions/run_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package actions
5+
6+
import (
7+
"testing"
8+
9+
"code.gitea.io/gitea/models/db"
10+
repo_model "code.gitea.io/gitea/models/repo"
11+
"code.gitea.io/gitea/models/unittest"
12+
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestUpdateRepoRunsNumbers(t *testing.T) {
17+
assert.NoError(t, unittest.PrepareTestDatabase())
18+
19+
// update the number to a wrong one, the original is 3
20+
_, err := db.GetEngine(t.Context()).ID(4).Cols("num_closed_action_runs").Update(&repo_model.Repository{
21+
NumClosedActionRuns: 2,
22+
})
23+
assert.NoError(t, err)
24+
25+
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
26+
assert.Equal(t, 4, repo.NumActionRuns)
27+
assert.Equal(t, 2, repo.NumClosedActionRuns)
28+
29+
// now update will correct them, only num_actionr_runs and num_closed_action_runs should be updated
30+
err = updateRepoRunsNumbers(t.Context(), repo)
31+
assert.NoError(t, err)
32+
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
33+
assert.Equal(t, 4, repo.NumActionRuns)
34+
assert.Equal(t, 3, repo.NumClosedActionRuns)
35+
}

models/activities/notification.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ func SetNotificationStatus(ctx context.Context, notificationID int64, user *user
386386

387387
notification.Status = status
388388

389-
_, err = db.GetEngine(ctx).ID(notificationID).Update(notification)
389+
_, err = db.GetEngine(ctx).ID(notificationID).Cols("status").Update(notification)
390390
return notification, err
391391
}
392392

models/asymkey/gpg_key_verify.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func VerifyGPGKey(ctx context.Context, ownerID int64, keyID, token, signature st
7878
}
7979

8080
key.Verified = true
81-
if _, err := db.GetEngine(ctx).ID(key.ID).SetExpr("verified", true).Update(new(GPGKey)); err != nil {
81+
if _, err := db.GetEngine(ctx).ID(key.ID).Cols("verified").Update(key); err != nil {
8282
return "", err
8383
}
8484

models/fixtures/repository.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@
110110
num_closed_milestones: 0
111111
num_projects: 0
112112
num_closed_projects: 1
113+
num_action_runs: 4
114+
num_closed_action_runs: 3
113115
is_private: false
114116
is_empty: false
115117
is_archived: false

models/git/branch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to str
368368
}
369369

370370
// 1. update branch in database
371-
if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{
371+
if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Cols("name").Update(&Branch{
372372
Name: to,
373373
}); err != nil {
374374
return err

models/issues/comment.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -862,10 +862,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
862862
if err = UpdateCommentAttachments(ctx, comment, opts.Attachments); err != nil {
863863
return err
864864
}
865-
case CommentTypeReopen, CommentTypeClose:
866-
if err = repo_model.UpdateRepoIssueNumbers(ctx, opts.Issue.RepoID, opts.Issue.IsPull, true); err != nil {
867-
return err
868-
}
865+
// comment type reopen and close event have their own logic to update numbers but not here
869866
}
870867
// update the issue's updated_unix column
871868
return UpdateIssueCols(ctx, opts.Issue, "updated_unix")

models/issues/issue_update.go

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,19 @@ func updateIssueNumbers(ctx context.Context, issue *Issue, doer *user_model.User
146146
}
147147

148148
// update repository's issue closed number
149-
if err := repo_model.UpdateRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, true); err != nil {
150-
return nil, err
149+
switch cmtType {
150+
case CommentTypeClose, CommentTypeMergePull:
151+
// only increase closed count
152+
if err := IncrRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, false); err != nil {
153+
return nil, err
154+
}
155+
case CommentTypeReopen:
156+
// only decrease closed count
157+
if err := DecrRepoIssueNumbers(ctx, issue.RepoID, issue.IsPull, false, true); err != nil {
158+
return nil, err
159+
}
160+
default:
161+
return nil, fmt.Errorf("invalid comment type: %d", cmtType)
151162
}
152163

153164
return CreateComment(ctx, &CreateCommentOptions{
@@ -318,7 +329,6 @@ type NewIssueOptions struct {
318329
Issue *Issue
319330
LabelIDs []int64
320331
Attachments []string // In UUID format.
321-
IsPull bool
322332
}
323333

324334
// NewIssueWithIndex creates issue with given index
@@ -369,7 +379,8 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
369379
}
370380
}
371381

372-
if err := repo_model.UpdateRepoIssueNumbers(ctx, opts.Issue.RepoID, opts.IsPull, false); err != nil {
382+
// Update repository issue total count
383+
if err := IncrRepoIssueNumbers(ctx, opts.Repo.ID, opts.Issue.IsPull, true); err != nil {
373384
return err
374385
}
375386

@@ -439,6 +450,42 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, la
439450
})
440451
}
441452

453+
// IncrRepoIssueNumbers increments repository issue numbers.
454+
func IncrRepoIssueNumbers(ctx context.Context, repoID int64, isPull, totalOrClosed bool) error {
455+
dbSession := db.GetEngine(ctx)
456+
var colName string
457+
if totalOrClosed {
458+
colName = util.Iif(isPull, "num_pulls", "num_issues")
459+
} else {
460+
colName = util.Iif(isPull, "num_closed_pulls", "num_closed_issues")
461+
}
462+
_, err := dbSession.Incr(colName).ID(repoID).
463+
NoAutoCondition().NoAutoTime().
464+
Update(new(repo_model.Repository))
465+
return err
466+
}
467+
468+
// DecrRepoIssueNumbers decrements repository issue numbers.
469+
func DecrRepoIssueNumbers(ctx context.Context, repoID int64, isPull, includeTotal, includeClosed bool) error {
470+
if !includeTotal && !includeClosed {
471+
return fmt.Errorf("no numbers to decrease for repo id %d", repoID)
472+
}
473+
474+
dbSession := db.GetEngine(ctx)
475+
if includeTotal {
476+
colName := util.Iif(isPull, "num_pulls", "num_issues")
477+
dbSession = dbSession.Decr(colName)
478+
}
479+
if includeClosed {
480+
closedColName := util.Iif(isPull, "num_closed_pulls", "num_closed_issues")
481+
dbSession = dbSession.Decr(closedColName)
482+
}
483+
_, err := dbSession.ID(repoID).
484+
NoAutoCondition().NoAutoTime().
485+
Update(new(repo_model.Repository))
486+
return err
487+
}
488+
442489
// UpdateIssueMentions updates issue-user relations for mentioned users.
443490
func UpdateIssueMentions(ctx context.Context, issueID int64, mentions []*user_model.User) error {
444491
if len(mentions) == 0 {

models/issues/milestone.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ func updateMilestone(ctx context.Context, m *Milestone) error {
181181
func UpdateMilestoneCounters(ctx context.Context, id int64) error {
182182
e := db.GetEngine(ctx)
183183
_, err := e.ID(id).
184+
Cols("num_issues", "num_closed_issues").
184185
SetExpr("num_issues", builder.Select("count(*)").From("issue").Where(
185186
builder.Eq{"milestone_id": id},
186187
)).

0 commit comments

Comments
 (0)