Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion services/issue/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ func getIssueFromRef(ctx context.Context, repo *repo_model.Repository, index int

// UpdateIssuesCommit checks if issues are manipulated by commit message.
func UpdateIssuesCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, commits []*repository.PushCommit, branchName string) error {
authorCache := make(map[string]*user_model.User)
getCommitAuthor := func(email string) (*user_model.User, error) {
if _, ok := authorCache[email]; ok {
return authorCache[email], nil
}
author, err := user_model.GetUserByEmail(ctx, email)
if err != nil {
if user_model.IsErrUserNotExist(err) {
authorCache[email] = nil
return nil, nil //nolint:nilnil // returns nil so that the email will be cached
}
return nil, err
}
authorCache[email] = author
return author, nil
}

// Commits are appended in the reverse order.
for i := len(commits) - 1; i >= 0; i-- {
c := commits[i]
Expand Down Expand Up @@ -215,7 +232,13 @@ func UpdateIssuesCommit(ctx context.Context, doer *user_model.User, repo *repo_m
refIssue.Repo = refRepo
if ref.Action == references.XRefActionCloses && !refIssue.IsClosed {
if len(ref.TimeLog) > 0 {
if err := issueAddTime(ctx, refIssue, doer, c.Timestamp, ref.TimeLog); err != nil {
timeDoer := doer
if author, err := getCommitAuthor(c.AuthorEmail); err != nil {
return err
} else if author != nil {
timeDoer = author
}
if err := issueAddTime(ctx, refIssue, timeDoer, c.Timestamp, ref.TimeLog); err != nil {
return err
}
}
Expand Down
28 changes: 28 additions & 0 deletions services/issue/commit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,34 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) {
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}

func TestUpdateIssuesCommitTimeLogUsesAuthor(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
CommitterEmail: "user2@example.com",
CommitterName: "User Two",
AuthorEmail: "user4@example.com",
AuthorName: "User Four",
Message: "close #1 @1h",
},
}

user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo.Owner = user

issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1})
unittest.AssertNotExistsBean(t, &issues_model.TrackedTime{IssueID: issue.ID, UserID: 4})

assert.NoError(t, UpdateIssuesCommit(t.Context(), user, repo, pushCommits, repo.DefaultBranch))
issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")

trackedTime := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{IssueID: issue.ID, UserID: 4})
assert.Equal(t, int64(3600), trackedTime.Time)
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}

func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
Expand Down