Skip to content

Commit

Permalink
Merge pull request #1384 from dippynark/support-commit-label-regex-pa…
Browse files Browse the repository at this point in the history
…ttern

feat: Support commit context match pattern
  • Loading branch information
jenkins-x-bot authored Nov 17, 2021
2 parents 2d0cb46 + 7548228 commit ab092cb
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 26 deletions.
3 changes: 3 additions & 0 deletions charts/lighthouse/templates/poller-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ spec:
imagePullPolicy: {{ tpl .Values.poller.image.pullPolicy . }}
args:
- "--namespace={{ .Release.Namespace }}"
{{- if .Values.poller.contextMatchPattern }}
- "--context-match-pattern={{ .Values.poller.contextMatchPattern }}"
{{- end }}
ports:
- name: http
containerPort: {{ .Values.poller.internalPort }}
Expand Down
3 changes: 3 additions & 0 deletions charts/lighthouse/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@ poller:
# poller.env.POLL_HOOK_ENDPOINT the hook service endpoint to post webhooks to
POLL_HOOK_ENDPOINT: http://hook/hook/poll

# poller.contextMatchPattern -- Regex pattern to use to match commit status context
contextMatchPattern: ""

resources:
# poller.resources.limits -- Resource limits applied to the poller pods
limits:
Expand Down
13 changes: 12 additions & 1 deletion cmd/poller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/http"
"net/url"
"os"
"regexp"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -40,6 +41,7 @@ type options struct {
namespace string
repoNames string
hookEndpoint string
contextMatchPattern string
runOnce bool
dryRun bool
disablePollRelease bool
Expand All @@ -62,6 +64,7 @@ func gatherOptions(fs *flag.FlagSet, args ...string) options {
fs.StringVar(&o.botName, "bot-name", "", "The bot name")
fs.StringVar(&o.gitServerURL, "git-url", "", "The git provider URL")
fs.StringVar(&o.gitKind, "git-kind", "", "The git provider kind (e.g. github, gitlab, bitbucketserver")
fs.StringVar(&o.contextMatchPattern, "context-match-pattern", "", "Regex pattern to use to match commit status context.")
fs.BoolVar(&o.runOnce, "run-once", false, "If true, run only once then quit.")
fs.BoolVar(&o.dryRun, "dry-run", false, "Disable POSTing to the webhook service and just log the webhooks instead.")
fs.BoolVar(&o.disablePollRelease, "no-release", false, "Disable polling for new commits on the main branch (releases) - mostly used for easier testing/debugging.")
Expand Down Expand Up @@ -154,6 +157,14 @@ func main() {
logrus.WithError(err).Fatalf("failed to parse git server %s", serverURL)
}

var contextMatchPatternCompiled *regexp.Regexp
if o.contextMatchPattern != "" {
contextMatchPatternCompiled, err = regexp.Compile(o.contextMatchPattern)
if err != nil {
logrus.WithError(err).Fatalf("failed to compile context match pattern \"%s\"", o.contextMatchPattern)
}
}

configureOpts := func(opts *gitv2.ClientFactoryOpts) {
opts.Token = func() []byte {
return []byte(o.gitToken)
Expand Down Expand Up @@ -194,7 +205,7 @@ func main() {
logrus.WithError(err).Fatal("failed to create scm client")
}

c, err := poller.NewPollingController(repoNames, serverURL, scmClient, fb, o.notifier)
c, err := poller.NewPollingController(repoNames, serverURL, scmClient, contextMatchPatternCompiled, fb, o.notifier)
if err != nil {
logrus.WithError(err).Fatal("Error creating Poller controller.")
}
Expand Down
46 changes: 28 additions & 18 deletions pkg/poller/poller.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package poller
import (
"context"
"net/http"
"regexp"
"strconv"
"strings"

Expand All @@ -19,34 +20,36 @@ var (
)

type pollingController struct {
DisablePollRelease bool
DisablePollPullRequest bool
repositoryNames []string
gitServer string
scmClient *scm.Client
fb filebrowser.Interface
pollstate pollstate.Interface
logger *logrus.Entry
notifier func(webhook *scm.WebhookWrapper) error
DisablePollRelease bool
DisablePollPullRequest bool
repositoryNames []string
gitServer string
scmClient *scm.Client
fb filebrowser.Interface
pollstate pollstate.Interface
logger *logrus.Entry
contextMatchPatternCompiled *regexp.Regexp
notifier func(webhook *scm.WebhookWrapper) error
}

func (c *pollingController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello from lighthouse poller\n"))
}

func NewPollingController(repositoryNames []string, gitServer string, scmClient *scm.Client, fb filebrowser.Interface, notifier func(webhook *scm.WebhookWrapper) error) (*pollingController, error) {
func NewPollingController(repositoryNames []string, gitServer string, scmClient *scm.Client, contextMatchPatternCompiled *regexp.Regexp, fb filebrowser.Interface, notifier func(webhook *scm.WebhookWrapper) error) (*pollingController, error) {
logger := logrus.NewEntry(logrus.StandardLogger())
if gitServer == "" {
gitServer = "https://github.com"
}
return &pollingController{
repositoryNames: repositoryNames,
gitServer: gitServer,
logger: logger,
scmClient: scmClient,
fb: fb,
notifier: notifier,
pollstate: pollstate.NewMemoryPollState(),
repositoryNames: repositoryNames,
gitServer: gitServer,
logger: logger,
scmClient: scmClient,
contextMatchPatternCompiled: contextMatchPatternCompiled,
fb: fb,
notifier: notifier,
pollstate: pollstate.NewMemoryPollState(),
}, nil
}

Expand Down Expand Up @@ -278,14 +281,21 @@ func (c *pollingController) hasStatusForSHA(ctx context.Context, l *logrus.Entry
return false, errors.Wrapf(err, "failed to list status")
}
for _, s := range statuses {
if !strings.HasPrefix(s.Label, "Lighthouse") {
if c.isMatchingStatus(s) {
l.WithField("Statuses", statuses).Info("the SHA has CI statuses so not triggering")
return true, nil
}
}
return false, nil
}

func (c *pollingController) isMatchingStatus(s *scm.Status) bool {
if c.contextMatchPatternCompiled != nil {
return c.contextMatchPatternCompiled.MatchString(s.Label)
}
return !strings.HasPrefix(s.Label, "Lighthouse")
}

func (c *pollingController) createPushHook(fullName, owner, repo, before, after, branch, refBranch string) (*scm.PushHook, error) {
return &scm.PushHook{
Ref: "refs/heads/" + refBranch,
Expand Down
36 changes: 29 additions & 7 deletions pkg/poller/poller_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package poller_test

import (
"os/exec"
"regexp"
"strings"
"testing"

scmfake "github.com/jenkins-x/go-scm/scm/driver/fake"
Expand All @@ -14,9 +17,11 @@ import (
)

var (
repoNames = []string{"myorg/myrepo"}

gitServer = "https://github.com"
repoNames = []string{"myorg/myrepo"}
gitServer = "https://github.com"
testDataDir = "test_data"
contextMatchPattern = "^Lighthouse$"
statusLabel = "Jenkins"
)

func TestPollerReleases(t *testing.T) {
Expand All @@ -30,10 +35,21 @@ func TestPollerReleases(t *testing.T) {
}
return nil
}
scmClient, _ := scmfake.NewDefault()
fb := fbfake.NewFakeFileBrowser("test_data", true)
scmClient, fakeData := scmfake.NewDefault()
fb := fbfake.NewFakeFileBrowser(testDataDir, true)

contextMatchPatternCompiled, err := regexp.Compile(contextMatchPattern)
require.NoErrorf(t, err, "failed to compile context match pattern \"%s\"", contextMatchPattern)

p, err := poller.NewPollingController(repoNames, gitServer, scmClient, fb, fakeNotifier)
// Load fake status with label that doesn't match our context match pattern
c := exec.Command("git", "rev-parse", "HEAD")
c.Dir = testDataDir
out, err := c.CombinedOutput()
require.NoError(t, err, "failed to get latest git commit sha")
sha := strings.TrimSpace(string(out))
fakeData.Statuses = map[string][]*scm.Status{sha: {{Label: statusLabel}}}

p, err := poller.NewPollingController(repoNames, gitServer, scmClient, contextMatchPatternCompiled, fb, fakeNotifier)
require.NoError(t, err, "failed to create PollingController")

p.PollReleases()
Expand Down Expand Up @@ -62,6 +78,9 @@ func TestPollerPullRequests(t *testing.T) {
scmClient, fakeData := scmfake.NewDefault()
fb := fbfake.NewFakeFileBrowser("test_data", true)

contextMatchPatternCompiled, err := regexp.Compile(contextMatchPattern)
require.NoErrorf(t, err, "failed to compile context match pattern \"%s\"", contextMatchPattern)

prNumber := 123
fullName := repoNames[0]
owner, repo := scm.Split(fullName)
Expand All @@ -85,7 +104,10 @@ func TestPollerPullRequests(t *testing.T) {
State: "open",
Sha: sha,
}
p, err := poller.NewPollingController(repoNames, gitServer, scmClient, fb, fakeNotifier)
// Load fake status with label that doesn't match our context match pattern
fakeData.Statuses = map[string][]*scm.Status{sha: {{Label: statusLabel}}}

p, err := poller.NewPollingController(repoNames, gitServer, scmClient, contextMatchPatternCompiled, fb, fakeNotifier)
require.NoError(t, err, "failed to create PollingController")

p.PollPullRequests()
Expand Down

0 comments on commit ab092cb

Please sign in to comment.