Move commit repo action from models to repofiles package (#7645)
* move commit repo action from models to repofiles package * fix unit tests
This commit is contained in:
parent
4d643a59db
commit
e7d4895732
198
models/action.go
198
models/action.go
|
@ -17,7 +17,6 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/git"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
@ -441,6 +440,9 @@ func (pc *PushCommits) ToAPIPayloadCommits(repoLink string) []*api.PayloadCommit
|
||||||
// AvatarLink tries to match user in database with e-mail
|
// AvatarLink tries to match user in database with e-mail
|
||||||
// in order to show custom avatar, and falls back to general avatar link.
|
// in order to show custom avatar, and falls back to general avatar link.
|
||||||
func (pc *PushCommits) AvatarLink(email string) string {
|
func (pc *PushCommits) AvatarLink(email string) string {
|
||||||
|
if pc.avatars == nil {
|
||||||
|
pc.avatars = make(map[string]string)
|
||||||
|
}
|
||||||
avatar, ok := pc.avatars[email]
|
avatar, ok := pc.avatars[email]
|
||||||
if ok {
|
if ok {
|
||||||
return avatar
|
return avatar
|
||||||
|
@ -655,200 +657,6 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit, bra
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommitRepoActionOptions represent options of a new commit action.
|
|
||||||
type CommitRepoActionOptions struct {
|
|
||||||
PusherName string
|
|
||||||
RepoOwnerID int64
|
|
||||||
RepoName string
|
|
||||||
RefFullName string
|
|
||||||
OldCommitID string
|
|
||||||
NewCommitID string
|
|
||||||
Commits *PushCommits
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommitRepoAction adds new commit action to the repository, and prepare
|
|
||||||
// corresponding webhooks.
|
|
||||||
func CommitRepoAction(opts CommitRepoActionOptions) error {
|
|
||||||
pusher, err := GetUserByName(opts.PusherName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("GetUserByName [%s]: %v", opts.PusherName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
repo, err := GetRepositoryByName(opts.RepoOwnerID, opts.RepoName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("GetRepositoryByName [owner_id: %d, name: %s]: %v", opts.RepoOwnerID, opts.RepoName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
refName := git.RefEndName(opts.RefFullName)
|
|
||||||
|
|
||||||
// Change default branch and empty status only if pushed ref is non-empty branch.
|
|
||||||
if repo.IsEmpty && opts.NewCommitID != git.EmptySHA && strings.HasPrefix(opts.RefFullName, git.BranchPrefix) {
|
|
||||||
repo.DefaultBranch = refName
|
|
||||||
repo.IsEmpty = false
|
|
||||||
if refName != "master" {
|
|
||||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
|
|
||||||
if !git.IsErrUnsupportedVersion(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change repository empty status and update last updated time.
|
|
||||||
if err = UpdateRepository(repo, false); err != nil {
|
|
||||||
return fmt.Errorf("UpdateRepository: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
isNewBranch := false
|
|
||||||
opType := ActionCommitRepo
|
|
||||||
// Check it's tag push or branch.
|
|
||||||
if strings.HasPrefix(opts.RefFullName, git.TagPrefix) {
|
|
||||||
opType = ActionPushTag
|
|
||||||
if opts.NewCommitID == git.EmptySHA {
|
|
||||||
opType = ActionDeleteTag
|
|
||||||
}
|
|
||||||
opts.Commits = &PushCommits{}
|
|
||||||
} else if opts.NewCommitID == git.EmptySHA {
|
|
||||||
opType = ActionDeleteBranch
|
|
||||||
opts.Commits = &PushCommits{}
|
|
||||||
} else {
|
|
||||||
// if not the first commit, set the compare URL.
|
|
||||||
if opts.OldCommitID == git.EmptySHA {
|
|
||||||
isNewBranch = true
|
|
||||||
} else {
|
|
||||||
opts.Commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = UpdateIssuesCommit(pusher, repo, opts.Commits.Commits, refName); err != nil {
|
|
||||||
log.Error("updateIssuesCommit: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(opts.Commits.Commits) > setting.UI.FeedMaxCommitNum {
|
|
||||||
opts.Commits.Commits = opts.Commits.Commits[:setting.UI.FeedMaxCommitNum]
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := json.Marshal(opts.Commits)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Marshal: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = NotifyWatchers(&Action{
|
|
||||||
ActUserID: pusher.ID,
|
|
||||||
ActUser: pusher,
|
|
||||||
OpType: opType,
|
|
||||||
Content: string(data),
|
|
||||||
RepoID: repo.ID,
|
|
||||||
Repo: repo,
|
|
||||||
RefName: refName,
|
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("NotifyWatchers: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
go HookQueue.Add(repo.ID)
|
|
||||||
}()
|
|
||||||
|
|
||||||
apiPusher := pusher.APIFormat()
|
|
||||||
apiRepo := repo.APIFormat(AccessModeNone)
|
|
||||||
|
|
||||||
var shaSum string
|
|
||||||
var isHookEventPush = false
|
|
||||||
switch opType {
|
|
||||||
case ActionCommitRepo: // Push
|
|
||||||
isHookEventPush = true
|
|
||||||
|
|
||||||
if isNewBranch {
|
|
||||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
|
||||||
if err != nil {
|
|
||||||
log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
shaSum, err = gitRepo.GetBranchCommitID(refName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err)
|
|
||||||
}
|
|
||||||
if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
|
|
||||||
Ref: refName,
|
|
||||||
Sha: shaSum,
|
|
||||||
RefType: "branch",
|
|
||||||
Repo: apiRepo,
|
|
||||||
Sender: apiPusher,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("PrepareWebhooks: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case ActionDeleteBranch: // Delete Branch
|
|
||||||
isHookEventPush = true
|
|
||||||
|
|
||||||
if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
|
|
||||||
Ref: refName,
|
|
||||||
RefType: "branch",
|
|
||||||
PusherType: api.PusherTypeUser,
|
|
||||||
Repo: apiRepo,
|
|
||||||
Sender: apiPusher,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("PrepareWebhooks.(delete branch): %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
case ActionPushTag: // Create
|
|
||||||
isHookEventPush = true
|
|
||||||
|
|
||||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
|
||||||
if err != nil {
|
|
||||||
log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
|
|
||||||
}
|
|
||||||
shaSum, err = gitRepo.GetTagCommitID(refName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err)
|
|
||||||
}
|
|
||||||
if err = PrepareWebhooks(repo, HookEventCreate, &api.CreatePayload{
|
|
||||||
Ref: refName,
|
|
||||||
Sha: shaSum,
|
|
||||||
RefType: "tag",
|
|
||||||
Repo: apiRepo,
|
|
||||||
Sender: apiPusher,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("PrepareWebhooks: %v", err)
|
|
||||||
}
|
|
||||||
case ActionDeleteTag: // Delete Tag
|
|
||||||
isHookEventPush = true
|
|
||||||
|
|
||||||
if err = PrepareWebhooks(repo, HookEventDelete, &api.DeletePayload{
|
|
||||||
Ref: refName,
|
|
||||||
RefType: "tag",
|
|
||||||
PusherType: api.PusherTypeUser,
|
|
||||||
Repo: apiRepo,
|
|
||||||
Sender: apiPusher,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("PrepareWebhooks.(delete tag): %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if isHookEventPush {
|
|
||||||
if err = PrepareWebhooks(repo, HookEventPush, &api.PushPayload{
|
|
||||||
Ref: opts.RefFullName,
|
|
||||||
Before: opts.OldCommitID,
|
|
||||||
After: opts.NewCommitID,
|
|
||||||
CompareURL: setting.AppURL + opts.Commits.CompareURL,
|
|
||||||
Commits: opts.Commits.ToAPIPayloadCommits(repo.HTMLURL()),
|
|
||||||
Repo: apiRepo,
|
|
||||||
Pusher: apiPusher,
|
|
||||||
Sender: apiPusher,
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("PrepareWebhooks: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err error) {
|
func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err error) {
|
||||||
if err = notifyWatchers(e, &Action{
|
if err = notifyWatchers(e, &Action{
|
||||||
ActUserID: doer.ID,
|
ActUserID: doer.ID,
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/modules/git"
|
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -409,119 +408,6 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
|
||||||
CheckConsistencyFor(t, &Action{})
|
CheckConsistencyFor(t, &Action{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCorrectRepoAction(t *testing.T, opts CommitRepoActionOptions, actionBean *Action) {
|
|
||||||
AssertNotExistsBean(t, actionBean)
|
|
||||||
assert.NoError(t, CommitRepoAction(opts))
|
|
||||||
AssertExistsAndLoadBean(t, actionBean)
|
|
||||||
CheckConsistencyFor(t, &Action{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCommitRepoAction(t *testing.T) {
|
|
||||||
samples := []struct {
|
|
||||||
userID int64
|
|
||||||
repositoryID int64
|
|
||||||
commitRepoActionOptions CommitRepoActionOptions
|
|
||||||
action Action
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
userID: 2,
|
|
||||||
repositoryID: 2,
|
|
||||||
commitRepoActionOptions: CommitRepoActionOptions{
|
|
||||||
RefFullName: "refName",
|
|
||||||
OldCommitID: "oldCommitID",
|
|
||||||
NewCommitID: "newCommitID",
|
|
||||||
Commits: &PushCommits{
|
|
||||||
avatars: make(map[string]string),
|
|
||||||
Commits: []*PushCommit{
|
|
||||||
{
|
|
||||||
Sha1: "abcdef1",
|
|
||||||
CommitterEmail: "user2@example.com",
|
|
||||||
CommitterName: "User Two",
|
|
||||||
AuthorEmail: "user4@example.com",
|
|
||||||
AuthorName: "User Four",
|
|
||||||
Message: "message1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Sha1: "abcdef2",
|
|
||||||
CommitterEmail: "user2@example.com",
|
|
||||||
CommitterName: "User Two",
|
|
||||||
AuthorEmail: "user2@example.com",
|
|
||||||
AuthorName: "User Two",
|
|
||||||
Message: "message2",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Len: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
action: Action{
|
|
||||||
OpType: ActionCommitRepo,
|
|
||||||
RefName: "refName",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userID: 2,
|
|
||||||
repositoryID: 1,
|
|
||||||
commitRepoActionOptions: CommitRepoActionOptions{
|
|
||||||
RefFullName: git.TagPrefix + "v1.1",
|
|
||||||
OldCommitID: git.EmptySHA,
|
|
||||||
NewCommitID: "newCommitID",
|
|
||||||
Commits: &PushCommits{},
|
|
||||||
},
|
|
||||||
action: Action{
|
|
||||||
OpType: ActionPushTag,
|
|
||||||
RefName: "v1.1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userID: 2,
|
|
||||||
repositoryID: 1,
|
|
||||||
commitRepoActionOptions: CommitRepoActionOptions{
|
|
||||||
RefFullName: git.TagPrefix + "v1.1",
|
|
||||||
OldCommitID: "oldCommitID",
|
|
||||||
NewCommitID: git.EmptySHA,
|
|
||||||
Commits: &PushCommits{},
|
|
||||||
},
|
|
||||||
action: Action{
|
|
||||||
OpType: ActionDeleteTag,
|
|
||||||
RefName: "v1.1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
userID: 2,
|
|
||||||
repositoryID: 1,
|
|
||||||
commitRepoActionOptions: CommitRepoActionOptions{
|
|
||||||
RefFullName: git.BranchPrefix + "feature/1",
|
|
||||||
OldCommitID: "oldCommitID",
|
|
||||||
NewCommitID: git.EmptySHA,
|
|
||||||
Commits: &PushCommits{},
|
|
||||||
},
|
|
||||||
action: Action{
|
|
||||||
OpType: ActionDeleteBranch,
|
|
||||||
RefName: "feature/1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range samples {
|
|
||||||
PrepareTestEnv(t)
|
|
||||||
|
|
||||||
user := AssertExistsAndLoadBean(t, &User{ID: s.userID}).(*User)
|
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: s.repositoryID, OwnerID: user.ID}).(*Repository)
|
|
||||||
repo.Owner = user
|
|
||||||
|
|
||||||
s.commitRepoActionOptions.PusherName = user.Name
|
|
||||||
s.commitRepoActionOptions.RepoOwnerID = user.ID
|
|
||||||
s.commitRepoActionOptions.RepoName = repo.Name
|
|
||||||
|
|
||||||
s.action.ActUserID = user.ID
|
|
||||||
s.action.RepoID = repo.ID
|
|
||||||
s.action.Repo = repo
|
|
||||||
s.action.IsPrivate = repo.IsPrivate
|
|
||||||
|
|
||||||
testCorrectRepoAction(t, s.commitRepoActionOptions, &s.action)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTransferRepoAction(t *testing.T) {
|
func TestTransferRepoAction(t *testing.T) {
|
||||||
assert.NoError(t, PrepareTestDatabase())
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,13 @@ func MainTest(m *testing.M, pathToGiteaRoot string) {
|
||||||
fatalTestError("url.Parse: %v\n", err)
|
fatalTestError("url.Parse: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = removeAllWithRetry(setting.RepoRootPath); err != nil {
|
||||||
|
fatalTestError("os.RemoveAll: %v\n", err)
|
||||||
|
}
|
||||||
|
if err = com.CopyDir(filepath.Join(pathToGiteaRoot, "integrations", "gitea-repositories-meta"), setting.RepoRootPath); err != nil {
|
||||||
|
fatalTestError("com.CopyDir: %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
exitStatus := m.Run()
|
exitStatus := m.Run()
|
||||||
if err = removeAllWithRetry(setting.RepoRootPath); err != nil {
|
if err = removeAllWithRetry(setting.RepoRootPath); err != nil {
|
||||||
fatalTestError("os.RemoveAll: %v\n", err)
|
fatalTestError("os.RemoveAll: %v\n", err)
|
||||||
|
|
|
@ -0,0 +1,211 @@
|
||||||
|
// 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 repofiles
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CommitRepoActionOptions represent options of a new commit action.
|
||||||
|
type CommitRepoActionOptions struct {
|
||||||
|
PusherName string
|
||||||
|
RepoOwnerID int64
|
||||||
|
RepoName string
|
||||||
|
RefFullName string
|
||||||
|
OldCommitID string
|
||||||
|
NewCommitID string
|
||||||
|
Commits *models.PushCommits
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitRepoAction adds new commit action to the repository, and prepare
|
||||||
|
// corresponding webhooks.
|
||||||
|
func CommitRepoAction(opts CommitRepoActionOptions) error {
|
||||||
|
pusher, err := models.GetUserByName(opts.PusherName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("GetUserByName [%s]: %v", opts.PusherName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := models.GetRepositoryByName(opts.RepoOwnerID, opts.RepoName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("GetRepositoryByName [owner_id: %d, name: %s]: %v", opts.RepoOwnerID, opts.RepoName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
refName := git.RefEndName(opts.RefFullName)
|
||||||
|
|
||||||
|
// Change default branch and empty status only if pushed ref is non-empty branch.
|
||||||
|
if repo.IsEmpty && opts.NewCommitID != git.EmptySHA && strings.HasPrefix(opts.RefFullName, git.BranchPrefix) {
|
||||||
|
repo.DefaultBranch = refName
|
||||||
|
repo.IsEmpty = false
|
||||||
|
if refName != "master" {
|
||||||
|
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
|
||||||
|
if !git.IsErrUnsupportedVersion(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change repository empty status and update last updated time.
|
||||||
|
if err = models.UpdateRepository(repo, false); err != nil {
|
||||||
|
return fmt.Errorf("UpdateRepository: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
isNewBranch := false
|
||||||
|
opType := models.ActionCommitRepo
|
||||||
|
// Check it's tag push or branch.
|
||||||
|
if strings.HasPrefix(opts.RefFullName, git.TagPrefix) {
|
||||||
|
opType = models.ActionPushTag
|
||||||
|
if opts.NewCommitID == git.EmptySHA {
|
||||||
|
opType = models.ActionDeleteTag
|
||||||
|
}
|
||||||
|
opts.Commits = &models.PushCommits{}
|
||||||
|
} else if opts.NewCommitID == git.EmptySHA {
|
||||||
|
opType = models.ActionDeleteBranch
|
||||||
|
opts.Commits = &models.PushCommits{}
|
||||||
|
} else {
|
||||||
|
// if not the first commit, set the compare URL.
|
||||||
|
if opts.OldCommitID == git.EmptySHA {
|
||||||
|
isNewBranch = true
|
||||||
|
} else {
|
||||||
|
opts.Commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = models.UpdateIssuesCommit(pusher, repo, opts.Commits.Commits, refName); err != nil {
|
||||||
|
log.Error("updateIssuesCommit: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opts.Commits.Commits) > setting.UI.FeedMaxCommitNum {
|
||||||
|
opts.Commits.Commits = opts.Commits.Commits[:setting.UI.FeedMaxCommitNum]
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(opts.Commits)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Marshal: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = models.NotifyWatchers(&models.Action{
|
||||||
|
ActUserID: pusher.ID,
|
||||||
|
ActUser: pusher,
|
||||||
|
OpType: opType,
|
||||||
|
Content: string(data),
|
||||||
|
RepoID: repo.ID,
|
||||||
|
Repo: repo,
|
||||||
|
RefName: refName,
|
||||||
|
IsPrivate: repo.IsPrivate,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("NotifyWatchers: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
go models.HookQueue.Add(repo.ID)
|
||||||
|
}()
|
||||||
|
|
||||||
|
apiPusher := pusher.APIFormat()
|
||||||
|
apiRepo := repo.APIFormat(models.AccessModeNone)
|
||||||
|
|
||||||
|
var shaSum string
|
||||||
|
var isHookEventPush = false
|
||||||
|
switch opType {
|
||||||
|
case models.ActionCommitRepo: // Push
|
||||||
|
isHookEventPush = true
|
||||||
|
|
||||||
|
if isNewBranch {
|
||||||
|
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
shaSum, err = gitRepo.GetBranchCommitID(refName)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("GetBranchCommitID[%s]: %v", opts.RefFullName, err)
|
||||||
|
}
|
||||||
|
if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{
|
||||||
|
Ref: refName,
|
||||||
|
Sha: shaSum,
|
||||||
|
RefType: "branch",
|
||||||
|
Repo: apiRepo,
|
||||||
|
Sender: apiPusher,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("PrepareWebhooks: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case models.ActionDeleteBranch: // Delete Branch
|
||||||
|
isHookEventPush = true
|
||||||
|
|
||||||
|
if err = models.PrepareWebhooks(repo, models.HookEventDelete, &api.DeletePayload{
|
||||||
|
Ref: refName,
|
||||||
|
RefType: "branch",
|
||||||
|
PusherType: api.PusherTypeUser,
|
||||||
|
Repo: apiRepo,
|
||||||
|
Sender: apiPusher,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("PrepareWebhooks.(delete branch): %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
case models.ActionPushTag: // Create
|
||||||
|
isHookEventPush = true
|
||||||
|
|
||||||
|
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("OpenRepository[%s]: %v", repo.RepoPath(), err)
|
||||||
|
}
|
||||||
|
shaSum, err = gitRepo.GetTagCommitID(refName)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("GetTagCommitID[%s]: %v", opts.RefFullName, err)
|
||||||
|
}
|
||||||
|
if err = models.PrepareWebhooks(repo, models.HookEventCreate, &api.CreatePayload{
|
||||||
|
Ref: refName,
|
||||||
|
Sha: shaSum,
|
||||||
|
RefType: "tag",
|
||||||
|
Repo: apiRepo,
|
||||||
|
Sender: apiPusher,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("PrepareWebhooks: %v", err)
|
||||||
|
}
|
||||||
|
case models.ActionDeleteTag: // Delete Tag
|
||||||
|
isHookEventPush = true
|
||||||
|
|
||||||
|
if err = models.PrepareWebhooks(repo, models.HookEventDelete, &api.DeletePayload{
|
||||||
|
Ref: refName,
|
||||||
|
RefType: "tag",
|
||||||
|
PusherType: api.PusherTypeUser,
|
||||||
|
Repo: apiRepo,
|
||||||
|
Sender: apiPusher,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("PrepareWebhooks.(delete tag): %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if isHookEventPush {
|
||||||
|
if err = models.PrepareWebhooks(repo, models.HookEventPush, &api.PushPayload{
|
||||||
|
Ref: opts.RefFullName,
|
||||||
|
Before: opts.OldCommitID,
|
||||||
|
After: opts.NewCommitID,
|
||||||
|
CompareURL: setting.AppURL + opts.Commits.CompareURL,
|
||||||
|
Commits: opts.Commits.ToAPIPayloadCommits(repo.HTMLURL()),
|
||||||
|
Repo: apiRepo,
|
||||||
|
Pusher: apiPusher,
|
||||||
|
Sender: apiPusher,
|
||||||
|
}); err != nil {
|
||||||
|
return fmt.Errorf("PrepareWebhooks: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
// 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 repofiles
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/modules/git"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testCorrectRepoAction(t *testing.T, opts CommitRepoActionOptions, actionBean *models.Action) {
|
||||||
|
models.AssertNotExistsBean(t, actionBean)
|
||||||
|
assert.NoError(t, CommitRepoAction(opts))
|
||||||
|
models.AssertExistsAndLoadBean(t, actionBean)
|
||||||
|
models.CheckConsistencyFor(t, &models.Action{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommitRepoAction(t *testing.T) {
|
||||||
|
samples := []struct {
|
||||||
|
userID int64
|
||||||
|
repositoryID int64
|
||||||
|
commitRepoActionOptions CommitRepoActionOptions
|
||||||
|
action models.Action
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
userID: 2,
|
||||||
|
repositoryID: 2,
|
||||||
|
commitRepoActionOptions: CommitRepoActionOptions{
|
||||||
|
RefFullName: "refName",
|
||||||
|
OldCommitID: "oldCommitID",
|
||||||
|
NewCommitID: "newCommitID",
|
||||||
|
Commits: &models.PushCommits{
|
||||||
|
Commits: []*models.PushCommit{
|
||||||
|
{
|
||||||
|
Sha1: "abcdef1",
|
||||||
|
CommitterEmail: "user2@example.com",
|
||||||
|
CommitterName: "User Two",
|
||||||
|
AuthorEmail: "user4@example.com",
|
||||||
|
AuthorName: "User Four",
|
||||||
|
Message: "message1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Sha1: "abcdef2",
|
||||||
|
CommitterEmail: "user2@example.com",
|
||||||
|
CommitterName: "User Two",
|
||||||
|
AuthorEmail: "user2@example.com",
|
||||||
|
AuthorName: "User Two",
|
||||||
|
Message: "message2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Len: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
action: models.Action{
|
||||||
|
OpType: models.ActionCommitRepo,
|
||||||
|
RefName: "refName",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userID: 2,
|
||||||
|
repositoryID: 1,
|
||||||
|
commitRepoActionOptions: CommitRepoActionOptions{
|
||||||
|
RefFullName: git.TagPrefix + "v1.1",
|
||||||
|
OldCommitID: git.EmptySHA,
|
||||||
|
NewCommitID: "newCommitID",
|
||||||
|
Commits: &models.PushCommits{},
|
||||||
|
},
|
||||||
|
action: models.Action{
|
||||||
|
OpType: models.ActionPushTag,
|
||||||
|
RefName: "v1.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userID: 2,
|
||||||
|
repositoryID: 1,
|
||||||
|
commitRepoActionOptions: CommitRepoActionOptions{
|
||||||
|
RefFullName: git.TagPrefix + "v1.1",
|
||||||
|
OldCommitID: "oldCommitID",
|
||||||
|
NewCommitID: git.EmptySHA,
|
||||||
|
Commits: &models.PushCommits{},
|
||||||
|
},
|
||||||
|
action: models.Action{
|
||||||
|
OpType: models.ActionDeleteTag,
|
||||||
|
RefName: "v1.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userID: 2,
|
||||||
|
repositoryID: 1,
|
||||||
|
commitRepoActionOptions: CommitRepoActionOptions{
|
||||||
|
RefFullName: git.BranchPrefix + "feature/1",
|
||||||
|
OldCommitID: "oldCommitID",
|
||||||
|
NewCommitID: git.EmptySHA,
|
||||||
|
Commits: &models.PushCommits{},
|
||||||
|
},
|
||||||
|
action: models.Action{
|
||||||
|
OpType: models.ActionDeleteBranch,
|
||||||
|
RefName: "feature/1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range samples {
|
||||||
|
models.PrepareTestEnv(t)
|
||||||
|
|
||||||
|
user := models.AssertExistsAndLoadBean(t, &models.User{ID: s.userID}).(*models.User)
|
||||||
|
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: s.repositoryID, OwnerID: user.ID}).(*models.Repository)
|
||||||
|
repo.Owner = user
|
||||||
|
|
||||||
|
s.commitRepoActionOptions.PusherName = user.Name
|
||||||
|
s.commitRepoActionOptions.RepoOwnerID = user.ID
|
||||||
|
s.commitRepoActionOptions.RepoName = repo.Name
|
||||||
|
|
||||||
|
s.action.ActUserID = user.ID
|
||||||
|
s.action.RepoID = repo.ID
|
||||||
|
s.action.Repo = repo
|
||||||
|
s.action.IsPrivate = repo.IsPrivate
|
||||||
|
|
||||||
|
testCorrectRepoAction(t, s.commitRepoActionOptions, &s.action)
|
||||||
|
}
|
||||||
|
}
|
|
@ -497,7 +497,7 @@ func PushUpdate(repo *models.Repository, branch string, opts models.PushUpdateOp
|
||||||
commits = models.ListToPushCommits(l)
|
commits = models.ListToPushCommits(l)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := models.CommitRepoAction(models.CommitRepoActionOptions{
|
if err := CommitRepoAction(CommitRepoActionOptions{
|
||||||
PusherName: opts.PusherName,
|
PusherName: opts.PusherName,
|
||||||
RepoOwnerID: repo.OwnerID,
|
RepoOwnerID: repo.OwnerID,
|
||||||
RepoName: repo.Name,
|
RepoName: repo.Name,
|
||||||
|
|
Loading…
Reference in New Issue