Skip to content

Commit ef0575c

Browse files
author
Xinguang Wang
committed
support bitbucket && removed the Byte Order Mark (BOM).
UTF-8 text string with a Byte Order Mark (BOM). The BOM identifies that the text is UTF-8 encoded, but it should be removed before decoding.
1 parent b8161a8 commit ef0575c

File tree

13 files changed

+179
-70
lines changed

13 files changed

+179
-70
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
.ash_history
3+
4+
webhook

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
FROM docker:1.11.2-git
1+
FROM docker:1.13.0-git
22

3-
ADD https://github.com/starboychina/webhook/releases/download/0.1.0/webhook /usr/bin/webhook
3+
#ADD https://github.com/starboychina/webhook/releases/download/0.1.0/webhook /usr/bin/webhook
4+
COPY webhook /usr/bin/webhook
45
RUN chmod +x /usr/bin/webhook
56

67
ENTRYPOINT ["/usr/bin/webhook", "--config", "/config.json"]

README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,29 @@ webhook
66

77
## What is `webhook`?
88

9-
`webhook` is a little webserver written in go. He waits for webhook calls by github (or gogs) to run little shell commands.
9+
`webhook` is a little webserver written in go. He waits for webhook calls by github (or bitbucket, gogs) to run little shell commands.
1010

1111
## How to use
1212

1313
Just edit the config.json to your needs. A short example:
14-
You want to track the status of your Repository URL and the branch master. If there is an update to this branch you want to execute your shell script "niftyscript.sh".
14+
You want to track the status of your Repository URL and the branch master. If there is an update to this branch you want to execute your shell script.
1515

1616
```json
1717
{
1818
"Hooks":[
1919
{
20-
"Repo":"username/repo",
21-
"Branch":"master",
22-
"Shell":"niftyscript.sh"
20+
"Repo":"Repo URL",
21+
"Branch":"development",
22+
"Shell":"cd /var/ && git pull && make && make install"
23+
},
24+
{
25+
"Repo":"Repo URL",
26+
"Branch":"staging",
27+
"Shell":"docker restart app-node"
2328
},
2429
{
2530
"Repo":"Repo URL",
26-
"Branch":"master",
31+
"Branch":"production",
2732
"Shell":"script.sh"
2833
}
2934
]
@@ -37,7 +42,7 @@ Now start the server with
3742
```
3843

3944
and add a git-webhook for your.domain.com:9000/github. Everytime you push to master, your script gets executed.
40-
or add your.domain.com:9000/gogs. for gogs Repository.
45+
or add your.domain.com:9000/bitbucket. for bitbucket Repository, add your.domain.com:9000/gogs. for gogs Repository.
4146

4247
## Using Docker
4348

bitbucket.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type bitbucketPayload struct {
9+
// Push
10+
Push bitbucketPush `json:"push"`
11+
// Repository
12+
Repository bitbucketRepository `json:"repository"`
13+
}
14+
15+
// Push is the common Bitbucket Push Sub Entity
16+
type bitbucketPush struct {
17+
Changes []bitbucketChange `json:"changes"`
18+
}
19+
20+
// Change is the common Bitbucket Change Sub Entity
21+
type bitbucketChange struct {
22+
New bitbucketChangeData `json:"new"`
23+
}
24+
25+
// ChangeData is the common Bitbucket ChangeData Sub Entity
26+
type bitbucketChangeData struct {
27+
Name string `json:"name"`
28+
}
29+
30+
// Repository is the common Bitbucket Repository Entity
31+
type bitbucketRepository struct {
32+
Links bitbucketLinks `json:"links"`
33+
}
34+
35+
// Links is the common Bitbucket Links Sub Entity
36+
type bitbucketLinks struct {
37+
HTML bitbucketHTML `json:"html"`
38+
}
39+
40+
// HTML is the common Bitbucket HTML Sub Entity
41+
type bitbucketHTML struct {
42+
HREF string `json:"href"`
43+
}
44+
45+
func init() {
46+
var payload bitbucketPayload
47+
route("/bitbucket", &payload, func(hook Hook) bool {
48+
fmt.Println(payload.Push.Changes[0].New.Name)
49+
return strings.TrimRight(hook.Repo, "/") == payload.Repository.Links.HTML.HREF &&
50+
payload.Push.Changes[0].New.Name == hook.Branch
51+
})
52+
}

build.sh

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
# go run cert/generate_cert.go --host blog.kansea.com --org blog.kansea.com
44

5-
GOOS=linux GOARCH=amd64 go build -o webhook
5+
# GOOS=linux GOARCH=amd64 go build -o webhook
66

7-
docker rmi starboychina/webhook
8-
docker build -t starboychina/webhook .
7+
rm webhook
8+
docker run -it --rm -v $(pwd):/root golang:alpine sh -c '
9+
apk add --update git
10+
go get github.com/starboychina/webhook
11+
cd /go/src/github.com/starboychina/webhook
12+
go build -o /root/webhook
13+
'
14+
15+
docker rmi starboychina/webhook
16+
docker build -t starboychina/webhook:1.13.0 .
17+
docker build -t starboychina .

config.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
{
44
"Repo":"https://github.com/starboychina/webhook",
55
"Branch":"master",
6-
"Shell":"build.sh"
6+
"Shell":"cd /var/ && git pull && make && make install"
77
},
88
{
99
"Repo":"https://try.gogs.io/starboychina/webhook",
1010
"Branch":"dev",
1111
"Shell":"date"
12+
},
13+
{
14+
"Repo":"https://bitbucket.org/starboychina/hook",
15+
"Branch":"master",
16+
"Shell":"date"
1217
}
1318
]
1419
}

github.go

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package main
22

33
import (
4-
"encoding/json"
5-
"fmt"
6-
"log"
7-
"net/http"
84
"strings"
95
)
106

@@ -18,28 +14,9 @@ type githubPayload struct {
1814
}
1915

2016
func init() {
21-
22-
http.HandleFunc("/github", githubHandle)
23-
24-
}
25-
26-
func githubHandle(w http.ResponseWriter, req *http.Request) {
27-
fmt.Fprintf(w, "")
28-
defer req.Body.Close()
29-
decoder := json.NewDecoder(req.Body)
30-
3117
var payload githubPayload
32-
err := decoder.Decode(&payload)
33-
if err != nil {
34-
log.Printf("payload json decode failed: %s\n", err)
35-
return
36-
}
37-
38-
for _, hook := range config.Hooks {
39-
if strings.TrimRight(hook.Repo, "/") == payload.Repo.URL && strings.Contains(payload.Ref, hook.Branch) {
40-
fmt.Println(hook.Repo)
41-
executeShell(hook.Shell)
42-
}
43-
}
44-
18+
route("/github", &payload, func(hook Hook) bool {
19+
return strings.TrimRight(hook.Repo, "/") == payload.Repo.URL &&
20+
payload.Ref == "refs/heads/"+hook.Branch
21+
})
4522
}

gogs.go

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package main
22

33
import (
4-
"encoding/json"
5-
"fmt"
6-
"log"
7-
"net/http"
84
"strings"
95
)
106

@@ -18,28 +14,9 @@ type gogsPayload struct {
1814
}
1915

2016
func init() {
21-
22-
http.HandleFunc("/gogs", gogsHandle)
23-
24-
}
25-
26-
func gogsHandle(w http.ResponseWriter, req *http.Request) {
27-
fmt.Fprintf(w, "")
28-
defer req.Body.Close()
29-
decoder := json.NewDecoder(req.Body)
30-
3117
var payload gogsPayload
32-
err := decoder.Decode(&payload)
33-
if err != nil {
34-
log.Printf("payload json decode failed: %s\n", err)
35-
return
36-
}
37-
38-
for _, hook := range config.Hooks {
39-
if strings.TrimRight(hook.Repo, "/") == payload.Repo.URL && strings.Contains(payload.Ref, hook.Branch) {
40-
fmt.Println(hook.Repo)
41-
executeShell(hook.Shell)
42-
}
43-
}
44-
18+
route("/gogs", &payload, func(hook Hook) bool {
19+
return strings.TrimRight(hook.Repo, "/") == payload.Repo.URL &&
20+
payload.Ref == "refs/heads/"+hook.Branch
21+
})
4522
}

httpHandle.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"net/http"
7+
)
8+
9+
func route(pattern string,
10+
payload interface{},
11+
handler func(Hook) bool) {
12+
13+
log.Printf(pattern)
14+
http.HandleFunc(pattern, func(w http.ResponseWriter, req *http.Request) {
15+
defer req.Body.Close()
16+
17+
err := unmarshal(req.Body, &payload)
18+
if err != nil {
19+
fmt.Fprintf(w, something)
20+
return
21+
}
22+
23+
loadConfig()
24+
25+
msg := ""
26+
for _, hook := range config.Hooks {
27+
if handler(hook) {
28+
msg = fmt.Sprintf(executed, hook.Repo, hook.Branch)
29+
logger.Printf("success: %s\n", msg)
30+
msg += "`" + hook.Shell + "`"
31+
executeShell(hook.Shell)
32+
}
33+
}
34+
35+
if len(msg) < 1 {
36+
logger.Printf(nothingToDo)
37+
msg = nothingToDo
38+
}
39+
fmt.Fprintf(w, msg)
40+
})
41+
}

json.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"io"
7+
"io/ioutil"
8+
)
9+
10+
func unmarshal(body io.Reader, v interface{}) error {
11+
bodyBytes, err := ioutil.ReadAll(body)
12+
13+
if err != nil {
14+
logger.Printf("error[ioutil.ReadAll]: %s\n", err)
15+
return err
16+
}
17+
bodyBytes = bytes.TrimPrefix(bodyBytes, []byte("\xef\xbb\xbf"))
18+
err = json.Unmarshal(bodyBytes, &v)
19+
20+
if err != nil {
21+
logger.Printf("error[json.Unmarshal]: %s\n", err)
22+
return err
23+
}
24+
return nil
25+
}

0 commit comments

Comments
 (0)