diff --git a/frontend.go b/frontend.go
index 5c694af..2d77045 100644
--- a/frontend.go
+++ b/frontend.go
@@ -112,6 +112,19 @@ func resultPage(w http.ResponseWriter, r *http.Request) {
Secret: secret,
}
+ // set the repo to opt-in
+ if strings.ToUpper(r.URL.Query().Get("optin")) == "ON" {
+ repo.OptIn = true
+ }
+ // define custom opt-in flag
+ if r.URL.Query().Get("optinFlag") != "" {
+ repo.OptInFlag = r.URL.Query().Get("optinFlag")
+ }
+ // define custom opt-out flag
+ if r.URL.Query().Get("optoutFlag") != "" {
+ repo.OptOutFlag = r.URL.Query().Get("optoutFlag")
+ }
+
name := "web"
hook := github.Hook{
Name: &name, Events: []string{"pull_request"},
diff --git a/repo.go b/repo.go
index c7c2f85..911e73f 100644
--- a/repo.go
+++ b/repo.go
@@ -27,6 +27,9 @@ type Repo struct {
Slug string
Token string
Secret string
+ OptIn bool
+ OptInFlag string `gorm:"default:'ci'"`
+ OptOutFlag string `gorm:"default:'ci skip'"`
}
type Repos []Repo
diff --git a/templates/auth.html b/templates/auth.html
index ba62653..27daf07 100644
--- a/templates/auth.html
+++ b/templates/auth.html
@@ -15,6 +15,29 @@
Your project slug is the Github user- and repository name separated by a slash e.g. ganggo/federation
+
+
+
+
+ That would mean that tests are triggered if you specify [ci] in the PR title, body, commit-message
+ or if the PR was tagged with ci. If you leave the box unchecked
+ tests will be triggered on every pull-request. However you can skip them by using [ci skip]
+ in the mentioned fields or tag it with ci skip.
+
+
+
+
+
+ If you want to use custom build triggers for opt-in you can specify it here.
+
+
+
+
+
+ If you want to use custom build triggers for opt-out you can specify it here.
+
+
+
diff --git a/webhook.go b/webhook.go
index a9bec60..31373f1 100644
--- a/webhook.go
+++ b/webhook.go
@@ -25,6 +25,8 @@ import (
"encoding/json"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
+ "strings"
+ "context"
)
func webhook(w http.ResponseWriter, r *http.Request) {
@@ -54,16 +56,18 @@ func webhook(w http.ResponseWriter, r *http.Request) {
}
// skip all events except for open PRs
- if *pr.State != "open" {
+ if pr.GetState() != "open" {
logger.Println("Ignore closed pull request")
fmt.Fprintf(w, `{}`)
return
}
var repo Repo
- err = db.Where("slug = ?", *pr.Base.Repo.FullName).Find(&repo).Error
+ err = db.Where("slug = ?",
+ pr.GetBase().GetRepo().GetFullName(),
+ ).Find(&repo).Error
if err != nil {
- logger.Println(err, *pr.Base.Repo.FullName)
+ logger.Println(err, pr.GetBase().GetRepo().GetFullName())
fmt.Fprintf(w, `{"error":"repo not registered"}`)
return
}
@@ -76,24 +80,86 @@ func webhook(w http.ResponseWriter, r *http.Request) {
// return
//}
+ var flagExists = false
+ var buildFlag = repo.OptOutFlag
+ if repo.OptIn {
+ buildFlag = repo.OptInFlag
+ }
+
+ // check PR title and body for [ci] or [ci skip] flag
+ if pr.Title != nil && strings.Contains(pr.GetTitle(),
+ fmt.Sprintf("[%s]", buildFlag)) {
+ flagExists = true
+ } else if pr.Body != nil && strings.Contains(pr.GetBody(),
+ fmt.Sprintf("[%s]", buildFlag)) {
+ flagExists = true
+ } else {
+ // check labels for build flag if we haven't already found it
+ for _, label := range pr.Labels {
+ if label.Name != nil && strings.Contains(label.GetName(), buildFlag) {
+ flagExists = true
+ break
+ }
+ }
+
+ if !flagExists {
+ // last but not least check the commit message for flags
+ client := github.NewClient(nil)
+ commits, _, err := client.PullRequests.ListCommits(
+ context.Background(),
+ pr.GetHead().GetUser().GetLogin(),
+ pr.GetHead().GetRepo().GetName(),
+ pr.GetNumber(), &github.ListOptions{})
+
+ if err == nil && len(commits) > 0 {
+ // check only last commit since older ones are irrelevant
+ commitMsg := commits[len(commits)-1].GetCommit().GetMessage()
+ flagExists = strings.Contains(
+ commitMsg, fmt.Sprintf("[%s]", buildFlag))
+ } else {
+ logger.Printf("Commits is empty or an error occurred: %+v\n", err)
+ }
+ }
+ }
+
+ // ignoring pull-request! Repository is set
+ // to opt-in and no build flag was found
+ if repo.OptIn && !flagExists {
+ logger.Printf(
+ "Ignore optin=%t buildFlag=%s flagExists=%t\n",
+ repo.OptIn, buildFlag, flagExists)
+ fmt.Fprintf(w, `{}`)
+ return
+ }
+
+ // ignoring pull-request! Repository is set
+ // to opt-out and a skip flag was found
+ if !repo.OptIn && flagExists {
+ logger.Printf(
+ "Ignore optin=%t buildFlag=%s flagExists=%t\n",
+ repo.OptIn, buildFlag, flagExists)
+ fmt.Fprintf(w, `{}`)
+ return
+ }
+
build := Build{
RepoID: repo.ID,
Matrix: fmt.Sprintf(
`"PROJECT=%s PRREPO=%s PRSHA=%s"`,
repo.Project,
- *pr.Head.Repo.CloneURL,
- *pr.Head.SHA,
+ pr.GetHead().GetRepo().GetCloneURL(),
+ pr.GetHead().GetSHA(),
),
- PRUser: *pr.Head.User.Login,
- PRRepo: *pr.Head.Repo.Name,
- PRSha: *pr.Head.SHA,
+ PRUser: pr.GetHead().GetUser().GetLogin(),
+ PRRepo: pr.GetHead().GetRepo().GetName(),
+ PRSha: pr.GetHead().GetSHA(),
}
+
err = db.Create(&build).Error
if err != nil {
logger.Println(err)
fmt.Fprintf(w, `{"error":"database error"}`)
return
}
-
fmt.Fprintf(w, `{}`)
}