From 790df28ae108b9974609601d4fe1db09e470d063 Mon Sep 17 00:00:00 2001 From: Brad Rydzewski Date: Mon, 26 Oct 2015 15:31:42 -0700 Subject: [PATCH] initial commit. compiles but hasn't been tested. needs docs too --- .drone.yml | 29 ++++++++++++++++ .gitignore | 3 ++ logo.svg | 20 +++++++++++ main.go | 47 ++++++++++++++++++++++++++ sender.go | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++ template.go | 41 +++++++++++++++++++++++ 6 files changed, 236 insertions(+) create mode 100644 .drone.yml create mode 100644 logo.svg create mode 100644 main.go create mode 100644 sender.go create mode 100644 template.go diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..b11694e --- /dev/null +++ b/.drone.yml @@ -0,0 +1,29 @@ +build: + image: golang:1.5 + environment: + - GO15VENDOREXPERIMENT=1 + - GOOS=linux + - GOARCH=amd64 + - CGO_ENABLED=0 + commands: + - go get + - go build + - go test + +publish: + docker: + username: drone + password: $$DOCKER_PASS + email: $$DOCKER_EMAIL + repo: plugins/drone-email + when: + branch: master + +plugin: + name: Email + desc: Send build status notifications via email. + type: notify + image: plugins/drone-email + labels: + - email + diff --git a/.gitignore b/.gitignore index daf913b..47f3ba5 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ _testmain.go *.exe *.test *.prof + +drone-email + diff --git a/logo.svg b/logo.svg new file mode 100644 index 0000000..815aa63 --- /dev/null +++ b/logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..8f54858 --- /dev/null +++ b/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "os" + + "github.com/drone/drone-go/drone" + "github.com/drone/drone-go/plugin" +) + +type Email struct { + Recipients []string `json:"recipients"` + + Host string `json:"host"` + Port string `json:"port"` + From string `json:"from"` + Username string `json:"username"` + Password string `json:"password"` +} + +type Context struct { + Email Email + Build drone.Build + Repo drone.Repo + System drone.System +} + +func main() { + repo := drone.Repo{} + build := drone.Build{} + system := drone.System{} + email := Email{} + + plugin.Param("system", &system) + plugin.Param("build", &build) + plugin.Param("repo", &repo) + plugin.Param("vargs", &email) + + err := Send(&Context{ + Email: email, + Build: build, + Repo: repo, + }) + if err != nil { + println(err.Error()) + os.Exit(1) + } +} diff --git a/sender.go b/sender.go new file mode 100644 index 0000000..8145fe4 --- /dev/null +++ b/sender.go @@ -0,0 +1,96 @@ +package main + +import ( + "bytes" + "fmt" + "net" + "net/smtp" + "strings" + + "github.com/drone/drone-go/drone" +) + +const ( + Subject = "[%s] %s/%s (%s - %s)" +) + +func Send(context *Context) error { + switch context.Build.Status { + case drone.StatusSuccess: + return SendSuccess(context) + default: + return SendFailure(context) + } +} + +// SendFailure sends email notifications to the list of +// recipients indicating the build failed. +func SendFailure(context *Context) error { + + // generate the email failure template + var buf bytes.Buffer + err := failureTemplate.ExecuteTemplate(&buf, "_", context) + if err != nil { + return err + } + + // generate the email subject + var subject = fmt.Sprintf( + Subject, + context.Build.Status, + context.Repo.Owner, + context.Repo.Name, + context.Build.Branch, + context.Build.Commit[:8], + ) + + return send(subject, buf.String(), context) +} + +// SendSuccess sends email notifications to the list of +// recipients indicating the build was a success. +func SendSuccess(context *Context) error { + + // generate the email success template + var buf bytes.Buffer + err := successTemplate.ExecuteTemplate(&buf, "_", context) + if err != nil { + return err + } + + // generate the email subject + var subject = fmt.Sprintf( + Subject, + context.Build.Status, + context.Repo.Owner, + context.Repo.Name, + context.Build.Branch, + context.Build.Commit[:8], + ) + + return send(subject, buf.String(), context) +} + +func send(subject, body string, c *Context) error { + + if len(c.Email.Recipients) == 0 { + c.Email.Recipients = []string{ + c.Build.Email, + } + } + + var auth smtp.Auth + var addr = net.JoinHostPort(c.Email.Host, c.Email.Port) + + // setup the authentication to the smtp server + // if the username and password are provided. + if len(c.Email.Username) > 0 { + auth = smtp.PlainAuth("", c.Email.Username, c.Email.Password, c.Email.Host) + } + + // genereate the raw email message + var to = strings.Join(c.Email.Recipients, ",") + var raw = fmt.Sprintf(rawMessage, c.Email.From, to, subject, body) + + return smtp.SendMail(addr, auth, c.Email.From, c.Email.Recipients, []byte(raw)) +} diff --git a/template.go b/template.go new file mode 100644 index 0000000..d71e997 --- /dev/null +++ b/template.go @@ -0,0 +1,41 @@ +package main + +import ( + "html/template" +) + +// raw email message template +var rawMessage = `From: %s +To: %s +Subject: %s +MIME-version: 1.0 +Content-Type: text/html; charset="UTF-8" +%s` + +// default success email template +var successTemplate = template.Must(template.New("_").Parse(` +

+ Build was Successful + (see results) +

+

Repository : {{.Repo.Owner}}/{{.Repo.Name}}

+

Commit : {{.Build.Commit}}

+

Author : {{.Build.Author}}

+

Branch : {{.Build.Branch}}

+

Message:

+

{{ .Build.Message }}

+`)) + +// default failure email template +var failureTemplate = template.Must(template.New("_").Parse(` +

+ Build Failed + (see results) +

+

Repository : {{.Repo.Owner}}/{{.Repo.Name}}

+

Commit : {{.Build.Commit}}

+

Author : {{.Build.Author}}

+

Branch : {{.Build.Branch}}

+

Message:

+

{{ .Build.Message }}

+`))