diff options
author | Unknwon <u@gogs.io> | 2017-07-27 16:53:02 -0400 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2017-07-27 16:53:02 -0400 |
commit | 6bc11c44504135b232605c932c519901a680d4e1 (patch) | |
tree | e12a8d108ef2d00347a2d1789d50f61a1617cfaf | |
parent | 643c85e9c8fd237912652d14a0535dfddf614d2b (diff) |
hook: fix email not sent after push (#4430)
Turns out mail service was not initialized at all, also mail must
be sent in sync in hook mode before program exits.
-rw-r--r-- | cmd/hook.go | 10 | ||||
-rw-r--r-- | gogs.go | 2 | ||||
-rw-r--r-- | models/action.go | 3 | ||||
-rw-r--r-- | models/comment.go | 6 | ||||
-rw-r--r-- | models/issue_mail.go | 3 | ||||
-rw-r--r-- | pkg/mailer/mail.go | 12 | ||||
-rw-r--r-- | pkg/mailer/mailer.go | 21 | ||||
-rw-r--r-- | pkg/setting/setting.go | 24 | ||||
-rw-r--r-- | pkg/template/template.go | 17 | ||||
-rw-r--r-- | templates/.VERSION | 2 |
10 files changed, 72 insertions, 28 deletions
diff --git a/cmd/hook.go b/cmd/hook.go index 0ff4a1c6..f8b96970 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -11,6 +11,7 @@ import ( "fmt" "os" "os/exec" + "path" "path/filepath" "strings" @@ -22,7 +23,9 @@ import ( "github.com/gogits/gogs/models" "github.com/gogits/gogs/pkg/httplib" + "github.com/gogits/gogs/pkg/mailer" "github.com/gogits/gogs/pkg/setting" + "github.com/gogits/gogs/pkg/template" http "github.com/gogits/gogs/routes/repo" ) @@ -184,6 +187,13 @@ func runHookPostReceive(c *cli.Context) error { } setup(c, "hooks/post-receive.log", true) + // Post-receive hook does more than just gather Git information, + // so we need to setup additional services for email notifications. + setting.NewPostReceiveHookServices() + mailer.NewContext() + mailer.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"), + path.Join(setting.CustomPath, "templates/mail"), template.NewFuncMap()) + isWiki := strings.Contains(os.Getenv(http.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/") buf := bytes.NewBuffer(nil) @@ -16,7 +16,7 @@ import ( "github.com/gogits/gogs/pkg/setting" ) -const APP_VER = "0.11.28.0718" +const APP_VER = "0.11.29.0727" func init() { setting.AppVer = APP_VER diff --git a/models/action.go b/models/action.go index 8b15f1cf..288a1812 100644 --- a/models/action.go +++ b/models/action.go @@ -379,8 +379,7 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err if ref[0] == '#' { ref = fmt.Sprintf("%s%s", repo.FullName(), ref) } else if !strings.Contains(ref, "/") { - // We don't support User#ID syntax yet - // return ErrNotImplemented + // FIXME: We don't support User#ID syntax yet continue } diff --git a/models/comment.go b/models/comment.go index 1be559b0..bcea2268 100644 --- a/models/comment.go +++ b/models/comment.go @@ -188,7 +188,7 @@ func (cmt *Comment) mailParticipants(e Engine, opType ActionType, issue *Issue) issue.Content = fmt.Sprintf("Reopened #%d", issue.Index) } if err = mailIssueCommentToParticipants(issue, cmt.Poster, mentions); err != nil { - log.Error(4, "mailIssueCommentToParticipants: %v", err) + log.Error(2, "mailIssueCommentToParticipants: %v", err) } return nil @@ -290,10 +290,10 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err // Notify watchers for whatever action comes in, ignore if no action type. if act.OpType > 0 { if err = notifyWatchers(e, act); err != nil { - log.Error(4, "notifyWatchers: %v", err) + log.Error(2, "notifyWatchers: %v", err) } if err = comment.mailParticipants(e, act.OpType, opts.Issue); err != nil { - log.Error(4, "MailParticipants: %v", err) + log.Error(2, "MailParticipants: %v", err) } } diff --git a/models/issue_mail.go b/models/issue_mail.go index 25f580d9..7ee38e63 100644 --- a/models/issue_mail.go +++ b/models/issue_mail.go @@ -155,7 +155,6 @@ func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string) tos = append(tos, mentions[i]) } mailer.SendIssueMentionMail(NewMailerIssue(issue), NewMailerRepo(issue.Repo), NewMailerUser(doer), GetUserEmailsByNames(tos)) - return nil } @@ -168,7 +167,7 @@ func (issue *Issue) MailParticipants() (err error) { } if err = mailIssueCommentToParticipants(issue, issue.Poster, mentions); err != nil { - log.Error(4, "mailIssueCommentToParticipants: %v", err) + log.Error(2, "mailIssueCommentToParticipants: %v", err) } return nil diff --git a/pkg/mailer/mail.go b/pkg/mailer/mail.go index a5c9c217..200e2e11 100644 --- a/pkg/mailer/mail.go +++ b/pkg/mailer/mail.go @@ -94,7 +94,7 @@ func SendUserMail(c *macaron.Context, u User, tpl, code, subject, info string) { msg := NewMessage([]string{u.Email()}, subject, body) msg.Info = fmt.Sprintf("UID: %d, %s", u.ID(), info) - SendAsync(msg) + Send(msg) } func SendActivateAccountMail(c *macaron.Context, u User) { @@ -122,7 +122,7 @@ func SendActivateEmailMail(c *macaron.Context, u User, email string) { msg := NewMessage([]string{email}, c.Tr("mail.activate_email"), body) msg.Info = fmt.Sprintf("UID: %d, activate email", u.ID()) - SendAsync(msg) + Send(msg) } // SendRegisterNotifyMail triggers a notify e-mail by admin created a account. @@ -139,7 +139,7 @@ func SendRegisterNotifyMail(c *macaron.Context, u User) { msg := NewMessage([]string{u.Email()}, c.Tr("mail.register_notify"), body) msg.Info = fmt.Sprintf("UID: %d, registration notify", u.ID()) - SendAsync(msg) + Send(msg) } // SendCollaboratorMail sends mail notification to new collaborator. @@ -160,7 +160,7 @@ func SendCollaboratorMail(u, doer User, repo Repository) { msg := NewMessage([]string{u.Email()}, subject, body) msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID()) - SendAsync(msg) + Send(msg) } func composeTplData(subject, body, link string) map[string]interface{} { @@ -192,7 +192,7 @@ func SendIssueCommentMail(issue Issue, repo Repository, doer User, tos []string) return } - SendAsync(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_COMMENT, tos, "issue comment")) + Send(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_COMMENT, tos, "issue comment")) } // SendIssueMentionMail composes and sends issue mention emails to target receivers. @@ -200,5 +200,5 @@ func SendIssueMentionMail(issue Issue, repo Repository, doer User, tos []string) if len(tos) == 0 { return } - SendAsync(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_MENTION, tos, "issue mention")) + Send(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_MENTION, tos, "issue mention")) } diff --git a/pkg/mailer/mailer.go b/pkg/mailer/mailer.go index 4c0960d6..25761832 100644 --- a/pkg/mailer/mailer.go +++ b/pkg/mailer/mailer.go @@ -24,6 +24,7 @@ import ( type Message struct { Info string // Message information for log purpose. *gomail.Message + confirmChan chan struct{} } // NewMessageFrom creates new mail message object with custom From header. @@ -48,9 +49,9 @@ func NewMessageFrom(to []string, from, subject, htmlBody string) *Message { } } msg.SetBody(contentType, body) - return &Message{ - Message: msg, + Message: msg, + confirmChan: make(chan struct{}), } } @@ -204,12 +205,14 @@ func processMailQueue() { } else { log.Trace("E-mails sent %s: %s", msg.GetHeader("To"), msg.Info) } + msg.confirmChan <- struct{}{} } } } var mailQueue chan *Message +// NewContext initializes settings for mailer. func NewContext() { // Need to check if mailQueue is nil because in during reinstall (user had installed // before but swithed install lock off), this function will be called again @@ -222,8 +225,18 @@ func NewContext() { go processMailQueue() } -func SendAsync(msg *Message) { +// Send puts new message object into mail queue. +// It returns without confirmation (mail processed asynchronously) in normal cases, +// but waits/blocks under hook mode to make sure mail has been sent. +func Send(msg *Message) { + mailQueue <- msg + + if setting.HookMode { + <-msg.confirmChan + return + } + go func() { - mailQueue <- msg + <-msg.confirmChan }() } diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 039c29c6..f206592d 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -832,9 +832,10 @@ var ( MailService *Mailer ) +// newMailService initializes mail service options from configuration. +// No non-error log will be printed in hook mode. func newMailService() { sec := Cfg.Section("mailer") - // Check mailer setting. if !sec.Key("ENABLED").MustBool() { return } @@ -863,6 +864,9 @@ func newMailService() { MailService.FromEmail = parsed.Address } + if HookMode { + return + } log.Info("Mail Service Enabled") } @@ -877,6 +881,8 @@ func newRegisterMailService() { log.Info("Register Mail Service Enabled") } +// newNotifyMailService initializes notification email service options from configuration. +// No non-error log will be printed in hook mode. func newNotifyMailService() { if !Cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").MustBool() { return @@ -885,6 +891,10 @@ func newNotifyMailService() { return } Service.EnableNotifyMail = true + + if HookMode { + return + } log.Info("Notify Mail Service Enabled") } @@ -901,3 +911,15 @@ func NewServices() { newRegisterMailService() newNotifyMailService() } + +// HookMode indicates whether program starts as Git server-side hook callback. +var HookMode bool + +// NewPostReceiveHookServices initializes all services that are needed by +// Git server-side post-receive hook callback. +func NewPostReceiveHookServices() { + HookMode = true + newService() + newMailService() + newNotifyMailService() +} diff --git a/pkg/template/template.go b/pkg/template/template.go index 882be145..f93aca74 100644 --- a/pkg/template/template.go +++ b/pkg/template/template.go @@ -22,11 +22,12 @@ import ( "gopkg.in/editorconfig/editorconfig-core-go.v1" "github.com/gogits/gogs/models" - "github.com/gogits/gogs/pkg/tool" "github.com/gogits/gogs/pkg/markup" "github.com/gogits/gogs/pkg/setting" + "github.com/gogits/gogs/pkg/tool" ) +// TODO: only initialize map once and save to a local variable to reduce copies. func NewFuncMap() []template.FuncMap { return []template.FuncMap{map[string]interface{}{ "GoVer": func() string { @@ -91,13 +92,13 @@ func NewFuncMap() []template.FuncMap { } return str[start:end] }, - "Join": strings.Join, - "EllipsisString": tool.EllipsisString, - "DiffTypeToStr": DiffTypeToStr, - "DiffLineTypeToStr": DiffLineTypeToStr, - "Sha1": Sha1, - "ShortSHA1": tool.ShortSHA1, - "MD5": tool.MD5, + "Join": strings.Join, + "EllipsisString": tool.EllipsisString, + "DiffTypeToStr": DiffTypeToStr, + "DiffLineTypeToStr": DiffLineTypeToStr, + "Sha1": Sha1, + "ShortSHA1": tool.ShortSHA1, + "MD5": tool.MD5, "ActionContent2Commits": ActionContent2Commits, "EscapePound": EscapePound, "RenderCommitMessage": RenderCommitMessage, diff --git a/templates/.VERSION b/templates/.VERSION index d3126a39..b95cfa9d 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.11.28.0718
\ No newline at end of file +0.11.29.0727
\ No newline at end of file |