mirror of
https://github.com/lddsb/drone-dingtalk-message.git
synced 2026-06-04 10:23:48 +08:00
complete tpl feature
This commit is contained in:
+6
-4
@@ -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"]
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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"),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -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("<font color=%s>%s</font>", 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("<font color=%s>%s</font>", 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]
|
||||
|
||||
+23
-21
@@ -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 {
|
||||
|
||||
@@ -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])
|
||||
@@ -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])
|
||||
Reference in New Issue
Block a user