diff --git a/Dockerfile b/Dockerfile
index 8829ecf..7f4f7b1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,9 +1,11 @@
-FROM golang
+FROM golang AS builder
WORKDIR /app
COPY . .
-RUN GO111MODULE=on go build -o drone-dingtalk-message .
+RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -a -o drone-dingtalk .
FROM alpine:latest
RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*
-COPY --from=0 /app/drone-dingtalk-message /bin
-ENTRYPOINT ["/bin/drone-dingtalk-message"]
+COPY --from=builder /app/drone-dingtalk /bin
+COPY --from=builder /app/tpls /app/tpls
+
+ENTRYPOINT ["/bin/drone-dingtalk"]
diff --git a/README.md b/README.md
index 2493f01..244d288 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
# Drone CI DingTalk Message Plugin
[](https://hub.docker.com/r/lddsb/drone-dingtalk-message) [](https://goreportcard.com/report/github.com/lddsb/drone-dingtalk-message) [](https://codecov.io/gh/lddsb/drone-dingtalk-message) [](LICENSE)
+just support `text`, `markdown` and `link` type now
### Drone CI Plugin Config
`0.8.x`
```yaml
@@ -36,34 +37,87 @@ String. Access token for group bot. (you can get the access token when you add a
String. Message type, plan support text, markdown, link and action card, but due to time issue, it's only support `markdown` and `text` now, and you can get the best experience by use markdown.
-`message_color`(when `type=markdown`)
+`tpl`
-Boolean value. This option can change the title and commit message color if turn on.
+String. Your custom `tpl`, it can be a local path or a remote http link.
-`success_color`(when `message_color=true`)
+`success_color`
String. You can customize the color for the `build success` message by this option, you should input a hex color, example: `008000`.
-`failure_color`(when `message_color=true`)
+`failure_color`
String. You can customize the color for the `build success` message by this option, you should input a hex color, example: `FF0000`.
-`sha_link`(when `type=markdown`)
-
-Boolean value. This option can link the sha to your source page when it turn on.
-
-`message_pic`(when `type=markdown`)
-
-Boolean value. If this option turn on, it will embed a image into the message.
-
-`success_pic`(when `message_pic=true`)
+`success_pic`
String. You can customize the picture for the `build success` message by this option.
-`failure_pic`(when `message_pic=true`)
+`failure_pic`
String. You can customize the picture for the `build failure` message by this option.
+`tpl_commit_branch_name`
+
+String. You can customize the [TPL_COMMIT_BRANCH] by this configuration item.
+
+`tpl_repo_short_name`
+
+String. You can customize the [TPL_REPO_SHORT_NAME] by this configuration item.
+
+`tpl_repo_full_name`
+
+String. You can customize the [TPL_REPO_FULL_NAME] by this configuration item.
+
+`tpl_build_status_sucdess`
+
+String. You can customize the [TPL_BUILD_STATUS] (when status=`success`) by this configuration item.
+
+`tpl_build_status_failure`
+
+String. You can customize the [TPL_BUILD_STATUS] (when status=`failure`) by this configuration item.
+
+### TPL
+> `tpl` won't work with message type `link` !!!
+
+That's a good news, we support `tpl` now.This is a example for `markdown` message:
+
+ # [TPL_REPO_FULL_NAME] build [TPL_BUILD_STATUS], takes [TPL_BUILD_CONSUMING]s
+ [TPL_COMMIT_MSG]
+
+ [TPL_COMMIT_SHA]([TPL_COMMIT_LINK])
+
+ [[TPL_AUTHOR_NAME]([TPL_AUTHOR_EMAIL])](mailto:[TPL_AUTHOR_EMAIL])
+
+ [Click To The Build Detail Page [TPL_STATUS_EMOTICON)]]([TPL_BUILD_LINK])
+You can write your own `tpl` what you want. The syntax of `tpl` is very simple, you can fill `tpl` with preset variables. It's a list of currently supported preset variables:
+
+| Variable | Value |
+| :-------------------: | :-------------------------------------------------: |
+| [TPL_REPO_SHORT_NAME] | current repo name(bare name) |
+| [TPL_REPO_FULL_NAME] | the full name(with group name) of current repo |
+| [TPL_REPO_GROUP_NAME] | the group name of current repo |
+| [TPL_REPO_OWNER_NAME] | the owner name of current repo |
+| [TPL_REPO_REMOTE_URL] | the remote url of current repo |
+| [TPL_BUILD_STATUS] | current build status(e.g., success, failure) |
+| [TPL_BUILD_LINK] | current build link |
+| [TPL_BUILD_EVENT] | current build event(e.g., push, pull request, etc.) |
+| [TPL_BUILD_CONSUMING] | current build consuming, second |
+| [TPL_COMMIT_SHA] | current commit sha |
+| [TPL_COMMIT_REF] | current commit ref(e.g., refs/heads/master, etc.) |
+| [TPL_COMMIT_LINK] | current commit remote url link |
+| [TPL_COMMIT_BRANCH] | current branch name(e.g., dev, etc) |
+| [TPL_COMMIT_MSG] | current commit message |
+| [TPL_AUTHOR_NAME] | current commit author name |
+| [TPL_AUTHOR_EMAIL] | current commit author email |
+| [TPL_AUTHOR_USERNAME] | current commit author username |
+| [TPL_AUTHOR_AVATAR] | current commit author avatar |
+| [TPL_STATUS_PIC] | custom pic for build status |
+| [TPL_STATUS_COLOR] | custom color for build status |
+| [TPL_STATUS_EMOTICON] | custom emoticon for build status |
+
+
+
### Screen Shot
- Send Success
@@ -89,12 +143,6 @@ String. You can customize the picture for the `build failure` message by this op

-### Todo
-
-- Multi-Type
-- Multi-Lang
-- More User Customization
-
### Development
We use `go mod` to manage dependencies, so it's easy to build.
@@ -111,3 +159,6 @@ $ cd /path/to/you/want && GO111MODULE=on go build .
```shell
$ ./drone-dingtalk-message -h
```
+
+### Todo
+- implement all message type
\ No newline at end of file
diff --git a/go.mod b/go.mod
index d3af10a..632795c 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,6 @@ go 1.12
require (
github.com/joho/godotenv v1.3.0
- github.com/lddsb/dingtalk-webhook v0.0.0-20190307231412-b4abe34b5fa9
+ github.com/lddsb/dingtalk-webhook v0.0.1
github.com/urfave/cli v1.20.0
)
diff --git a/go.sum b/go.sum
index da0fc6c..44c6e09 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,6 @@
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
-github.com/lddsb/dingtalk-webhook v0.0.0-20190307231412-b4abe34b5fa9 h1:ZeUdCEbcT0+l10jTSyjU9+18ZbDTz6TdkH6yGiCd9dQ=
-github.com/lddsb/dingtalk-webhook v0.0.0-20190307231412-b4abe34b5fa9/go.mod h1:5E+/sOBb6m+3ztqnZl4danEY3I5FeIwb12v12s9osbw=
+github.com/lddsb/dingtalk-webhook v0.0.1 h1:l4FdTMaRaHnrYfByALukFWK0ru9Rttl0dANg13/SnTI=
+github.com/lddsb/dingtalk-webhook v0.0.1/go.mod h1:5E+/sOBb6m+3ztqnZl4danEY3I5FeIwb12v12s9osbw=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
diff --git a/main.go b/main.go
index 09fdf91..717f1ff 100644
--- a/main.go
+++ b/main.go
@@ -2,11 +2,10 @@ package main
import (
"fmt"
- "log"
- "os"
-
_ "github.com/joho/godotenv/autoload"
"github.com/urfave/cli"
+ "log"
+ "os"
)
// Version of cli
@@ -36,12 +35,6 @@ func main() {
Usage: "dingtalk webhook access token",
EnvVar: "PLUGIN_ACCESS_TOKEN,PLUGIN_TOKEN",
},
- cli.StringFlag{
- Name: "config.lang",
- Value: "zh_CN",
- Usage: "the lang display (zh_CN or en_US, zh_CN is default)",
- EnvVar: "PLUGIN_LANG",
- },
cli.StringFlag{
Name: "config.message.type,message_type",
Usage: "dingtalk message type, like text, markdown, action card, link and feed card...",
@@ -57,6 +50,11 @@ func main() {
Usage: "at someone in a dingtalk group need this guy bind's mobile",
EnvVar: "PLUGIN_MSG_AT_MOBILES",
},
+ cli.StringFlag{
+ Name: "commit.author.username",
+ Usage: "providers the author username for the current commit",
+ EnvVar: "DRONE_COMMIT_AUTHOR",
+ },
cli.StringFlag{
Name: "commit.author.avatar",
Usage: "providers the author avatar url for the current commit",
@@ -94,10 +92,35 @@ func main() {
EnvVar: "DRONE_COMMIT_SHA",
},
cli.StringFlag{
- Name: "repo.fullname",
+ Name: "commit.ref",
+ Usage: "provider the commit ref for the current build",
+ EnvVar: "DRONE_COMMIT_REF",
+ },
+ cli.StringFlag{
+ Name: "repo.full.name",
Usage: "providers the full name of the repository",
EnvVar: "DRONE_REPO",
},
+ cli.StringFlag{
+ Name: "repo.name",
+ Usage: "provider the name of the repository",
+ EnvVar: "DRONE_REPO_NAME",
+ },
+ cli.StringFlag{
+ Name: "repo.group",
+ Usage: "provider the group of the repository",
+ EnvVar: "DRONE_REPO_NAMESPACE",
+ },
+ cli.StringFlag{
+ Name: "repo.remote.url",
+ Usage: "provider the remote url of the repository",
+ EnvVar: "DRONE_REMOTE_URL",
+ },
+ cli.StringFlag{
+ Name: "repo.owner",
+ Usage: "provider the owner of the repository",
+ EnvVar: "DRONE_REPO_OWNER",
+ },
cli.StringFlag{
Name: "build.status",
Usage: "build status",
@@ -110,39 +133,69 @@ func main() {
EnvVar: "DRONE_BUILD_LINK",
},
cli.StringFlag{
- Name: "config.success.pic.url",
- Usage: "config success picture url",
+ Name: "build.event",
+ Usage: "build event",
+ EnvVar: "DRONE_BUILD_EVENT",
+ },
+ cli.StringFlag{
+ Name: "build.started",
+ Usage: "build started",
+ EnvVar: "DRONE_BUILD_STARTED",
+ },
+ cli.StringFlag{
+ Name: "build.finished",
+ Usage: "build finished",
+ EnvVar: "DRONE_BUILD_FINISHED",
+ },
+ cli.StringFlag{
+ Name: "tpl.build.status.success",
+ Usage: "tpl.build status for replace success",
+ EnvVar: "TPL_BUILD_STATUS_SUCCESS, PLUGIN_TPL_BUILD_STATUS_SUCCESS",
+ },
+ cli.StringFlag{
+ Name: "tpl.build.status.failure",
+ Usage: "tpl.build status for replace failure",
+ EnvVar: "TPL_BUILD_STATUS_FAILURE, PLUGIN_TPL_BUILD_STATUS_FAILURE",
+ },
+ cli.StringFlag{
+ Name: "custom.pic.url.success",
+ Usage: "custom success picture url",
EnvVar: "SUCCESS_PICTURE_URL,PLUGIN_SUCCESS_PIC",
},
cli.StringFlag{
- Name: "config.failure.pic.url",
- Usage: "config failure picture url",
+ Name: "custom.pic.url.failure",
+ Usage: "custom failure picture url",
EnvVar: "FAILURE_PICTURE_URL,PLUGIN_FAILURE_PIC",
},
cli.StringFlag{
- Name: "config.success.color",
- Usage: "config success color for title in markdown",
+ Name: "custom.color.success",
+ Usage: "custom success color for title in markdown",
EnvVar: "SUCCESS_COLOR,PLUGIN_SUCCESS_COLOR",
},
cli.StringFlag{
- Name: "config.failure.color",
- Usage: "config failure color for title in markdown",
+ Name: "custom.color.failure",
+ Usage: "custom failure color for title in markdown",
EnvVar: "FAILURE_COLOR,PLUGIN_FAILURE_COLOR",
},
- cli.BoolFlag{
- Name: "config.message.color",
- Usage: "configure the message with color or not",
- EnvVar: "PLUGIN_COLOR,PLUGIN_MESSAGE_COLOR",
+ cli.StringFlag{
+ Name: "custom.tpl",
+ Usage: "custom tpl",
+ EnvVar: "PLUGIN_TPL,PLUGIN_CUSTOM_TPL",
},
- cli.BoolFlag{
- Name: "config.message.pic",
- Usage: "configure the message with picture or not",
- EnvVar: "PLUGIN_PIC,PLUGIN_MESSAGE_PIC",
+ cli.StringFlag{
+ Name: "tpl.repo.full.name",
+ Usage: "tpl custom repo full name",
+ EnvVar: "PLUGIN_TPL_REPO_FULL_NAME,TPL_REPO_FULL_NAME",
},
- cli.BoolFlag{
- Name: "config.message.sha.link",
- Usage: "link sha source page or not",
- EnvVar: "PLUGIN_SHA_LINK,PLUGIN_MESSAGE_SHA_LINK",
+ cli.StringFlag{
+ Name: "tpl.repo.short.name",
+ Usage: "tpl custom repo short name",
+ EnvVar: "PLUGIN_TPL_REPO_SHORT_NAME,TPL_REPO_SHORT_NAME",
+ },
+ cli.StringFlag{
+ Name: "tpl.commit.branch.name",
+ Usage: "tpl custom commit branch name",
+ EnvVar: "PLUGIN_TPL_COMMIT_BRANCH_NAME,TPL_COMMIT_BRANCH_NAME",
},
}
@@ -157,50 +210,66 @@ func run(c *cli.Context) {
Drone: Drone{
// repo info
Repo: Repo{
- FullName: c.String("repo.fullname"),
+ ShortName: c.String("repo.name"),
+ GroupName: c.String("repo.group"),
+ OwnerName: c.String("repo.owner"),
+ RemoteURL: c.String("repo.remote.url"),
+ FullName: c.String("repo.full.name"),
},
// build info
Build: Build{
- Status: c.String("build.status"),
- Link: c.String("build.link"),
+ Status: c.String("build.status"),
+ Link: c.String("build.link"),
+ Event: c.String("build.event"),
+ StartAt: c.Int64("build.started"),
+ FinishedAt: c.Int64("build.finished"),
},
Commit: Commit{
Sha: c.String("commit.sha"),
Branch: c.String("commit.branch"),
Message: c.String("commit.message"),
Link: c.String("commit.link"),
- Authors: struct {
- Avatar string
- Email string
- Name string
- }{
- Avatar: c.String("commit.author.avatar"),
- Email: c.String("commit.author.email"),
- Name: c.String("commit.author.name"),
+ Author: CommitAuthor{
+ Avatar: c.String("commit.author.avatar"),
+ Email: c.String("commit.author.email"),
+ Name: c.String("commit.author.name"),
+ Username: c.String("commit.author.username"),
},
},
},
// custom config
Config: Config{
AccessToken: c.String("config.token"),
- //Lang: c.String("config.lang"),
- IsAtALL: c.Bool("config.message.at.all"),
- MsgType: c.String("config.message.type"),
- Mobiles: c.String("config.message.at.mobiles"),
- Debug: c.Bool("config.debug"),
+ IsAtALL: c.Bool("config.message.at.all"),
+ MsgType: c.String("config.message.type"),
+ Mobiles: c.String("config.message.at.mobiles"),
+ Debug: c.Bool("config.debug"),
},
- Extra: Extra{
- Pic: ExtraPic{
- WithPic: c.Bool("config.message.pic"),
- SuccessPicURL: c.String("config.success.pic.url"),
- FailurePicURL: c.String("config.failure.pic.url"),
+ Custom: Custom{
+ Pic: Pic{
+ SuccessPicURL: c.String("custom.pic.url.success"),
+ FailurePicURL: c.String("custom.pic.url.failure"),
},
- Color: ExtraColor{
- SuccessColor: c.String("config.success.color"),
- FailureColor: c.String("config.failure.color"),
- WithColor: c.Bool("config.message.color"),
+ Color: Color{
+ SuccessColor: c.String("custom.color.success"),
+ FailureColor: c.String("custom.color.failure"),
+ },
+ Tpl: c.String("custom.tpl"),
+ },
+ Tpl:Tpl{
+ Repo: TplRepo{
+ FullName: c.String("tpl.repo.full.name"),
+ ShortName: c.String("tpl.repo.short.name"),
+ },
+ Commit: TplCommit{
+ Branch: c.String("tpl.commit.branch.name"),
+ },
+ Build: TplBuild{
+ Status:Status{
+ Success: c.String("tpl.build.status.success"),
+ Failure: c.String("tpl.build.status.failure"),
+ },
},
- LinkSha: c.Bool("config.message.sha.link"),
},
}
diff --git a/plugin.go b/plugin.go
index a888d87..cfa59b9 100644
--- a/plugin.go
+++ b/plugin.go
@@ -3,48 +3,61 @@ package main
import (
"errors"
"fmt"
- "log"
- "strings"
-
webhook "github.com/lddsb/dingtalk-webhook"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "net/url"
+ "os"
+ "regexp"
+ "strings"
)
type (
- // Repo `repo base info`
+ // Repo repo base info
Repo struct {
- FullName string // repository full name
+ ShortName string // short name
+ GroupName string // group name
+ FullName string // repository full name
+ OwnerName string // repo owner
+ RemoteURL string // repo remote url
}
- // Build `build info`
+ // Build build info
Build struct {
- Status string // providers the current build status
- Link string // providers the current build link
+ Status string // providers the current build status
+ Link string // providers the current build link
+ Event string // trigger event
+ StartAt int64 // build start at ( unix timestamp )
+ FinishedAt int64 // build finish at ( unix timestamp )
}
- // Commit `commit info`
+ // Commit commit info
Commit struct {
Branch string // providers the branch for the current commit
Link string // providers the http link to the current commit in the remote source code management system(e.g.GitHub)
Message string // providers the commit message for the current build
Sha string // providers the commit sha for the current build
- Authors CommitAuthors
+ Ref string // commit ref
+ Author CommitAuthor
}
- // CommitAuthors `commit author info`
- CommitAuthors struct {
- Avatar string // providers the author avatar for the current commit
- Email string // providers the author email for the current commit
- Name string // providers the author name for the current commit
+ // CommitAuthor commit author info
+ CommitAuthor struct {
+ Avatar string // providers the author avatar for the current commit
+ Email string // providers the author email for the current commit
+ Name string // providers the author name for the current commit
+ Username string // the author username for the current commit
}
- // Drone `drone info`
+ // Drone drone info
Drone struct {
Repo Repo
Build Build
Commit Commit
}
- // Config `plugin private config`
+ // Config plugin private config
Config struct {
Debug bool
AccessToken string
@@ -54,12 +67,12 @@ type (
MsgType string
}
- // MessageConfig `DingTalk message struct`
+ // MessageConfig DingTalk message struct
MessageConfig struct {
ActionCard ActionCard
}
- // ActionCard `action card message struct`
+ // ActionCard action card message struct
ActionCard struct {
LinkUrls string
LinkTitles string
@@ -67,36 +80,59 @@ type (
BtnOrientation bool
}
- // Extra `extra variables`
- Extra struct {
- Color ExtraColor
- Pic ExtraPic
- LinkSha bool
- }
-
- // ExtraPic `extra config for pic`
- ExtraPic struct {
- WithPic bool
+ // Pic extra config for pic
+ Pic struct {
SuccessPicURL string
FailurePicURL string
}
- // ExtraColor `extra config for color`
- ExtraColor struct {
- WithColor bool
+ // Color extra config for color
+ Color struct {
SuccessColor string
FailureColor string
}
- // Plugin `plugin all config`
+ // Plugin plugin all config
Plugin struct {
- Drone Drone
- Config Config
- Extra Extra
+ Tpl Tpl
+ Drone Drone
+ Config Config
+ Custom Custom
+ Message MessageConfig
+ }
+
+ Custom struct {
+ Tpl string
+ Color Color
+ Pic Pic
+ }
+
+ Tpl struct {
+ Repo TplRepo
+ Commit TplCommit
+ Build TplBuild
+ }
+
+ TplRepo struct {
+ FullName string
+ ShortName string
+ }
+
+ TplCommit struct {
+ Branch string
+ }
+
+ TplBuild struct {
+ Status Status
+ }
+
+ Status struct {
+ Success string
+ Failure string
}
)
-// Exec `execute webhook`
+// Exec execute webhook
func (p *Plugin) Exec() error {
var err error
if 0 == len(p.Config.AccessToken) {
@@ -104,19 +140,20 @@ func (p *Plugin) Exec() error {
return errors.New(msg)
}
- if 6 > len(p.Drone.Commit.Sha) {
- return errors.New("commit sha cannot short than 6")
+ tpl, err := p.getMessage()
+ if err != nil {
+ return err
}
newWebhook := webhook.NewWebHook(p.Config.AccessToken)
mobiles := strings.Split(p.Config.Mobiles, ",")
switch strings.ToLower(p.Config.MsgType) {
case "markdown":
- err = newWebhook.SendMarkdownMsg("You have a new message...", p.baseTpl(), p.Config.IsAtALL, mobiles...)
+ err = newWebhook.SendMarkdownMsg("new message", tpl, p.Config.IsAtALL, mobiles...)
case "text":
- err = newWebhook.SendTextMsg(p.baseTpl(), p.Config.IsAtALL, mobiles...)
+ err = newWebhook.SendTextMsg(tpl, p.Config.IsAtALL, mobiles...)
case "link":
- err = newWebhook.SendLinkMsg(p.Drone.Build.Status, p.baseTpl(), p.Drone.Commit.Authors.Avatar, p.Drone.Build.Link)
+ err = newWebhook.SendLinkMsg(p.Drone.Build.Status, tpl, p.Drone.Commit.Author.Avatar, p.Drone.Build.Link)
default:
msg := "not support message type"
err = errors.New(msg)
@@ -129,90 +166,156 @@ func (p *Plugin) Exec() error {
return err
}
-// markdownTpl `output the tpl of markdown`
-func (p *Plugin) markdownTpl() string {
- var tpl string
-
- // title
- title := fmt.Sprintf(" %s *Branch Build %s*",
- strings.Title(p.Drone.Commit.Branch),
- strings.Title(p.Drone.Build.Status))
- // with color on title
- if p.Extra.Color.WithColor {
- title = fmt.Sprintf("%s", p.getColor(), title)
+// fileExists check file is exists
+func fileExists(filePath string) bool {
+ _, err := os.Stat(filePath)
+ if err != nil {
+ if os.IsExist(err) {
+ return true
+ }
+ return false
}
-
- tpl = fmt.Sprintf("# %s \n", title)
-
- // with pic
- if p.Extra.Pic.WithPic {
- tpl += fmt.Sprintf("\n\n",
- p.Drone.Build.Status,
- p.getPicURL())
- }
-
- // commit message
- commitMsg := fmt.Sprintf("%s", p.Drone.Commit.Message)
- if p.Extra.Color.WithColor {
- commitMsg = fmt.Sprintf("%s", p.getColor(), commitMsg)
- }
- tpl += commitMsg + "\n\n"
-
- // sha info
- commitSha := p.Drone.Commit.Sha
- if p.Extra.LinkSha {
- commitSha = fmt.Sprintf("[Click To %s Commit Detail Page](%s)", commitSha[:6], p.Drone.Commit.Link)
- }
- tpl += commitSha + "\n\n"
-
- // author info
- authorInfo := fmt.Sprintf("`%s(%s)`", p.Drone.Commit.Authors.Name, p.Drone.Commit.Authors.Email)
- tpl += authorInfo + "\n\n"
-
- // build detail link
- buildDetail := fmt.Sprintf("[Click To The Build Detail Page %s](%s)",
- p.getEmoticon(),
- p.Drone.Build.Link)
- tpl += buildDetail
- return tpl
+ return true
}
-func (p *Plugin) baseTpl() string {
- tpl := ""
- switch strings.ToLower(p.Config.MsgType) {
- case "markdown":
- tpl = p.markdownTpl()
- case "text":
- tpl = fmt.Sprintf(`[%s] %s
-%s (%s)
-@%s
-%s (%s)
-`,
- p.Drone.Build.Status,
- strings.TrimSpace(p.Drone.Commit.Message),
- p.Drone.Repo.FullName,
- p.Drone.Commit.Branch,
- p.Drone.Commit.Sha,
- p.Drone.Commit.Authors.Name,
- p.Drone.Commit.Authors.Email)
- case "link":
- tpl = fmt.Sprintf(`%s(%s) @%s %s(%s)`,
- p.Drone.Repo.FullName,
- p.Drone.Commit.Branch,
- p.Drone.Commit.Sha[:6],
- p.Drone.Commit.Authors.Name,
- p.Drone.Commit.Authors.Email)
- case "actionCard":
- // coming soon
+// getTpl get tpl from local file or remote file
+func (p *Plugin) getTpl() (tpl string, err error) {
+ //var tpl string
+ tplDir := "/app/tpls"
+ if "" == p.Custom.Tpl {
+ p.Custom.Tpl = fmt.Sprintf("%s/%s.tpl", tplDir, strings.ToLower(p.Config.MsgType))
+ }
+ u, err := url.Parse(p.Custom.Tpl)
+ if err != nil {
+ return "", err
+ }
+
+ if u.Scheme != "" {
+ resp, err := http.Get(p.Custom.Tpl)
+ if err != nil {
+ return "", err
+ }
+
+ // check response
+ if u.Path != resp.Request.URL.Path {
+ return "", errors.New("cannot get tpl from url")
+ }
+
+ // defer close
+ defer func() {
+ _ = resp.Body.Close()
+ }()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+
+ tpl = string(body)
+ } else {
+ if !fileExists(p.Custom.Tpl) {
+ return "", errors.New("tpl file not exists")
+ }
+
+ tplStr, err := ioutil.ReadFile(p.Custom.Tpl)
+ if err != nil {
+ return "", err
+ }
+
+ tpl = string(tplStr)
+ }
+
+
+ return tpl, nil
+}
+
+// fillTpl fill the tpl by valid keyword
+func (p *Plugin) fillTpl(tpl string) string {
+ envs := p.getEnvs()
+ // replace regex
+ reg := regexp.MustCompile(`\[([^\[\]]*)]`)
+ match := reg.FindAllStringSubmatch(tpl, -1)
+ for _, m := range match {
+ // check if the keyword is legal
+ if _, ok := envs[m[1]]; ok {
+ // replace keyword
+ tpl = strings.ReplaceAll(tpl, m[0], envs[m[1]].(string))
+ }
}
return tpl
}
-/**
-get emoticon
-*/
+// getEnvs get available envs
+func (p *Plugin) getEnvs() map[string]interface{} {
+ var envs map[string]interface{}
+ envs = make(map[string]interface{})
+ envs["TPL_REPO_FULL_NAME"] = p.Drone.Repo.FullName
+ if p.Tpl.Repo.FullName != "" {
+ envs["TPL_REPO_FULL_NAME"] = p.Tpl.Repo.FullName
+ }
+ envs["TPL_REPO_SHORT_NAME"] = p.Drone.Repo.ShortName
+ if p.Tpl.Repo.ShortName != "" {
+ envs["TPL_REPO_SHORT_NAME"] = p.Tpl.Repo.ShortName
+ }
+ envs["TPL_REPO_GROUP_NAME"] = p.Drone.Repo.GroupName
+ envs["TPL_REPO_OWNER_NAME"] = p.Drone.Repo.OwnerName
+ envs["TPL_REPO_REMOTE_URL"] = p.Drone.Repo.RemoteURL
+
+ envs["TPL_BUILD_STATUS"] = p.getStatus()
+ envs["TPL_BUILD_LINK"] = p.Drone.Build.Link
+ envs["TPL_BUILD_EVENT"] = p.Drone.Build.Event
+ envs["TPL_BUILD_CONSUMING"] = fmt.Sprintf("%v", p.Drone.Build.FinishedAt-p.Drone.Build.StartAt)
+
+ envs["TPL_COMMIT_SHA"] = p.Drone.Commit.Sha
+ envs["TPL_COMMIT_REF"] = p.Drone.Commit.Ref
+ envs["TPL_COMMIT_LINK"] = p.Drone.Commit.Link
+ envs["TPL_COMMIT_MSG"] = p.Drone.Commit.Message
+ envs["TPL_COMMIT_BRANCH"] = p.Drone.Commit.Branch
+ if p.Tpl.Commit.Branch != "" {
+ envs["TPL_COMMIT_BRANCH"] = p.Tpl.Commit.Branch
+ }
+
+ envs["TPL_AUTHOR_NAME"] = p.Drone.Commit.Author.Name
+ envs["TPL_AUTHOR_USERNAME"] = p.Drone.Commit.Author.Username
+ envs["TPL_AUTHOR_EMAIL"] = p.Drone.Commit.Author.Email
+ envs["TPL_AUTHOR_AVATAR"] = p.Drone.Commit.Author.Avatar
+
+ envs["TPL_STATUS_PIC"] = p.getPicURL()
+ envs["TPL_STATUS_COLOR"] = p.getColor()
+ envs["TPL_STATUS_EMOTICON"] = p.getEmoticon()
+
+ return envs
+}
+
+// getMessage get message tpl
+func (p *Plugin) getMessage() (tpl string, err error) {
+ tpl, err = p.getTpl()
+ if err != nil {
+ return "", err
+ }
+ return p.fillTpl(tpl), nil
+}
+
+// getStatus
+func (p *Plugin) getStatus() string {
+ if p.Drone.Build.Status == "success" {
+ if p.Tpl.Build.Status.Success != "" {
+ return p.Tpl.Build.Status.Success
+ }
+
+ return p.Drone.Build.Status
+ }
+
+ if p.Tpl.Build.Status.Failure != "" {
+ return p.Tpl.Build.Status.Failure
+ }
+
+ return p.Drone.Build.Status
+}
+
+// get emoticon
func (p *Plugin) getEmoticon() string {
emoticons := make(map[string]string)
emoticons["success"] = ":)"
@@ -226,44 +329,41 @@ func (p *Plugin) getEmoticon() string {
return ":("
}
-/**
-get picture url
-*/
+// get picture url
func (p *Plugin) getPicURL() string {
pics := make(map[string]string)
// success picture url
pics["success"] = "https://ws4.sinaimg.cn/large/006tNc79gy1fz05g5a7utj30he0bfjry.jpg"
- if p.Extra.Pic.SuccessPicURL != "" {
- pics["success"] = p.Extra.Pic.SuccessPicURL
+ if p.Custom.Pic.SuccessPicURL != "" {
+ pics["success"] = p.Custom.Pic.SuccessPicURL
}
// failure picture url
pics["failure"] = "https://ws1.sinaimg.cn/large/006tNc79gy1fz0b4fghpnj30hd0bdmxn.jpg"
- if p.Extra.Pic.FailurePicURL != "" {
- pics["failure"] = p.Extra.Pic.FailurePicURL
+ if p.Custom.Pic.FailurePicURL != "" {
+ pics["failure"] = p.Custom.Pic.FailurePicURL
}
- url, ok := pics[p.Drone.Build.Status]
+ picURL, ok := pics[p.Drone.Build.Status]
if ok {
- return url
+ return picURL
}
return ""
}
-/**
-get color for message title
-*/
+// get color for message title
func (p *Plugin) getColor() string {
colors := make(map[string]string)
// success color
colors["success"] = "#008000"
- if p.Extra.Color.SuccessColor != "" {
- colors["success"] = "#" + p.Extra.Color.SuccessColor
+ if p.Custom.Color.SuccessColor != "" {
+ colors["success"] = "#" + p.Custom.Color.SuccessColor
}
+
// failure color
colors["failure"] = "#FF0000"
- if p.Extra.Color.FailureColor != "" {
- colors["failure"] = "#" + p.Extra.Color.FailureColor
+ if p.Custom.Color.FailureColor != "" {
+ colors["failure"] = "#" + p.Custom.Color.FailureColor
}
color, ok := colors[p.Drone.Build.Status]
diff --git a/plugin_test.go b/plugin_test.go
index 5ea7675..e4440e2 100644
--- a/plugin_test.go
+++ b/plugin_test.go
@@ -12,43 +12,45 @@ func TestPlugin(t *testing.T) {
}
p.Config.AccessToken = "example-access-token"
- err = p.Exec()
- if nil == err {
- t.Error("commit sha length error should be catch!")
- }
-
- p.Drone.Commit.Sha = "53729847dfksj"
+ p.Custom.Tpl = "tpls/markdown.tpl"
err = p.Exec()
if nil == err {
t.Error("not support message type error should be catch!")
}
- p.Config.MsgType = "text"
- err = p.Exec()
- if nil == err {
- t.Error("access token invalid error should be catch!")
- }
-
p.Config.MsgType = "link"
err = p.Exec()
if nil == err {
t.Error("access token invalid error should be catch!")
}
- p.Extra.Color.WithColor = true
- p.Extra.Color.FailureColor = "#555555"
- p.Extra.Color.SuccessColor = "#222222"
- p.Extra.Pic.WithPic = true
- p.Extra.Pic.FailurePicURL = "https://www.baidu.com"
- p.Extra.Pic.SuccessPicURL = "https://www.baidu.com"
- p.Extra.LinkSha = true
- // p.Drone.Build.Status = "failure"
- p.Config.MsgType = "markdown"
+ p.Custom.Tpl = "https://aaa.com"
+ p.Config.MsgType = "text"
err = p.Exec()
if nil == err {
t.Error("access token invalid error should be catch!")
}
+
+ p.Custom.Tpl = ""
+ p.Config.MsgType = "link"
+ err = p.Exec()
+ if nil == err {
+ t.Error("access token invalid error should be catch!")
+ }
+
+ p.Custom.Color.FailureColor = "#555555"
+ p.Custom.Color.SuccessColor = "#222222"
+ p.Custom.Pic.FailurePicURL = "https://www.baidu.com"
+ p.Custom.Pic.SuccessPicURL = "https://www.baidu.com"
+ p.Config.MsgType = "markdown"
+ p.Custom.Tpl = "tpls/markdown.tpl"
+ err = p.Exec()
+ if nil == err {
+ t.Error("access token invalid error should be catch!")
+ }
+
+ p.Custom.Tpl = "https://gist.githubusercontent.com/lddsb/87065e73678dcf56cd222a3c2f1f32b0/raw/fce9fb28b2c8c768eb93df5598beee8c98cba610/md.tpl"
p.Drone.Build.Status = "failure"
err = p.Exec()
if nil == err {
diff --git a/tpls/markdown.tpl b/tpls/markdown.tpl
new file mode 100644
index 0000000..c7f72a4
--- /dev/null
+++ b/tpls/markdown.tpl
@@ -0,0 +1,9 @@
+### [TPL_REPO_SHORT_NAME] build [TPL_BUILD_STATUS] (`takes [TPL_BUILD_CONSUMING]s`)
+
+[TPL_COMMIT_MSG]
+
+[[TPL_COMMIT_SHA]]([TPL_COMMIT_LINK])
+
+[[TPL_AUTHOR_NAME]([TPL_AUTHOR_EMAIL])](mailto:[TPL_AUTHOR_EMAIL])
+
+[Click To The Build Detail Page [TPL_STATUS_EMOTICON]]([TPL_BUILD_LINK])
\ No newline at end of file
diff --git a/tpls/text.tpl b/tpls/text.tpl
new file mode 100644
index 0000000..063ece9
--- /dev/null
+++ b/tpls/text.tpl
@@ -0,0 +1,5 @@
+[TPL_REPO_NAME] build [TPL_BUILD_STATUS] (takes [TPL_BUILD_CONSUMING]s)
+[TPL_COMMIT_MSG]
+[TPL_COMMIT_SHA] ([TPL_COMMIT_LINK])
+[TPL_AUTHOR_NAME] ([TPL_AUTHOR_EMAIL])
+Click To The Build Detail Page [TPL_STATUS_EMOTICON] ([TPL_BUILD_LINK])
\ No newline at end of file