diff --git a/modules/git/utils.go b/modules/git/utils.go index e791f1604..2b823366b 100644 --- a/modules/git/utils.go +++ b/modules/git/utils.go @@ -88,6 +88,19 @@ func RefEndName(refStr string) string { return refStr } +// SplitRefName splits a full refname to reftype and simple refname +func SplitRefName(refStr string) (string, string) { + if strings.HasPrefix(refStr, BranchPrefix) { + return BranchPrefix, refStr[len(BranchPrefix):] + } + + if strings.HasPrefix(refStr, TagPrefix) { + return TagPrefix, refStr[len(TagPrefix):] + } + + return "", refStr +} + // ParseBool returns the boolean value represented by the string as per git's git_config_bool // true will be returned for the result if the string is empty, but valid will be false. // "true", "yes", "on" are all true, true diff --git a/modules/notification/action/action.go b/modules/notification/action/action.go index 70ab9975b..9caeb5aac 100644 --- a/modules/notification/action/action.go +++ b/modules/notification/action/action.go @@ -5,6 +5,7 @@ package action import ( + "encoding/json" "fmt" "path" "strings" @@ -206,3 +207,52 @@ func (*actionNotifier) NotifyMergePullRequest(pr *models.PullRequest, doer *mode log.Error("NotifyWatchers [%d]: %v", pr.ID, err) } } + +func (a *actionNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { + data, err := json.Marshal(commits) + if err != nil { + log.Error("json.Marshal: %v", err) + return + } + + if err := models.NotifyWatchers(&models.Action{ + ActUserID: repo.OwnerID, + ActUser: repo.MustOwner(), + OpType: models.ActionMirrorSyncPush, + RepoID: repo.ID, + Repo: repo, + IsPrivate: repo.IsPrivate, + RefName: refName, + Content: string(data), + }); err != nil { + log.Error("notifyWatchers: %v", err) + } +} + +func (a *actionNotifier) NotifySyncCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) { + if err := models.NotifyWatchers(&models.Action{ + ActUserID: repo.OwnerID, + ActUser: repo.MustOwner(), + OpType: models.ActionMirrorSyncCreate, + RepoID: repo.ID, + Repo: repo, + IsPrivate: repo.IsPrivate, + RefName: refFullName, + }); err != nil { + log.Error("notifyWatchers: %v", err) + } +} + +func (a *actionNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) { + if err := models.NotifyWatchers(&models.Action{ + ActUserID: repo.OwnerID, + ActUser: repo.MustOwner(), + OpType: models.ActionMirrorSyncCreate, + RepoID: repo.ID, + Repo: repo, + IsPrivate: repo.IsPrivate, + RefName: refFullName, + }); err != nil { + log.Error("notifyWatchers: %v", err) + } +} diff --git a/modules/notification/base/notifier.go b/modules/notification/base/notifier.go index 1935c3055..c8c89d22b 100644 --- a/modules/notification/base/notifier.go +++ b/modules/notification/base/notifier.go @@ -47,4 +47,8 @@ type Notifier interface { NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) NotifyCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) NotifyDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) + + NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) + NotifySyncCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) + NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) } diff --git a/modules/notification/base/null.go b/modules/notification/base/null.go index b9ecaed42..79e9f7f7f 100644 --- a/modules/notification/base/null.go +++ b/modules/notification/base/null.go @@ -130,3 +130,15 @@ func (*NullNotifier) NotifyRenameRepository(doer *models.User, repo *models.Repo // NotifyTransferRepository places a place holder function func (*NullNotifier) NotifyTransferRepository(doer *models.User, repo *models.Repository, oldOwnerName string) { } + +// NotifySyncPushCommits places a place holder function +func (*NullNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { +} + +// NotifySyncCreateRef places a place holder function +func (*NullNotifier) NotifySyncCreateRef(doer *models.User, repo *models.Repository, refType, refFullName string) { +} + +// NotifySyncDeleteRef places a place holder function +func (*NullNotifier) NotifySyncDeleteRef(doer *models.User, repo *models.Repository, refType, refFullName string) { +} diff --git a/modules/notification/notification.go b/modules/notification/notification.go index fa0b280e7..71d6e79e6 100644 --- a/modules/notification/notification.go +++ b/modules/notification/notification.go @@ -227,3 +227,24 @@ func NotifyDeleteRef(pusher *models.User, repo *models.Repository, refType, refF notifier.NotifyDeleteRef(pusher, repo, refType, refFullName) } } + +// NotifySyncPushCommits notifies commits pushed to notifiers +func NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { + for _, notifier := range notifiers { + notifier.NotifySyncPushCommits(pusher, repo, refName, oldCommitID, newCommitID, commits) + } +} + +// NotifySyncCreateRef notifies branch or tag creation to notifiers +func NotifySyncCreateRef(pusher *models.User, repo *models.Repository, refType, refFullName string) { + for _, notifier := range notifiers { + notifier.NotifySyncCreateRef(pusher, repo, refType, refFullName) + } +} + +// NotifySyncDeleteRef notifies branch or tag deletion to notifiers +func NotifySyncDeleteRef(pusher *models.User, repo *models.Repository, refType, refFullName string) { + for _, notifier := range notifiers { + notifier.NotifySyncDeleteRef(pusher, repo, refType, refFullName) + } +} diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index 213e33c09..4ef60fef8 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -695,3 +695,25 @@ func (m *webhookNotifier) NotifyUpdateRelease(doer *models.User, rel *models.Rel func (m *webhookNotifier) NotifyDeleteRelease(doer *models.User, rel *models.Release) { sendReleaseHook(doer, rel, api.HookReleaseDeleted) } + +func (m *webhookNotifier) NotifySyncPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *models.PushCommits) { + apiPusher := pusher.APIFormat() + apiCommits, err := commits.ToAPIPayloadCommits(repo.RepoPath(), repo.HTMLURL()) + if err != nil { + log.Error("commits.ToAPIPayloadCommits failed: %v", err) + return + } + + if err := webhook_module.PrepareWebhooks(repo, models.HookEventPush, &api.PushPayload{ + Ref: refName, + Before: oldCommitID, + After: newCommitID, + CompareURL: setting.AppURL + commits.CompareURL, + Commits: apiCommits, + Repo: repo.APIFormat(models.AccessModeOwner), + Pusher: apiPusher, + Sender: apiPusher, + }); err != nil { + log.Error("PrepareWebhooks: %v", err) + } +} diff --git a/services/mirror/mirror.go b/services/mirror/mirror.go index 8c8131b5c..d35a205d0 100644 --- a/services/mirror/mirror.go +++ b/services/mirror/mirror.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/sync" @@ -336,19 +337,17 @@ func syncMirror(repoID string) { continue } + tp, _ := git.SplitRefName(result.refName) + // Create reference if result.oldCommitID == gitShortEmptySha { - if err = SyncCreateAction(m.Repo, result.refName); err != nil { - log.Error("SyncCreateAction [repo_id: %d]: %v", m.RepoID, err) - } + notification.NotifySyncCreateRef(m.Repo.MustOwner(), m.Repo, tp, result.refName) continue } // Delete reference if result.newCommitID == gitShortEmptySha { - if err = SyncDeleteAction(m.Repo, result.refName); err != nil { - log.Error("SyncDeleteAction [repo_id: %d]: %v", m.RepoID, err) - } + notification.NotifySyncDeleteRef(m.Repo.MustOwner(), m.Repo, tp, result.refName) continue } @@ -368,15 +367,15 @@ func syncMirror(repoID string) { log.Error("CommitsBetweenIDs [repo_id: %d, new_commit_id: %s, old_commit_id: %s]: %v", m.RepoID, newCommitID, oldCommitID, err) continue } - if err = SyncPushAction(m.Repo, SyncPushActionOptions{ - RefName: result.refName, - OldCommitID: oldCommitID, - NewCommitID: newCommitID, - Commits: models.ListToPushCommits(commits), - }); err != nil { - log.Error("SyncPushAction [repo_id: %d]: %v", m.RepoID, err) - continue + + theCommits := models.ListToPushCommits(commits) + if len(theCommits.Commits) > setting.UI.FeedMaxCommitNum { + theCommits.Commits = theCommits.Commits[:setting.UI.FeedMaxCommitNum] } + + theCommits.CompareURL = m.Repo.ComposeCompareURL(oldCommitID, newCommitID) + + notification.NotifySyncPushCommits(m.Repo.MustOwner(), m.Repo, result.refName, oldCommitID, newCommitID, models.ListToPushCommits(commits)) } // Get latest commit date and update to current repository updated time diff --git a/services/mirror/sync.go b/services/mirror/sync.go deleted file mode 100644 index ba9e896dd..000000000 --- a/services/mirror/sync.go +++ /dev/null @@ -1,67 +0,0 @@ -// 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 mirror - -import ( - "encoding/json" - "fmt" - - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/notification" - "code.gitea.io/gitea/modules/setting" -) - -func syncAction(opType models.ActionType, repo *models.Repository, refName string, data []byte) error { - if err := models.NotifyWatchers(&models.Action{ - ActUserID: repo.OwnerID, - ActUser: repo.MustOwner(), - OpType: opType, - RepoID: repo.ID, - Repo: repo, - IsPrivate: repo.IsPrivate, - RefName: refName, - Content: string(data), - }); err != nil { - return fmt.Errorf("notifyWatchers: %v", err) - } - - return nil -} - -// SyncPushActionOptions mirror synchronization action options. -type SyncPushActionOptions struct { - RefName string - OldCommitID string - NewCommitID string - Commits *models.PushCommits -} - -// SyncPushAction adds new action for mirror synchronization of pushed commits. -func SyncPushAction(repo *models.Repository, opts SyncPushActionOptions) error { - if len(opts.Commits.Commits) > setting.UI.FeedMaxCommitNum { - opts.Commits.Commits = opts.Commits.Commits[:setting.UI.FeedMaxCommitNum] - } - - opts.Commits.CompareURL = repo.ComposeCompareURL(opts.OldCommitID, opts.NewCommitID) - - notification.NotifyPushCommits(repo.MustOwner(), repo, opts.RefName, opts.OldCommitID, opts.NewCommitID, opts.Commits) - - data, err := json.Marshal(opts.Commits) - if err != nil { - return err - } - - return syncAction(models.ActionMirrorSyncPush, repo, opts.RefName, data) -} - -// SyncCreateAction adds new action for mirror synchronization of new reference. -func SyncCreateAction(repo *models.Repository, refName string) error { - return syncAction(models.ActionMirrorSyncCreate, repo, refName, nil) -} - -// SyncDeleteAction adds new action for mirror synchronization of delete reference. -func SyncDeleteAction(repo *models.Repository, refName string) error { - return syncAction(models.ActionMirrorSyncDelete, repo, refName, nil) -}