From 8530255ae6b27b24f751b7ac5441cc7976512c90 Mon Sep 17 00:00:00 2001 From: Denis Denisov Date: Wed, 7 Sep 2016 21:29:06 +0300 Subject: [PATCH 1/6] Makefile build cross-binary --- Makefile | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..e9f04d63 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +OS = darwin freebsd linux openbsd windows +ARCHS = 386 arm amd64 arm64 + +all: build release + +build: deps + go build + +release: clean deps + @for arch in $(ARCHS);\ + do \ + for os in $(OS);\ + do \ + echo "Building $$os-$$arch"; \ + mkdir -p build/webhook-$$os-$$arch/; \ + GOOS=$$os GOARCH=$$arch go build -o build/webhook-$$os-$$arch/webhook; \ + tar cz -C build -f build/webhook-$$os-$$arch.tar.gz webhook-$$os-$$arch; \ + done \ + done + +test: deps + go test ./... + +deps: + go get -d -v -t ./... + +clean: + rm -rf build + rm -f webhook From 3b59539a3364d2c677ea8032b12f72f4f0985a8a Mon Sep 17 00:00:00 2001 From: Adnan Hajdarevic Date: Thu, 29 Sep 2016 19:15:51 +0200 Subject: [PATCH 2/6] do not prefix specified environment variable name with HOOK_ (fixes #98) --- hook/hook.go | 2 +- hook/hook_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hook/hook.go b/hook/hook.go index 9699f394..4b59ce98 100644 --- a/hook/hook.go +++ b/hook/hook.go @@ -367,7 +367,7 @@ func (h *Hook) ExtractCommandArgumentsForEnv(headers, query, payload *map[string if arg, ok := h.PassEnvironmentToCommand[i].Get(headers, query, payload); ok { if h.PassEnvironmentToCommand[i].EnvName != "" { // first try to use the EnvName if specified - args = append(args, EnvNamespace+h.PassEnvironmentToCommand[i].EnvName+"="+arg) + args = append(args, h.PassEnvironmentToCommand[i].EnvName+"="+arg) } else { // then fallback on the name args = append(args, EnvNamespace+h.PassEnvironmentToCommand[i].Name+"="+arg) diff --git a/hook/hook_test.go b/hook/hook_test.go index f9ae1f71..1fc9a886 100644 --- a/hook/hook_test.go +++ b/hook/hook_test.go @@ -179,7 +179,7 @@ var hookExtractCommandArgumentsForEnvTests = []struct { "test", []Argument{Argument{"header", "a", "MYKEY"}}, &map[string]interface{}{"a": "z"}, nil, nil, - []string{"HOOK_MYKEY=z"}, + []string{"MYKEY=z"}, true, }, // failures From 1943c5311f939080f8dcb9b66d6cf832a9904867 Mon Sep 17 00:00:00 2001 From: Adnan Hajdarevic Date: Thu, 29 Sep 2016 19:16:47 +0200 Subject: [PATCH 3/6] bump version to 2.5.0 --- webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhook.go b/webhook.go index e7620269..3827db8d 100644 --- a/webhook.go +++ b/webhook.go @@ -21,7 +21,7 @@ import ( ) const ( - version = "2.4.0" + version = "2.5.0" ) var ( From cc0d9b2cba63d7dab0aac5c6330beaedd20eb7c6 Mon Sep 17 00:00:00 2001 From: Adnan Hajdarevic Date: Thu, 29 Sep 2016 19:57:06 +0200 Subject: [PATCH 4/6] fix tests, return raw output, return 500 if the command did not execute properly - fixes #87 return raw stdout instead of json wrapped message - fixes #88 --- hook/hook.go | 7 ------- test/hooks.json.tmpl | 3 +-- webhook.go | 27 +++++++++++---------------- webhook_test.go | 16 +++++++++++----- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/hook/hook.go b/hook/hook.go index 4b59ce98..5555fd4d 100644 --- a/hook/hook.go +++ b/hook/hook.go @@ -521,10 +521,3 @@ func (r MatchRule) Evaluate(headers, query, payload *map[string]interface{}, bod } return false, nil } - -// CommandStatusResponse type encapsulates the executed command exit code, message, stdout and stderr -type CommandStatusResponse struct { - ResponseMessage string `json:"message,omitempty"` - Output string `json:"output,omitempty"` - Error string `json:"error,omitempty"` -} diff --git a/test/hooks.json.tmpl b/test/hooks.json.tmpl index 1839a18b..4d944495 100644 --- a/test/hooks.json.tmpl +++ b/test/hooks.json.tmpl @@ -57,7 +57,7 @@ "id": "bitbucket", "execute-command": "{{ .Hookecho }}", "command-working-directory": "/", - "include-command-output-in-response": true, + "include-command-output-in-response": false, "response-message": "success", "parse-parameters-as-json": [ { @@ -136,4 +136,3 @@ } } ] - diff --git a/webhook.go b/webhook.go index 3827db8d..1ff5a6ef 100644 --- a/webhook.go +++ b/webhook.go @@ -222,8 +222,14 @@ func hookHandler(w http.ResponseWriter, r *http.Request) { } if matchedHook.CaptureCommandOutput { - response := handleHook(matchedHook, &headers, &query, &payload, &body) - fmt.Fprintf(w, response) + response, err := handleHook(matchedHook, &headers, &query, &payload, &body) + + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error occurred while executing the hook's command. Please check your logs for more details.\n") + } else { + fmt.Fprintf(w, response) + } } else { go handleHook(matchedHook, &headers, &query, &payload, &body) fmt.Fprintf(w, matchedHook.ResponseMessage) @@ -241,7 +247,7 @@ func hookHandler(w http.ResponseWriter, r *http.Request) { } } -func handleHook(h *hook.Hook, headers, query, payload *map[string]interface{}, body *[]byte) string { +func handleHook(h *hook.Hook, headers, query, payload *map[string]interface{}, body *[]byte) (string, error) { var err error cmd := exec.Command(h.ExecuteCommand) @@ -261,28 +267,17 @@ func handleHook(h *hook.Hook, headers, query, payload *map[string]interface{}, b log.Printf("executing %s (%s) with arguments %q and environment %s using %s as cwd\n", h.ExecuteCommand, cmd.Path, cmd.Args, envs, cmd.Dir) - out, err := cmd.CombinedOutput() + out, err := cmd.Output() log.Printf("command output: %s\n", out) - var errorResponse string - if err != nil { log.Printf("error occurred: %+v\n", err) - errorResponse = fmt.Sprintf("%+v", err) } log.Printf("finished handling %s\n", h.ID) - var response []byte - response, err = json.Marshal(&hook.CommandStatusResponse{ResponseMessage: h.ResponseMessage, Output: string(out), Error: errorResponse}) - - if err != nil { - log.Printf("error marshalling response: %+v", err) - return h.ResponseMessage - } - - return string(response) + return string(out), err } func reloadHooks() { diff --git a/webhook_test.go b/webhook_test.go index 80cf0c3c..0b25de9b 100644 --- a/webhook_test.go +++ b/webhook_test.go @@ -372,7 +372,9 @@ var hookHandlerTests = []struct { }`, false, http.StatusOK, - `{"output":"arg: 1481a2de7b2a7d02428ad93446ab166be7793fbb lolwut@noway.biz\nenv: HOOK_head_commit.timestamp=2013-03-12T08:14:29-07:00\n"}`, + `arg: 1481a2de7b2a7d02428ad93446ab166be7793fbb lolwut@noway.biz +env: HOOK_head_commit.timestamp=2013-03-12T08:14:29-07:00 +`, }, { "bitbucket", // bitbucket sends their payload using uriencoded params. @@ -381,7 +383,7 @@ var hookHandlerTests = []struct { `payload={"canon_url": "https://bitbucket.org","commits": [{"author": "marcus","branch": "master","files": [{"file": "somefile.py","type": "modified"}],"message": "Added some more things to somefile.py\n","node": "620ade18607a","parents": ["702c70160afc"],"raw_author": "Marcus Bertrand ","raw_node": "620ade18607ac42d872b568bb92acaa9a28620e9","revision": null,"size": -1,"timestamp": "2012-05-30 05:58:56","utctimestamp": "2014-11-07 15:19:02+00:00"}],"repository": {"absolute_url": "/webhook/testing/","fork": false,"is_private": true,"name": "Project X","owner": "marcus","scm": "git","slug": "project-x","website": "https://atlassian.com/"},"user": "marcus"}`, true, http.StatusOK, - `{"message":"success"}`, + `success`, }, { "gitlab", @@ -431,7 +433,8 @@ var hookHandlerTests = []struct { }`, false, http.StatusOK, - `{"message":"success","output":"arg: b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327 John Smith john@example.com\n"}`, + `arg: b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327 John Smith john@example.com +`, }, { @@ -469,7 +472,9 @@ var hookHandlerTests = []struct { }`, false, http.StatusOK, - `{"output":"arg: 1481a2de7b2a7d02428ad93446ab166be7793fbb lolwut@noway.biz\nenv: HOOK_head_commit.timestamp=2013-03-12T08:14:29-07:00\n"}`, + `arg: 1481a2de7b2a7d02428ad93446ab166be7793fbb lolwut@noway.biz +env: HOOK_head_commit.timestamp=2013-03-12T08:14:29-07:00 +`, }, { @@ -506,7 +511,8 @@ var hookHandlerTests = []struct { }`, false, http.StatusOK, - `{"output":"arg: 1481a2de7b2a7d02428ad93446ab166be7793fbb lolwut@noway.biz\n"}`, + `arg: 1481a2de7b2a7d02428ad93446ab166be7793fbb lolwut@noway.biz +`, }, {"empty payload", "github", nil, `{}`, false, http.StatusOK, `Hook rules were not satisfied.`}, From c53596df5990fe8003d786856add38b25a8574c3 Mon Sep 17 00:00:00 2001 From: Adnan Hajdarevic Date: Thu, 29 Sep 2016 20:08:47 +0200 Subject: [PATCH 5/6] override content type header when returning error message --- webhook.go | 1 + 1 file changed, 1 insertion(+) diff --git a/webhook.go b/webhook.go index 1ff5a6ef..36a303b8 100644 --- a/webhook.go +++ b/webhook.go @@ -225,6 +225,7 @@ func hookHandler(w http.ResponseWriter, r *http.Request) { response, err := handleHook(matchedHook, &headers, &query, &payload, &body) if err != nil { + w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusInternalServerError) fmt.Fprintf(w, "Error occurred while executing the hook's command. Please check your logs for more details.\n") } else { From 75cf8952be6712144c0912dfe74b0a7146409a0a Mon Sep 17 00:00:00 2001 From: Adnan Hajdarevic Date: Thu, 29 Sep 2016 20:11:20 +0200 Subject: [PATCH 6/6] remove \n --- webhook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webhook.go b/webhook.go index 36a303b8..20ac190f 100644 --- a/webhook.go +++ b/webhook.go @@ -227,7 +227,7 @@ func hookHandler(w http.ResponseWriter, r *http.Request) { if err != nil { w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.WriteHeader(http.StatusInternalServerError) - fmt.Fprintf(w, "Error occurred while executing the hook's command. Please check your logs for more details.\n") + fmt.Fprintf(w, "Error occurred while executing the hook's command. Please check your logs for more details.") } else { fmt.Fprintf(w, response) }