diff --git a/main.go b/main.go index 621d4a8..6f580e8 100644 --- a/main.go +++ b/main.go @@ -14,45 +14,45 @@ import ( "github.com/drone/drone-go/template" ) +var ( + build string + buildDate string +) + func main() { + fmt.Printf("Drone Webhook Plugin built at %s\n", buildDate) - // plugin settings - var sys = drone.System{} - var repo = drone.Repo{} - var build = drone.Build{} - var vargs = Webhook{} + system := drone.System{} + repo := drone.Repo{} + build := drone.Build{} + vargs := Params{} - // set plugin parameters - plugin.Param("system", &sys) + plugin.Param("system", &system) plugin.Param("repo", &repo) plugin.Param("build", &build) plugin.Param("vargs", &vargs) + plugin.MustParse() - // parse the parameters - if err := plugin.Parse(); err != nil { - fmt.Println(err) - os.Exit(1) - } - - // set default values if len(vargs.Method) == 0 { vargs.Method = "POST" } + if len(vargs.ContentType) == 0 { vargs.ContentType = "application/json" } - // data structure data := struct { System drone.System `json:"system"` Repo drone.Repo `json:"repo"` Build drone.Build `json:"build"` - }{sys, repo, build} + }{system, repo, build} // creates the payload. by default the payload // is the build details in json format, but a custom // template may also be used. + var buf bytes.Buffer + if len(vargs.Template) == 0 { if err := json.NewEncoder(&buf).Encode(&data); err != nil { fmt.Printf("Error encoding json payload. %s\n", err) @@ -62,8 +62,9 @@ func main() { err := template.Write(&buf, vargs.Template, &drone.Payload{ Build: &build, Repo: &repo, - System: &sys, + System: &system, }) + if err != nil { fmt.Printf("Error executing content template. %s\n", err) os.Exit(1) @@ -74,30 +75,31 @@ func main() { // all auth, headers, method, template (payload), // and content_type values will be applied to // every webhook request. - for i, rawurl := range vargs.Urls { + for i, rawurl := range vargs.Urls { uri, err := url.Parse(rawurl) + if err != nil { fmt.Printf("Error parsing hook url. %s\n", err) os.Exit(1) } - // vargs.Method defaults to POST, no need to check b := buf.Bytes() r := bytes.NewReader(b) + req, err := http.NewRequest(vargs.Method, uri.String(), r) + if err != nil { fmt.Printf("Error creating http request. %s\n", err) os.Exit(1) } - // vargs.ContentType defaults to application/json, no need to check req.Header.Set("Content-Type", vargs.ContentType) + for key, value := range vargs.Headers { req.Header.Set(key, value) } - // set basic auth if a user or user and pass is provided if len(vargs.Auth.Username) > 0 { if len(vargs.Auth.Password) > 0 { req.SetBasicAuth(vargs.Auth.Username, vargs.Auth.Password) @@ -107,24 +109,23 @@ func main() { } resp, err := http.DefaultClient.Do(req) + if err != nil { fmt.Printf("Error executing http request. %s\n", err) os.Exit(1) } + defer resp.Body.Close() - // if debug is on or response status code is bad if vargs.Debug || resp.StatusCode >= http.StatusBadRequest { - - // read the response body body, err := ioutil.ReadAll(resp.Body) + if err != nil { // I do not think we need to os.Exit(1) if we are // unable to read a http response body. fmt.Printf("Error reading http response body. %s\n", err) } - // debug/info print if vargs.Debug { fmt.Printf("[debug] Webhook %d\n URL: %s\n METHOD: %s\n HEADERS: %s\n REQUEST BODY: %s\n RESPONSE STATUS: %s\n RESPONSE BODY: %s\n", i+1, req.URL, req.Method, req.Header, string(b), resp.Status, string(body)) } else { diff --git a/webhook.go b/types.go similarity index 65% rename from webhook.go rename to types.go index 5d3d94c..0dc03b2 100644 --- a/webhook.go +++ b/types.go @@ -1,18 +1,16 @@ package main -// Webhook represents a webhook. -type Webhook struct { +type Params struct { Urls []string `json:"urls"` Debug bool `json:"debug"` - Auth BasicAuth `json:"auth"` + Auth Auth `json:"auth"` Headers map[string]string `json:"header"` Method string `json:"method"` Template string `json:"template"` ContentType string `json:"content_type"` } -// BasicAuth represents a HTTP basic authentication username and password. -type BasicAuth struct { +type Auth struct { Username string `json:"username"` Password string `json:"password"` }