Skip to content

Instantly share code, notes, and snippets.

@larryli
Last active January 2, 2016 13:59
Show Gist options
  • Save larryli/8314170 to your computer and use it in GitHub Desktop.
Save larryli/8314170 to your computer and use it in GitHub Desktop.
// GOARCH=arm GOOS=linux GOCHAR=5 go build -ldflags "-s -w" -o github-webhook-pull.cgi github-webhook-pull.go
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/http/cgi"
"os"
)
// see https://help.github.com/articles/post-receive-hooks
type Person struct {
Name string `json:"name"`
Email string `json:"email"`
}
type Commit struct {
ID string `json:"id"`
Message string `json:"message"`
Added []string `json:"added"`
Removed []string `json:"removed"`
Modified []string `json:"modified"`
Timestamp string `json:"timestamp"`
Url string `json:"url"`
Author Person `json:"author"`
}
type Repository struct {
ID int `json:"id"`
Name string `json:"name"`
Created int `json:"created_at"`
Description string `json:"description"`
Fork bool `json:"fork"`
Forks int `json:"forks"`
Homepage string `json:"homepage"`
Issues int `json:"open_issues"`
Language string `json:"language"`
Owner Person `json:"owner"`
Private bool `json:"private"`
Pushed int `json:"pushed_at"`
Size int `json:"size"`
Url string `json:"url"`
}
type WebHook struct {
Before string `json:"before"`
After string `json:"after"`
Ref string `json:"ref"`
Commits []Commit `json:"commits"`
Repo Repository `json:"repository"`
}
func plain(w http.ResponseWriter) {
header := w.Header()
header.Set("Content-Type", "text/plain; charset=utf-8")
}
func dump(w http.ResponseWriter, path string, hook WebHook) {
plain(w)
fmt.Fprintln(w, "PATH", path)
fmt.Fprintln(w, "REPO_FORKS", hook.Repo.Forks)
fmt.Fprintln(w, "REPO_PRIVATE", hook.Repo.Private)
fmt.Fprintln(w, "REPO_CREATED", hook.Repo.Created)
fmt.Fprintln(w, "REPO_PUSHED", hook.Repo.Pushed)
fmt.Fprintln(w, "REPO_NAME", hook.Repo.Name)
fmt.Fprintln(w, "REPO_URL", hook.Repo.Url)
fmt.Fprintln(w, "REPO_DESCRIPTION", hook.Repo.Description)
fmt.Fprintln(w, "REPO_HOMEPAGE", hook.Repo.Homepage)
fmt.Fprintln(w, "REPO_OWNER_NAME", hook.Repo.Owner.Name)
fmt.Fprintln(w, "REPO_OWNER_EMAIL", hook.Repo.Owner.Email)
fmt.Fprintln(w, "WEBHOOK_BEFORE", hook.Before)
fmt.Fprintln(w, "WEBHOOK_AFTER", hook.After)
fmt.Fprintln(w, "WEBHOOK_REF", hook.Ref)
}
func isNotGitPath(path string) bool {
stat1, err1 := os.Stat(path)
if err1 != nil {
return true
}
if stat1.IsDir() == false {
return true
}
path2 := path + "/.git"
stat2, err2 := os.Stat(path2)
if err2 != nil {
return true
}
if stat2.IsDir() == false {
return true
}
return false
}
func handler(w http.ResponseWriter, r *http.Request) {
var hook WebHook
if r.Method != "POST" {
http.Error(w, "Method not allowed", 405)
return
}
if err := r.ParseForm(); err != nil {
http.Error(w, "Bad request", 400)
return
}
path := r.FormValue("path")
if path == "" || isNotGitPath(path) {
http.Error(w, "Bad request", 400)
return
}
payload := r.FormValue("payload")
if payload == "" {
http.Error(w, "Bad request", 400)
return
}
if err := json.Unmarshal([]byte(payload), &hook); err != nil {
http.Error(w, "Bad request", 400)
return
}
dump(w, path, hook)
}
func main() {
if err := cgi.Serve(http.HandlerFunc(handler)); err != nil {
fmt.Println(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment