diff --git a/server/handler/hook.go b/server/handler/hook.go index 2b08a0130..3aeebf6ef 100644 --- a/server/handler/hook.go +++ b/server/handler/hook.go @@ -2,9 +2,11 @@ package handler import ( "net/http" + "strings" "github.com/drone/drone/plugin/remote" "github.com/drone/drone/server/database" + "github.com/drone/drone/shared/build/script" "github.com/drone/drone/shared/httputil" "github.com/drone/drone/shared/model" "github.com/gorilla/pat" @@ -49,7 +51,7 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { // in some cases we have neither a hook nor error. An example // would be GitHub sending a ping request to the URL, in which // case we'll just exit quiely with an 'OK' - if hook == nil { + if hook == nil || strings.Contains(hook.Message, "[CI SKIP]") { w.WriteHeader(http.StatusOK) return nil } @@ -80,6 +82,15 @@ func (h *HookHandler) PostHook(w http.ResponseWriter, r *http.Request) error { return badRequest{err} } + // verify the commit hooks branch matches the list of approved + // branches (unless it is a pull request). Note that we don't really + // care if parsing the yaml fails here. + s, _ := script.ParseBuild(yml, map[string]string{}) + if len(hook.PullRequest) != 0 && !s.MatchBranch(hook.Branch) { + w.WriteHeader(http.StatusOK) + return nil + } + c := model.Commit{ RepoID: repo.ID, Status: model.StatusEnqueue, diff --git a/shared/build/script/script.go b/shared/build/script/script.go index bb6ddc002..9f7d2d6ed 100644 --- a/shared/build/script/script.go +++ b/shared/build/script/script.go @@ -71,6 +71,9 @@ type Build struct { // linked to the build environment. Services []string + // White-list of Branches that are built. + Branches []string + Deploy *deploy.Deploy `yaml:"deploy,omitempty"` Publish *publish.Publish `yaml:"publish,omitempty"` Notifications *notify.Notification `yaml:"notify,omitempty"` @@ -119,6 +122,18 @@ func (b *Build) WriteBuild(f *buildfile.Buildfile) { } } +func (b *Build) MatchBranch(branch string) bool { + if len(b.Branches) == 0 { + return true + } + for _, item := range b.Branches { + if item == branch { + return true + } + } + return false +} + type Publish interface { Write(f *buildfile.Buildfile) }