forked from IBM/CodeEngine
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgithub.go
More file actions
Latest commit
116 lines (101 loc) · 3.09 KB
/
Copy pathgithub.go
File metadata and controls
116 lines (101 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package main
import (
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"os"
)
// To verify events are from out github webhook set this to the "secert"
// we set on the github webhook. Leave it blank to skip the check.
varGitHubSecret=os.Getenv("GIT_SECRET")
// Verify the incoming github event by checking its signature against
// the SHA of the body, using our GIT_SECRET as the key
funcVerifyEvent(req*http.Request, body []byte, secretstring) bool {
sig:=req.Header.Get("X-HUB-SIGNATURE")
iflen(sig) !=45||sig[:5] !="sha1=" {
returnfalse
}
calc:=make([]byte, 20)
hex.Decode(calc, []byte(sig[5:]))
mac:=hmac.New(sha1.New, []byte(secret))
mac.Write(body)
returnhmac.Equal(calc, mac.Sum(nil))
}
// Do whatever logic we need for the incoming event
funcProcessEvent(eventTypestring, eventBody []byte) int {
log.Printf("Event Type: %s", eventType)
// Only care about "push" events and "ping" for webhook creation
ifeventType=="ping" {
returnhttp.StatusOK
} elseifeventType!="push" {
log.Print("Not a 'push' event so exit")
returnhttp.StatusBadRequest
}
pretty, _:=json.MarshalIndent(json.RawMessage(eventBody), "", " ")
log.Printf("\nEvent:\n%s", string(pretty))
// The following sample JSON is just a subset of the data in the event,
// but has the key bits we care about:
//
// {
// "ref": "refs/heads/master",
// "before": "--commit-ID--",
// "after": "--commit-ID--",
// "repository": {
// "name": "CodeEngine",
// "full_name": "IBM/CodeEngin,
// }
// "pusher": {
// "name": "github-id",
// "email": "user-email"
// },
// "sender": {},
// "commits": []
// }
// Define a var/struct to hold the parsed event data
PushEvent:=struct {
Refstring
Afterstring
Repostruct {
Namestring
FullNamestring
}
Pusherstruct {
Namestring
Emailstring
}
}{}
// Parse the event data into the PushEvent object
err:=json.Unmarshal(eventBody, &PushEvent)
iferr!=nil {
log.Printf("Error parsing:\n%s\n%s", err, string(eventBody))
returnhttp.StatusBadRequest
}
log.Printf("%s committed %q to %q branch",
PushEvent.Pusher.Name, PushEvent.After, PushEvent.Ref)
// Now we'd normally do a build, but let's just fake it.
// To see how to kick off CodeEngine CLI commands from inside of an app
// see the "cecli" sample.
log.Print("ibmcloud ce buildrun submit ...")
returnhttp.StatusOK
}
// Simple web server that waits for incoming events, verifies they're
// from our webhook (by using the GIT_SECRET, if set) and if ok process it
funcmain() {
http.HandleFunc("/", func(w http.ResponseWriter, r*http.Request) {
body, _:=ioutil.ReadAll(r.Body)
// Make sure it comes from our repo (if we want to check it at all)
ifGitHubSecret!=""&&!VerifyEvent(r, body, GitHubSecret) {
log.Printf("Error verifying github event")
w.WriteHeader(http.StatusUnauthorized)
return
}
status:=ProcessEvent(r.Header.Get("X-Github-Event"), body)
w.WriteHeader(status)
})
log.Printf("Listening on port 8080")
http.ListenAndServe(":8080", nil)
}