first big commit

This commit is contained in:
Clement Venard
2017-11-27 16:15:14 +08:00
parent 2e8ea83bbe
commit fa95cdc5fc
6 changed files with 165 additions and 143 deletions
+11 -8
View File
@@ -1,4 +1,4 @@
# drone-wechat # drone-wechat (WORK IN PROGRESS)
Drone plugin to send build status notifications via WeChat for Work. For usage Drone plugin to send build status notifications via WeChat for Work. For usage
information please look at [the docs](DOCS.md). information please look at [the docs](DOCS.md).
@@ -18,18 +18,21 @@ go build
Build the Docker image with the following commands: Build the Docker image with the following commands:
``` ```
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -tags netgo -o release/linux/amd64/drone-webhook GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -tags netgo -o release/linux/amd64/drone-wechat
docker build --rm -t plugins/webhook . docker build --rm -t plugins/drone-wechat .
``` ```
### Usage ### Usage
``` ```
docker run --rm \ docker run --rm \
-e PLUGIN_URLS=https://bbc.com/... \ -e PLUGIN_ACCESS_TOKEN=accesstoken \
-e PLUGIN_HEADERS="HEADER1=value1" \ -e PLUGIN_AGENT_ID=agentid \
-e PLUGIN_USERNAME=drone \ -e PLUGIN_DEBUG=true \
-e PLUGIN_PASSWORD=password \ -e PLUGIN_MSG_URL=url \
-e PLUGIN_BTN_TXT=true \
-e PLUGIN_TITLE=title \
-e PLUGIN_DESCRIPTION=description \
-e DRONE_REPO_OWNER=octocat \ -e DRONE_REPO_OWNER=octocat \
-e DRONE_REPO_NAME=hello-world \ -e DRONE_REPO_NAME=hello-world \
-e DRONE_COMMIT_SHA=7fd1a60b01f91b314f59955a4e4d4e80d8edf11d \ -e DRONE_COMMIT_SHA=7fd1a60b01f91b314f59955a4e4d4e80d8edf11d \
@@ -39,5 +42,5 @@ docker run --rm \
-e DRONE_BUILD_STATUS=success \ -e DRONE_BUILD_STATUS=success \
-e DRONE_BUILD_LINK=http://github.com/octocat/hello-world \ -e DRONE_BUILD_LINK=http://github.com/octocat/hello-world \
-e DRONE_TAG=1.0.0 \ -e DRONE_TAG=1.0.0 \
plugins/webhook plugins/drone-wechat
``` ```
BIN
View File
Binary file not shown.
+40 -15
View File
@@ -23,15 +23,27 @@ func main() {
EnvVar: "PLUGIN_METHOD", EnvVar: "PLUGIN_METHOD",
Value: "POST", Value: "POST",
}, },
cli.StringFlag{
Name: "url",
Usage: "wechat work url",
EnvVar: "PLUGIN_URL",
Value: "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=",
},
cli.StringFlag{ cli.StringFlag{
Name: "access-token", Name: "access-token",
Usage: "The access token for authorization", Usage: "The access token for authorization",
EnvVar: "PLUGIN_ACCESS_TOKEN,WEBHOOK_ACCESS_TOKEN", EnvVar: "PLUGIN_ACCESS_TOKEN,WEBHOOK_ACCESS_TOKEN",
}, },
cli.StringFlag{
Name: "agentid",
Usage: "Agent ID",
EnvVar: "PLUGIN_AGENT_ID,WEBHOOK_AGENT_ID",
},
cli.StringFlag{ cli.StringFlag{
Name: "msgtype", Name: "msgtype",
Usage: "The type of message, either text, textcard", Usage: "The type of message, either text, textcard",
EnvVar: "PLUGIN_MSGTYPE,WEBHOOK_MSGTYPE", EnvVar: "PLUGIN_MSGTYPE,WEBHOOK_MSGTYPE",
Value: "textcard",
}, },
cli.StringFlag{ cli.StringFlag{
Name: "content-type", Name: "content-type",
@@ -50,22 +62,32 @@ func main() {
Usage: "Party ID to send messages to", Usage: "Party ID to send messages to",
EnvVar: "PLUGIN_TO_PARTY", EnvVar: "PLUGIN_TO_PARTY",
}, },
cli.StringFlag{
Name: "title",
Usage: "Message title",
EnvVar: "PLUGIN_TITLE",
},
cli.StringFlag{
Name: "description",
Usage: "Description ",
EnvVar: "PLUGIN_DESCRIPTION",
},
cli.StringFlag{
Name: "msgurl",
Usage: "message url ",
EnvVar: "PLUGIN_MSG_URL",
},
cli.StringFlag{
Name: "btntxt",
Usage: "Button text ",
EnvVar: "PLUGIN_BTN_TXT",
},
cli.StringFlag{ cli.StringFlag{
Name: "safe", Name: "safe",
Usage: "Whether to make this message confidential or not, 0 is false, 1 is true. Defaults to false", Usage: "Whether to make this message confidential or not, 0 is false, 1 is true. Defaults to false",
EnvVar: "PLUGIN_SAFE", EnvVar: "PLUGIN_SAFE",
Value: "0", Value: "0",
}, },
cli.StringFlag{
Name: "content",
Usage: "custom template for webhook",
EnvVar: "PLUGIN_CONTENT",
},
cli.StringSliceFlag{
Name: "headers",
Usage: "custom headers key map",
EnvVar: "PLUGIN_HEADERS",
},
cli.BoolFlag{ cli.BoolFlag{
Name: "debug", Name: "debug",
Usage: "enable debug information", Usage: "enable debug information",
@@ -191,14 +213,17 @@ func run(c *cli.Context) error {
Config: Config{ Config: Config{
Method: c.String("method"), Method: c.String("method"),
AccessToken: c.String("access-token"), AccessToken: c.String("access-token"),
Agentid: c.Int("agentid"),
MsgType: c.String("msgtype"), MsgType: c.String("msgtype"),
ToUser: c.StringSlice("touser"), URL: c.String("url"),
ToParty: c.StringSlice("toparty"), MsgURL: c.String("msgurl"),
BtnTxt: c.String("btntxt"),
ToUser: c.String("touser"),
ToParty: c.String("toparty"),
Title: c.String("title"),
Description: c.String("description"),
Safe: c.Bool("safe"), Safe: c.Bool("safe"),
Content: c.String("content"),
ContentType: c.String("content-type"), ContentType: c.String("content-type"),
Template: c.String("template"),
Headers: c.StringSlice("headers"),
Debug: c.Bool("debug"), Debug: c.Bool("debug"),
SkipVerify: c.Bool("skip-verify"), SkipVerify: c.Bool("skip-verify"),
}, },
+40 -46
View File
@@ -7,9 +7,6 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url"
"os"
"strings"
) )
const ( const (
@@ -41,16 +38,19 @@ type (
Config struct { Config struct {
Method string Method string
AccessToken string AccessToken string
MsgType string Agentid int `json:"agentid"`
ToUser []string MsgType string `json:"msgtype"`
ToParty []string URL string
MsgURL string
BtnTxt string
ToUser string `json:"touser"`
ToParty string `json:"toparty"`
Safe bool Safe bool
Content string
ContentType string ContentType string
Template string
Headers []string
Debug bool Debug bool
SkipVerify bool SkipVerify bool
Title string `json:"title"`
Description string `json:"description"`
} }
Job struct { Job struct {
@@ -69,7 +69,7 @@ func (p Plugin) Exec() error {
var buf bytes.Buffer var buf bytes.Buffer
var b []byte var b []byte
if p.Config.Content == "" { if p.Config.Title == "" {
data := struct { data := struct {
Repo Repo `json:"repo"` Repo Repo `json:"repo"`
Build Build `json:"build"` Build Build `json:"build"`
@@ -81,12 +81,25 @@ func (p Plugin) Exec() error {
} }
b = buf.Bytes() b = buf.Bytes()
} else { } else {
txt, err := RenderTrim(p.Config.Template, p) textCard := struct {
if err != nil { Title string `json:"title"`
return err Description string `json:"description"`
} MsgURL string `json:"url"`
text := txt BtnTxt string `json:"btntext"`
b = []byte(text) }{p.Config.Title, p.Config.Description, p.Config.MsgURL, p.Config.BtnTxt}
data := struct {
ToUser string `json:"touser"`
MsgType string `json:"msgtype"`
Agentid int `json:"agentid"`
TextCard struct {
Title string `json:"title"`
Description string `json:"description"`
MsgURL string `json:"url"`
BtnTxt string `json:"btntext"`
} `json:"textcard"`
}{p.Config.ToUser, p.Config.MsgType, p.Config.Agentid, textCard}
b, _ = json.Marshal(data) // []byte(data)
} }
@@ -95,35 +108,13 @@ func (p Plugin) Exec() error {
// and content_type values will be applied to // and content_type values will be applied to
// every webhook request. // every webhook request.
// TODO: Construct URL for WeChat work url := p.Config.URL + p.Config.AccessToken
fmt.Println("URL:>", url)
for i, rawurl := range p.Config.URLs { req, err := http.NewRequest("POST", url, bytes.NewBuffer(b))
uri, err := url.Parse(rawurl) req.Header.Set("Content-Type", "application/json")
if err != nil { // client := &http.Client{}
fmt.Printf("Error: Failed to parse the hook URL. %s\n", err)
os.Exit(1)
}
r := bytes.NewReader(b)
req, err := http.NewRequest(p.Config.Method, uri.String(), r)
if err != nil {
fmt.Printf("Error: Failed to create the HTTP request. %s\n", err)
return err
}
req.Header.Set("Content-Type", p.Config.ContentType)
for _, value := range p.Config.Headers {
header := strings.Split(value, "=")
req.Header.Set(header[0], header[1])
}
if p.Config.Username != "" && p.Config.Password != "" {
req.SetBasicAuth(p.Config.Username, p.Config.Password)
}
client := http.DefaultClient client := http.DefaultClient
if p.Config.SkipVerify { if p.Config.SkipVerify {
@@ -133,6 +124,7 @@ func (p Plugin) Exec() error {
}, },
} }
} }
resp, err := client.Do(req) resp, err := client.Do(req)
if err != nil { if err != nil {
@@ -142,6 +134,11 @@ func (p Plugin) Exec() error {
defer resp.Body.Close() defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
fmt.Println("response Headers:", resp.Header)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("response Body:", string(body))
if p.Config.Debug || resp.StatusCode >= http.StatusBadRequest { if p.Config.Debug || resp.StatusCode >= http.StatusBadRequest {
body, err := ioutil.ReadAll(resp.Body) body, err := ioutil.ReadAll(resp.Body)
@@ -152,7 +149,6 @@ func (p Plugin) Exec() error {
if p.Config.Debug { if p.Config.Debug {
fmt.Printf( fmt.Printf(
debugRespFormat, debugRespFormat,
i+1,
req.URL, req.URL,
req.Method, req.Method,
req.Header, req.Header,
@@ -163,13 +159,11 @@ func (p Plugin) Exec() error {
} else { } else {
fmt.Printf( fmt.Printf(
respFormat, respFormat,
i+1,
req.URL, req.URL,
resp.Status, resp.Status,
string(body), string(body),
) )
} }
} }
}
return nil return nil
} }
+1 -1
View File
@@ -33,5 +33,5 @@
"revisionTime": "2017-07-06T19:46:25Z" "revisionTime": "2017-07-06T19:46:25Z"
} }
], ],
"rootPath": "github.com/drone-plugins/drone-webhook" "rootPath": "github.com/clem109/drone-wechat"
} }