aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUnknwon <u@gogs.io>2017-07-27 16:53:02 -0400
committerUnknwon <u@gogs.io>2017-07-27 16:53:02 -0400
commit6bc11c44504135b232605c932c519901a680d4e1 (patch)
treee12a8d108ef2d00347a2d1789d50f61a1617cfaf
parent643c85e9c8fd237912652d14a0535dfddf614d2b (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.go10
-rw-r--r--gogs.go2
-rw-r--r--models/action.go3
-rw-r--r--models/comment.go6
-rw-r--r--models/issue_mail.go3
-rw-r--r--pkg/mailer/mail.go12
-rw-r--r--pkg/mailer/mailer.go21
-rw-r--r--pkg/setting/setting.go24
-rw-r--r--pkg/template/template.go17
-rw-r--r--templates/.VERSION2
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)
diff --git a/gogs.go b/gogs.go
index 1d0592d3..75e43da7 100644
--- a/gogs.go
+++ b/gogs.go
@@ -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