Repository: jenkins-x/lighthouse
Pull request #1342 (2021-07-02 13:26:45)

fix: correct BBC scm client authentication for keeper
Fix scm client authentication failure for bitbucket cloud


Patch:
diff --git a/.jx/updatebot.yaml b/.jx/updatebot.yaml
index d54b6b9d..86084df4 100644
--- a/.jx/updatebot.yaml
+++ b/.jx/updatebot.yaml
@@ -9,4 +9,4 @@ spec:
             pattern: |
               version: (.*)
             files:
-              - "charts/jxgh/lighthouse/defaults.yaml"
+              - "charts/jx3/lighthouse/defaults.yaml"
diff --git a/charts/lighthouse/README.md b/charts/lighthouse/README.md
index b04c1942..bb689157 100644
--- a/charts/lighthouse/README.md
+++ b/charts/lighthouse/README.md
@@ -73,13 +73,13 @@ helm uninstall my-lighthouse --namespace lighthouse
 | `gcJobs.successfulJobsHistoryLimit` | int | Drives the successful jobs history limit | `3` |
 | `git.kind` | string | Git SCM provider (`github`, `gitlab`, `stash`) | `"github"` |
 | `git.server` | string | Git server URL | `""` |
-| `githubApp.enabled` | bool | Enables GitHub app authentication | `false` |
-| `githubApp.username` | string | GitHub app user name | `"jenkins-x[bot]"` |
+| `githubApp.enabled` | string | Enables GitHub app authentication | `"false log"` |
+| `githubApp.username` | string | GitHub app user name  | `"jenkins-x[bot]"` |
 | `hmacToken` | string | Secret used for webhooks | `""` |
 | `hmacTokenEnabled` | bool | Enables the use of a hmac token. This should always be enabled if possible - though some git providers don't support it such as bitbucket cloud | `true` |
 | `image.parentRepository` | string | Docker registry to pull images from | `"ghcr.io/jenkins-x"` |
 | `image.pullPolicy` | string | Image pull policy | `"IfNotPresent"` |
-| `image.tag` | string | Docker images tag the following tag is latest on the main branch, it's a specific version on a git tag | `"latest"` |
+| `image.tag` | string | Docker images tag | `"0.0.750"` |
 | `jenkinscontroller.affinity` | object | [Affinity rules](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) applied to the tekton controller pods | `{}` |
 | `jenkinscontroller.image.pullPolicy` | string | Template for computing the tekton controller docker image pull policy | `"{{ .Values.image.pullPolicy }}"` |
 | `jenkinscontroller.image.repository` | string | Template for computing the Jenkins controller docker image repository | `"{{ .Values.image.parentRepository }}/lighthouse-jenkins-controller"` |
diff --git a/charts/lighthouse/templates/config-external-plugins.yaml b/charts/lighthouse/templates/config-external-plugins.yaml
deleted file mode 100644
index 5aaa2308..00000000
--- a/charts/lighthouse/templates/config-external-plugins.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: lighthouse-external-plugins
-  labels:
-    app: {{ template "fullname" . }}
-    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
-    release: "{{ .Release.Name }}"
-data:
-  config.yaml: |-
-{{ toYaml .Values.externalPlugins | indent 4 }}
diff --git a/charts/lighthouse/templates/webhooks-role.yaml b/charts/lighthouse/templates/webhooks-role.yaml
index 549fd60b..46a4b1d4 100644
--- a/charts/lighthouse/templates/webhooks-role.yaml
+++ b/charts/lighthouse/templates/webhooks-role.yaml
@@ -15,14 +15,6 @@ rules:
   - create
   - list
   - watch
-- apiGroups:
-  - ""
-  resources:
-  - services
-  verbs:
-  - get
-  - list
-  - watch
 - apiGroups:
   - lighthouse.jenkins.io
   resources:
diff --git a/charts/lighthouse/values.yaml b/charts/lighthouse/values.yaml
index e5e8bbd2..2d6a31e5 100644
--- a/charts/lighthouse/values.yaml
+++ b/charts/lighthouse/values.yaml
@@ -60,19 +60,6 @@ image:
 env:
   JX_DEFAULT_IMAGE: ""
 
-
-externalPlugins:
-- name: cd-indicators
-  requiredResources:
-  - kind: Service
-    namespace: jx
-    name: cd-indicators
-- name: lighthouse-webui-plugin
-  requiredResources:
-  - kind: Service
-    namespace: jx
-    name: lighthouse-webui-plugin
-
 gcJobs:
   # gcJobs.maxAge -- Max age from which `LighthouseJob`s will be deleted
   maxAge: 168h
diff --git a/go.mod b/go.mod
index 3677ee22..fb5ff99b 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
 	github.com/h2non/gock v1.0.9
 	github.com/hashicorp/go-multierror v1.1.0
 	github.com/hashicorp/golang-lru v0.5.4
-	github.com/jenkins-x/go-scm v1.10.3
+	github.com/jenkins-x/go-scm v1.10.0
 	github.com/mattn/go-zglob v0.0.1
 	github.com/onsi/ginkgo v1.14.1
 	github.com/onsi/gomega v1.10.2
@@ -35,7 +35,7 @@ require (
 
 replace (
 	// lets override the go-scm version from tektoncd
-	github.com/jenkins-x/go-scm => github.com/jenkins-x/go-scm v1.10.3
+	github.com/jenkins-x/go-scm => github.com/jenkins-x/go-scm v1.10.0
 
 	github.com/tektoncd/pipeline => github.com/jenkins-x/pipeline v0.3.2-0.20210223153617-0d1186b27496
 
diff --git a/go.sum b/go.sum
index 64f2f237..e9d6e777 100644
--- a/go.sum
+++ b/go.sum
@@ -464,8 +464,8 @@ github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mq
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
 github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
 github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
-github.com/jenkins-x/go-scm v1.10.3 h1:ONe2YImgnYxFRsl7njmnutWBSZU29XvcIU87t88lV6s=
-github.com/jenkins-x/go-scm v1.10.3/go.mod h1:z7xTO9/VzqW3xEbEMH2z5cpOGrZ8+nOHOWfU1ngFGxs=
+github.com/jenkins-x/go-scm v1.10.0 h1:SSLR/TtbSKwScGtYHFygdXPx/88igT+xFgmlOfhh6y0=
+github.com/jenkins-x/go-scm v1.10.0/go.mod h1:z7xTO9/VzqW3xEbEMH2z5cpOGrZ8+nOHOWfU1ngFGxs=
 github.com/jenkins-x/pipeline v0.3.2-0.20210223153617-0d1186b27496 h1:yN90dXuD7TkAkYwKr5h2fT7bjA7osK7tMhuz31qL7gE=
 github.com/jenkins-x/pipeline v0.3.2-0.20210223153617-0d1186b27496/go.mod h1:y1XwzBDu4EmOCfoeV2cUW2icCto/izTyjEKK5j0UmwA=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
diff --git a/pkg/externalplugincfg/load.go b/pkg/externalplugincfg/load.go
deleted file mode 100644
index 9e0dde44..00000000
--- a/pkg/externalplugincfg/load.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package externalplugincfg
-
-import (
-	"context"
-	"github.com/jenkins-x/lighthouse/pkg/util"
-	"github.com/pkg/errors"
-	"github.com/sirupsen/logrus"
-	apierrors "k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/client-go/kubernetes"
-	"sigs.k8s.io/yaml"
-	"strings"
-)
-
-func LoadDisabledPlugins(l *logrus.Entry, client kubernetes.Interface, namespace string) ([]string, error) {
-	answer := []string{}
-
-	ctx := context.TODO()
-
-	l = l.WithFields(map[string]interface{}{
-		"Namespace": namespace,
-		"ConfigMap": ConfigMapName,
-	})
-	cm, err := client.CoreV1().ConfigMaps(namespace).Get(ctx, ConfigMapName, metav1.GetOptions{})
-	if err != nil {
-		if apierrors.IsNotFound(err) {
-			l.Warnf("no ConfigMap for the external plugin configuration")
-			return answer, nil
-		}
-		if err != nil {
-			return nil, errors.Wrapf(err, "failed to load ConfigMap %s in namespace %s", ConfigMapName, namespace)
-		}
-	}
-	text := ""
-	if cm != nil && cm.Data != nil {
-		text = cm.Data["config.yaml"]
-	}
-	if text == "" {
-		l.Warnf("no config.yaml entry in external plugin ConfigMap")
-		return answer, nil
-	}
-
-	var externalPlugins []ExternalPlugin
-	err = yaml.Unmarshal([]byte(text), &externalPlugins)
-	if err != nil {
-		return answer, errors.Wrapf(err, "failed to unmarshal external plugin configuration")
-	}
-
-	for _, p := range externalPlugins {
-		if util.StringArrayIndex(answer, p.Name) >= 0 {
-			continue
-		}
-		for _, r := range p.RequiredResources {
-			exists, err := CheckResourceExists(ctx, client, namespace, r)
-			if err != nil {
-				return answer, errors.Wrapf(err, "failed to check if resource exists %s", r.String())
-			}
-			if !exists {
-				l.WithField("ExternalPlugin", p.Name).Infof("disabling external plugin as resource is not available %s", r.String())
-				answer = append(answer, p.Name)
-				break
-			}
-		}
-	}
-	return answer, nil
-}
-
-// CheckResourceExists checks if a service exists
-func CheckResourceExists(ctx context.Context, client kubernetes.Interface, namespace string, r Resource) (bool, error) {
-	k := strings.ToLower(r.Kind)
-	ns := r.Namespace
-	if ns == "" {
-		ns = namespace
-	}
-	name := r.Name
-	if name == "" {
-		return true, nil
-	}
-	if k == "service" {
-		_, err := client.CoreV1().Services(ns).Get(ctx, name, metav1.GetOptions{})
-		if apierrors.IsNotFound(err) {
-			return false, nil
-		}
-		if err != nil {
-			return false, errors.Wrapf(err, "failed to find Service %s/%s", ns, name)
-		}
-		return true, nil
-	}
-	// TODO
-	return true, nil
-}
diff --git a/pkg/externalplugincfg/types.go b/pkg/externalplugincfg/types.go
deleted file mode 100644
index 228cd090..00000000
--- a/pkg/externalplugincfg/types.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package externalplugincfg
-
-const (
-	// ConfigMapName name of the config map for external plugins
-	ConfigMapName = "lighthouse-external-plugins"
-)
-
-// ExternalPlugin holds configuration for registering an external
-// plugin in prow.
-type ExternalPlugin struct {
-	// Name of the plugin.
-	Name string `json:"name"`
-	// RequiredResources the kubernetes resources required to enable this external plugin
-	RequiredResources []Resource `json:"requiredResources,omitempty"`
-}
-
-// Resource represents a kubernetes resource
-type Resource struct {
-	// Kind of the resource.
-	Kind string `json:"kind"`
-	// Name of the resource.
-	Name string `json:"name"`
-	// Namespace of the resource.
-	Namespace string `json:"namespace"`
-}
-
-func (r *Resource) String() string {
-	if r.Namespace != "" {
-		return r.Kind + "/" + r.Namespace + "/" + r.Name
-	}
-	return r.Kind + "/" + r.Name
-}
diff --git a/pkg/filebrowser/fake/fake_file_browser.go b/pkg/filebrowser/fake/fake_file_browser.go
index 6a40f1d5..57f1fd7f 100644
--- a/pkg/filebrowser/fake/fake_file_browser.go
+++ b/pkg/filebrowser/fake/fake_file_browser.go
@@ -1,11 +1,10 @@
 package fake
 
 import (
+	"github.com/jenkins-x/lighthouse/pkg/util"
 	"io/ioutil"
 	"path/filepath"
 
-	"github.com/jenkins-x/lighthouse/pkg/util"
-
 	"github.com/jenkins-x/go-scm/scm"
 	"github.com/jenkins-x/lighthouse/pkg/filebrowser"
 	"github.com/pkg/errors"
@@ -28,13 +27,13 @@ func (f *fakeFileBrowser) GetMainAndCurrentBranchRefs(owner, repo, ref string) (
 	return f.mainAndCurrentBranchRefs, nil
 }
 
-func (f *fakeFileBrowser) GetFile(owner, repo, path, ref string, fc filebrowser.FetchCache) ([]byte, error) {
+func (f *fakeFileBrowser) GetFile(owner, repo, path, ref string) ([]byte, error) {
 	fileName := filepath.Join(f.dir, path)
 	/* #nosec */
 	return ioutil.ReadFile(fileName)
 }
 
-func (f *fakeFileBrowser) ListFiles(owner, repo, path, ref string, fc filebrowser.FetchCache) ([]*scm.FileEntry, error) {
+func (f *fakeFileBrowser) ListFiles(owner, repo, path, ref string) ([]*scm.FileEntry, error) {
 	dir := filepath.Join(f.dir, path)
 	exists, err := util.DirExists(dir)
 	if err != nil {
diff --git a/pkg/filebrowser/fetch_cache.go b/pkg/filebrowser/fetch_cache.go
deleted file mode 100644
index 8220053b..00000000
--- a/pkg/filebrowser/fetch_cache.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package filebrowser
-
-import "sync"
-
-// FetchCache whether or not we should fetch the given repo ref
-// we only need to fetch a given repo ref once per webhook request
-type FetchCache interface {
-	// ShouldFetch returns true if we should fetch for the given owner, repo and ref
-	ShouldFetch(fullName, ref string) bool
-}
-
-// NewFetchCache creates a default fetch cache
-func NewFetchCache() FetchCache {
-	return &defaultFetchCache{fetched: map[string]bool{}}
-}
-
-type defaultFetchCache struct {
-	lock    sync.RWMutex
-	fetched map[string]bool
-}
-
-// ShouldFetch returns true if we should fetch for the given owner, repo and ref
-func (f *defaultFetchCache) ShouldFetch(fullName, ref string) bool {
-	key := fullName + "@" + ref
-
-	f.lock.Lock()
-
-	answer := false
-	if !f.fetched[key] {
-		answer = true
-		f.fetched[key] = true
-	}
-	f.lock.Unlock()
-	return answer
-}
diff --git a/pkg/filebrowser/git_file_browser.go b/pkg/filebrowser/git_file_browser.go
index 17df05c6..ac3b3d06 100644
--- a/pkg/filebrowser/git_file_browser.go
+++ b/pkg/filebrowser/git_file_browser.go
@@ -1,39 +1,31 @@
 package filebrowser
 
 import (
+	"github.com/jenkins-x/lighthouse/pkg/util"
 	"io/ioutil"
 	"os/exec"
 	"path/filepath"
-	"regexp"
 	"strings"
 	"sync"
 
 	"github.com/jenkins-x/go-scm/scm"
 	"github.com/jenkins-x/lighthouse/pkg/git/v2"
-	"github.com/jenkins-x/lighthouse/pkg/util"
 	"github.com/pkg/errors"
-	"github.com/sirupsen/logrus"
 )
 
 type gitFileBrowser struct {
 	clientFactory git.ClientFactory
 	clientsLock   sync.RWMutex
 	clients       map[string]*repoClientFacade
-	pullTimes     map[string]int64
 }
 
 const headBranchPrefix = "HEAD branch:"
 
-var (
-	shaRegex = regexp.MustCompile("\\b[0-9a-f]{7,40}\\b")
-)
-
 // NewFileBrowserFromGitClient creates a new file browser from an Scm client
 func NewFileBrowserFromGitClient(clientFactory git.ClientFactory) Interface {
 	return &gitFileBrowser{
 		clientFactory: clientFactory,
 		clients:       map[string]*repoClientFacade{},
-		pullTimes:     map[string]int64{},
 	}
 }
 
@@ -41,8 +33,8 @@ func (f *gitFileBrowser) GetMainAndCurrentBranchRefs(_, _, eventRef string) ([]s
 	return []string{"", eventRef}, nil
 }
 
-func (f *gitFileBrowser) GetFile(owner, repo, path, ref string, fc FetchCache) (answer []byte, err error) {
-	err = f.withRepoClient(owner, repo, ref, fc, func(repoClient git.RepoClient) error {
+func (f *gitFileBrowser) GetFile(owner, repo, path, ref string) (answer []byte, err error) {
+	err = f.withRepoClient(owner, repo, ref, func(repoClient git.RepoClient) error {
 		f := repoPath(repoClient, path)
 		var err error
 		answer, err = ioutil.ReadFile(f) // #nosec
@@ -51,8 +43,8 @@ func (f *gitFileBrowser) GetFile(owner, repo, path, ref string, fc FetchCache) (
 	return
 }
 
-func (f *gitFileBrowser) ListFiles(owner, repo, path, ref string, fc FetchCache) (answer []*scm.FileEntry, err error) {
-	err = f.withRepoClient(owner, repo, ref, fc, func(repoClient git.RepoClient) error {
+func (f *gitFileBrowser) ListFiles(owner, repo, path, ref string) (answer []*scm.FileEntry, err error) {
+	err = f.withRepoClient(owner, repo, ref, func(repoClient git.RepoClient) error {
 		dir := repoPath(repoClient, path)
 		exists, err := util.DirExists(dir)
 		if err != nil {
@@ -97,7 +89,7 @@ func repoPath(repoClient git.RepoClient, path string) string {
 	return filepath.Join(dir, path)
 }
 
-func (f *gitFileBrowser) withRepoClient(owner, repo, ref string, fc FetchCache, fn func(repoClient git.RepoClient) error) error {
+func (f *gitFileBrowser) withRepoClient(owner, repo, ref string, fn func(repoClient git.RepoClient) error) error {
 	client := f.getOrCreateClient(owner, repo)
 
 	var repoClient git.RepoClient
@@ -118,7 +110,7 @@ func (f *gitFileBrowser) withRepoClient(owner, repo, ref string, fc FetchCache,
 	}
 	if err == nil {
 		repoClient = client.repoClient
-		err = client.UseRef(ref, fc)
+		err = client.UseRef(ref)
 		if err != nil {
 			err = errors.Wrapf(err, "failed to switch to ref %s", ref)
 		}
@@ -157,13 +149,8 @@ type repoClientFacade struct {
 	ref        string
 }
 
-var (
-	// maxRefFetchSeconds number of seconds to reuse the git fetch to avoid slowing things down too much
-	maxRefFetchSeconds = int64(20)
-)
-
 // UseRef this method should only be used within the lock
-func (c *repoClientFacade) UseRef(ref string, fc FetchCache) error {
+func (c *repoClientFacade) UseRef(ref string) error {
 	ref = strings.TrimSpace(ref)
 	if ref == "" {
 		ref = c.mainBranch
@@ -173,31 +160,6 @@ func (c *repoClientFacade) UseRef(ref string, fc FetchCache) error {
 		ref = "origin/" + strings.TrimPrefix(ref, "refs/heads/")
 	}
 
-	shouldFetch := fc.ShouldFetch(c.fullName, ref)
-	if shouldFetch && IsSHA(ref) {
-		// lets check if we've already fetched this sha
-		sha, err := c.repoClient.HasSHA(ref)
-		if err == nil && sha != "" {
-			shouldFetch = false
-			logrus.StandardLogger().WithFields(map[string]interface{}{
-				"Name": c.fullName,
-				"Ref":  ref,
-				"File": "git_file_browser",
-			}).Info("not fetching ref as we already have it")
-		}
-	}
-	if shouldFetch {
-		logrus.StandardLogger().WithFields(map[string]interface{}{
-			"Name": c.fullName,
-			"Ref":  ref,
-			"File": "git_file_browser",
-		}).Info("fetching ref")
-	}
-
-	if c.ref == ref && !shouldFetch {
-		return nil
-	}
-
 	// lets switch to the main branch first before we go to a custom sha/ref
 	if c.ref != "" && c.ref != c.mainBranch {
 		err := c.repoClient.Checkout(c.mainBranch)
@@ -206,17 +168,15 @@ func (c *repoClientFacade) UseRef(ref string, fc FetchCache) error {
 		}
 	}
 
-	if shouldFetch {
-		if ref != c.mainBranch {
-			err := c.repoClient.FetchRef(ref)
-			if err != nil {
-				return errors.Wrapf(err, "failed to fetch repository %s", c.fullName)
-			}
-		} else {
-			err := c.repoClient.Fetch()
-			if err != nil {
-				return errors.Wrapf(err, "failed to fetch repository %s", c.fullName)
-			}
+	if ref != c.mainBranch {
+		err := c.repoClient.FetchRef(ref)
+		if err != nil {
+			return errors.Wrapf(err, "failed to fetch repository %s", c.fullName)
+		}
+	} else {
+		err := c.repoClient.Fetch()
+		if err != nil {
+			return errors.Wrapf(err, "failed to fetch repository %s", c.fullName)
 		}
 	}
 	c.ref = ref
@@ -263,8 +223,3 @@ func runCmd(dir, cmd string, arg ...string) (string, error) {
 	}
 	return text, nil
 }
-
-// IsSHA returns true if the given ref is a git sha
-func IsSHA(ref string) bool {
-	return shaRegex.MatchString(ref)
-}
diff --git a/pkg/filebrowser/interface.go b/pkg/filebrowser/interface.go
index 482d229e..561560e0 100644
--- a/pkg/filebrowser/interface.go
+++ b/pkg/filebrowser/interface.go
@@ -8,8 +8,8 @@ type Interface interface {
 	GetMainAndCurrentBranchRefs(owner, repo, ref string) ([]string, error)
 
 	// GetFile returns a file from the given path in the repository with the given sha
-	GetFile(owner, repo, path, ref string, fc FetchCache) ([]byte, error)
+	GetFile(owner, repo, path, ref string) ([]byte, error)
 
 	// ListFiles returns the file and directory entries in the given path in the repository with the given sha
-	ListFiles(owner, repo, path, ref string, fc FetchCache) ([]*scm.FileEntry, error)
+	ListFiles(owner, repo, path, ref string) ([]*scm.FileEntry, error)
 }
diff --git a/pkg/filebrowser/scm_file_browser.go b/pkg/filebrowser/scm_file_browser.go
index 62ea0c8f..301f71ff 100644
--- a/pkg/filebrowser/scm_file_browser.go
+++ b/pkg/filebrowser/scm_file_browser.go
@@ -37,10 +37,10 @@ func (f *scmFileBrowser) GetMainAndCurrentBranchRefs(owner, repo, eventRef strin
 	return refs, nil
 }
 
-func (f *scmFileBrowser) GetFile(owner, repo, path, ref string, fc FetchCache) ([]byte, error) {
+func (f *scmFileBrowser) GetFile(owner, repo, path, ref string) ([]byte, error) {
 	return f.scmClient.GetFile(owner, repo, path, ref)
 }
 
-func (f *scmFileBrowser) ListFiles(owner, repo, path, ref string, fc FetchCache) ([]*scm.FileEntry, error) {
+func (f *scmFileBrowser) ListFiles(owner, repo, path, ref string) ([]*scm.FileEntry, error) {
 	return f.scmClient.ListFiles(owner, repo, path, ref)
 }
diff --git a/pkg/foghorn/controller.go b/pkg/foghorn/controller.go
index 7cdf819c..08f971e9 100644
--- a/pkg/foghorn/controller.go
+++ b/pkg/foghorn/controller.go
@@ -236,7 +236,7 @@ func (r *LighthouseJobReconciler) reportStatus(activity *lighthousev1alpha1.Acti
 	}
 
 	// Trigger external plugins if appropriate
-	if external := util.ExternalPluginsForEvent(r.pluginConfig, util.LighthousePayloadTypeActivity, fmt.Sprintf("%s/%s", owner, repo), nil); len(external) > 0 {
+	if external := util.ExternalPluginsForEvent(r.pluginConfig, util.LighthousePayloadTypeActivity, fmt.Sprintf("%s/%s", owner, repo)); len(external) > 0 {
 		go util.CallExternalPluginsWithActivityRecord(r.logger, external, activity, util.HMACToken(), r.wg)
 	}
 
diff --git a/pkg/git/v2/interactor.go b/pkg/git/v2/interactor.go
index 5ce23901..71b3f915 100644
--- a/pkg/git/v2/interactor.go
+++ b/pkg/git/v2/interactor.go
@@ -66,8 +66,6 @@ type Interactor interface {
 	MergeCommitsExistBetween(target, head string) (bool, error)
 	// ShowRef returns the commit for a commitlike. Unlike rev-parse it does not require a checkout.
 	ShowRef(commitlike string) (string, error)
-	// HasSHA checks if a ref is a sha we have fetched locally
-	HasSHA(ref string) (string, error)
 }
 
 // cacher knows how to cache and update repositories in a central cache
@@ -377,12 +375,3 @@ func (i *interactor) ShowRef(commitlike string) (string, error) {
 	}
 	return strings.TrimSpace(string(out)), nil
 }
-
-func (i *interactor) HasSHA(ref string) (string, error) {
-	i.logger.Infof("Checking if %s is a fetched SHA", ref)
-	out, err := i.executor.Run("cat-file", "commit", ref)
-	if err != nil {
-		return "", fmt.Errorf("failed to verify ref is a sha: %s: %v", ref, err)
-	}
-	return strings.TrimSpace(string(out)), nil
-}
diff --git a/pkg/keeper/githubapp/factory.go b/pkg/keeper/githubapp/factory.go
index 56dca74a..44cd4f31 100644
--- a/pkg/keeper/githubapp/factory.go
+++ b/pkg/keeper/githubapp/factory.go
@@ -27,7 +27,7 @@ func NewKeeperController(configAgent *config.Agent, botName string, gitKind stri
 
 	var scmClient *scm.Client
 	var err error
-	if gitKind == "gitea" {
+	if gitKind == "gitea" || gitKind == "bitbucketcloud" {
 		// gitea returns 403 if the gitToken isn't passed here
 		scmClient, err = factory.NewClient(gitKind, serverURL, gitToken, factory.SetUsername(botName))
 	} else {
diff --git a/pkg/keeper/keeper.go b/pkg/keeper/keeper.go
index 17e837c6..325e3777 100644
--- a/pkg/keeper/keeper.go
+++ b/pkg/keeper/keeper.go
@@ -1369,8 +1369,7 @@ func (c *DefaultController) presubmitsByPull(sp *subpool) (map[int][]job.Presubm
 	repo := sp.repo
 	sharedConfig := c.config()
 	cache := inrepo.NewResolverCache()
-	fc := filebrowser.NewFetchCache()
-	cfg, _, err := inrepo.Generate(c.fileBrowsers, fc, cache, sharedConfig, nil, owner, repo, "")
+	cfg, _, err := inrepo.Generate(c.fileBrowsers, cache, sharedConfig, nil, owner, repo, "")
 	if err != nil {
 		return nil, errors.Wrapf(err, "failed to calculate in repo config")
 	}
diff --git a/pkg/plugins/updateconfig/updateconfig.go b/pkg/plugins/updateconfig/updateconfig.go
index 760877ed..97f67e35 100644
--- a/pkg/plugins/updateconfig/updateconfig.go
+++ b/pkg/plugins/updateconfig/updateconfig.go
@@ -266,7 +266,7 @@ func handle(spc scmProviderClient, kc corev1.ConfigMapsGetter, cp commentPruner,
 	isUpdate := false
 
 	switch pre.Action {
-	case scm.ActionClose, scm.ActionMerge:
+	case scm.ActionClose:
 		isMerge = true
 	case scm.ActionOpen, scm.ActionReopen, scm.ActionSync:
 		isUpdate = true
diff --git a/pkg/triggerconfig/inrepo/calculate.go b/pkg/triggerconfig/inrepo/calculate.go
index 4c7f86d9..02033bbd 100644
--- a/pkg/triggerconfig/inrepo/calculate.go
+++ b/pkg/triggerconfig/inrepo/calculate.go
@@ -10,7 +10,7 @@ import (
 )
 
 // Generate generates the in repository config if enabled for this repository otherwise return the shared config
-func Generate(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.FetchCache, cache *ResolverCache, sharedConfig *config.Config, sharedPlugins *plugins.Configuration, owner, repo, eventRef string) (*config.Config, *plugins.Configuration, error) {
+func Generate(fileBrowsers *filebrowser.FileBrowsers, cache *ResolverCache, sharedConfig *config.Config, sharedPlugins *plugins.Configuration, owner, repo, eventRef string) (*config.Config, *plugins.Configuration, error) {
 	fullName := scm.Join(owner, repo)
 	if !sharedConfig.InRepoConfigEnabled(fullName) {
 		return sharedConfig, sharedPlugins, nil
@@ -38,7 +38,7 @@ func Generate(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.FetchCache,
 	}
 
 	for _, ref := range refs {
-		repoConfig, err := LoadTriggerConfig(fileBrowsers, fc, cache, owner, repo, ref)
+		repoConfig, err := LoadTriggerConfig(fileBrowsers, cache, owner, repo, ref)
 		if err != nil {
 			return sharedConfig, sharedPlugins, errors.Wrapf(err, "failed to load trigger config for repository %s/%s for ref %s", owner, repo, ref)
 		}
diff --git a/pkg/triggerconfig/inrepo/load_triggers.go b/pkg/triggerconfig/inrepo/load_triggers.go
index 2f36be51..f32dea53 100644
--- a/pkg/triggerconfig/inrepo/load_triggers.go
+++ b/pkg/triggerconfig/inrepo/load_triggers.go
@@ -22,8 +22,8 @@ import (
 )
 
 // MergeTriggers merges the configuration with any `lighthouse.yaml` files in the repository
-func MergeTriggers(cfg *config.Config, pluginCfg *plugins.Configuration, fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.FetchCache, cache *ResolverCache, ownerName string, repoName string, sha string) (bool, error) {
-	repoConfig, err := LoadTriggerConfig(fileBrowsers, fc, cache, ownerName, repoName, sha)
+func MergeTriggers(cfg *config.Config, pluginCfg *plugins.Configuration, fileBrowsers *filebrowser.FileBrowsers, cache *ResolverCache, ownerName string, repoName string, sha string) (bool, error) {
+	repoConfig, err := LoadTriggerConfig(fileBrowsers, cache, ownerName, repoName, sha)
 	if err != nil {
 		return false, errors.Wrap(err, "failed to load configs")
 	}
@@ -39,17 +39,17 @@ func MergeTriggers(cfg *config.Config, pluginCfg *plugins.Configuration, fileBro
 }
 
 // LoadTriggerConfig loads the `lighthouse.yaml` configuration files in the repository
-func LoadTriggerConfig(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.FetchCache, cache *ResolverCache, ownerName string, repoName string, sha string) (*triggerconfig.Config, error) {
+func LoadTriggerConfig(fileBrowsers *filebrowser.FileBrowsers, cache *ResolverCache, ownerName string, repoName string, sha string) (*triggerconfig.Config, error) {
 	m := map[string]*triggerconfig.Config{}
 	path := ".lighthouse"
-	files, err := fileBrowsers.LighthouseGitFileBrowser().ListFiles(ownerName, repoName, path, sha, fc)
+	files, err := fileBrowsers.LighthouseGitFileBrowser().ListFiles(ownerName, repoName, path, sha)
 	if err != nil {
 		return nil, errors.Wrapf(err, "failed to find any lighthouse configuration files in repo %s/%s at sha %s", ownerName, repoName, sha)
 	}
 	for _, f := range files {
 		if isDirType(f.Type) {
 			filePath := path + "/" + f.Name + "/triggers.yaml"
-			cfg, err := loadConfigFile(fileBrowsers, fc, cache, ownerName, repoName, filePath, sha)
+			cfg, err := loadConfigFile(fileBrowsers, cache, ownerName, repoName, filePath, sha)
 			if err != nil {
 				return nil, errors.Wrapf(err, "failed to load file %s in %s/%s with sha %s", filePath, ownerName, repoName, sha)
 			}
@@ -58,7 +58,7 @@ func LoadTriggerConfig(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.Fe
 			}
 		} else if f.Name == "triggers.yaml" {
 			filePath := path + "/" + f.Name
-			cfg, err := loadConfigFile(fileBrowsers, fc, cache, ownerName, repoName, filePath, sha)
+			cfg, err := loadConfigFile(fileBrowsers, cache, ownerName, repoName, filePath, sha)
 			if err != nil {
 				return nil, errors.Wrapf(err, "failed to load file %s in %s/%s with sha %s", filePath, ownerName, repoName, sha)
 			}
@@ -107,8 +107,8 @@ func isDirType(t string) bool {
 	return strings.ToLower(t) == "dir"
 }
 
-func loadConfigFile(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.FetchCache, cache *ResolverCache, ownerName, repoName, path, sha string) (*triggerconfig.Config, error) {
-	data, err := fileBrowsers.LighthouseGitFileBrowser().GetFile(ownerName, repoName, path, sha, fc)
+func loadConfigFile(fileBrowsers *filebrowser.FileBrowsers, cache *ResolverCache, ownerName, repoName, path, sha string) (*triggerconfig.Config, error) {
+	data, err := fileBrowsers.LighthouseGitFileBrowser().GetFile(ownerName, repoName, path, sha)
 	if err != nil {
 		return nil, errors.Wrapf(err, "failed to find file %s in repo %s/%s with sha %s", path, ownerName, repoName, sha)
 	}
@@ -129,7 +129,7 @@ func loadConfigFile(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.Fetch
 			if err != nil {
 				sourcePath = filepath.Join(dir, r.SourcePath)
 			}
-			err = loadJobBaseFromSourcePath(fileBrowsers, fc, cache, &r.Base, ownerName, repoName, sourcePath, sha)
+			err = loadJobBaseFromSourcePath(fileBrowsers, cache, &r.Base, ownerName, repoName, sourcePath, sha)
 			if err != nil {
 				return nil, errors.Wrapf(err, "failed to load source for presubmit %s", r.Name)
 			}
@@ -147,7 +147,7 @@ func loadConfigFile(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.Fetch
 			if err != nil {
 				sourcePath = filepath.Join(dir, r.SourcePath)
 			}
-			err = loadJobBaseFromSourcePath(fileBrowsers, fc, cache, &r.Base, ownerName, repoName, sourcePath, sha)
+			err = loadJobBaseFromSourcePath(fileBrowsers, cache, &r.Base, ownerName, repoName, sourcePath, sha)
 			if err != nil {
 				return nil, errors.Wrapf(err, "failed to load source for postsubmit %s", r.Name)
 			}
@@ -159,7 +159,7 @@ func loadConfigFile(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.Fetch
 	return repoConfig, nil
 }
 
-func loadJobBaseFromSourcePath(fileBrowsers *filebrowser.FileBrowsers, fc filebrowser.FetchCache, cache *ResolverCache, j *job.Base, ownerName, repoName, path, sha string) error {
+func loadJobBaseFromSourcePath(fileBrowsers *filebrowser.FileBrowsers, cache *ResolverCache, j *job.Base, ownerName, repoName, path, sha string) error {
 	var data []byte
 
 	// source path can either be a local file or a Git URL
@@ -171,7 +171,7 @@ func loadJobBaseFromSourcePath(fileBrowsers *filebrowser.FileBrowsers, fc filebr
 		}
 
 	} else {
-		data, err = fileBrowsers.LighthouseGitFileBrowser().GetFile(ownerName, repoName, path, sha, fc)
+		data, err = fileBrowsers.LighthouseGitFileBrowser().GetFile(ownerName, repoName, path, sha)
 		if err != nil {
 			return errors.Wrapf(err, "failed to find file %s in repo %s/%s with sha %s", path, ownerName, repoName, sha)
 		}
@@ -187,7 +187,6 @@ func loadJobBaseFromSourcePath(fileBrowsers *filebrowser.FileBrowsers, fc filebr
 
 	usesResolver := &UsesResolver{
 		FileBrowsers: fileBrowsers,
-		FetchCache:   fc,
 		Cache:        cache,
 		OwnerName:    ownerName,
 		RepoName:     repoName,
diff --git a/pkg/triggerconfig/inrepo/uses_resolver.go b/pkg/triggerconfig/inrepo/uses_resolver.go
index 029a3f9f..98a13e20 100644
--- a/pkg/triggerconfig/inrepo/uses_resolver.go
+++ b/pkg/triggerconfig/inrepo/uses_resolver.go
@@ -20,7 +20,6 @@ import (
 // UsesResolver resolves the `uses:` URI syntax
 type UsesResolver struct {
 	FileBrowsers     *filebrowser.FileBrowsers
-	FetchCache       filebrowser.FetchCache
 	Cache            *ResolverCache
 	OwnerName        string
 	RepoName         string
@@ -144,7 +143,7 @@ func (r *UsesResolver) GetData(path string, ignoreNotExist bool) ([]byte, error)
 			return nil, errors.Errorf("could not find git file browser for server %s in uses: git URI %s", gitURI.Server, gitURI.String())
 		}
 	}
-	data, err = fb.GetFile(owner, repo, path, sha, r.FetchCache)
+	data, err = fb.GetFile(owner, repo, path, sha)
 	if err != nil && IsScmNotFound(err) {
 		err = nil
 	}
diff --git a/pkg/util/externalplugins.go b/pkg/util/externalplugins.go
index e9781250..c9b7380b 100644
--- a/pkg/util/externalplugins.go
+++ b/pkg/util/externalplugins.go
@@ -251,7 +251,7 @@ func dispatch(endpoint string, payload []byte, h http.Header) error {
 
 // ExternalPluginsForEvent returns whether there are any external plugins that need to
 // get the present event.
-func ExternalPluginsForEvent(pluginConfig *plugins.ConfigAgent, eventKind string, srcRepo string, disabledExternalPlugins []string) []plugins.ExternalPlugin {
+func ExternalPluginsForEvent(pluginConfig *plugins.ConfigAgent, eventKind string, srcRepo string) []plugins.ExternalPlugin {
 	var matching []plugins.ExternalPlugin
 	if pluginConfig.Config() == nil {
 		return matching
@@ -267,9 +267,6 @@ func ExternalPluginsForEvent(pluginConfig *plugins.ConfigAgent, eventKind string
 
 		// Make sure the events match
 		for _, p := range extPlugins {
-			if StringArrayIndex(disabledExternalPlugins, p.Name) >= 0 {
-				continue
-			}
 			if len(p.Events) == 0 {
 				matching = append(matching, p)
 			} else {
diff --git a/pkg/util/strings.go b/pkg/util/strings.go
deleted file mode 100644
index 3768c4ca..00000000
--- a/pkg/util/strings.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package util
-
-// StringArrayIndex returns the index in the slice which equals the given value
-func StringArrayIndex(array []string, value string) int {
-	for i, v := range array {
-		if v == value {
-			return i
-		}
-	}
-	return -1
-}
diff --git a/pkg/webhook/create_agent.go b/pkg/webhook/create_agent.go
index 5517dce8..ddd052c8 100644
--- a/pkg/webhook/create_agent.go
+++ b/pkg/webhook/create_agent.go
@@ -18,9 +18,6 @@ package webhook
 
 import (
 	"strings"
-	"time"
-
-	"github.com/jenkins-x/lighthouse/pkg/filebrowser"
 
 	"github.com/jenkins-x/go-scm/scm"
 	"github.com/jenkins-x/lighthouse/pkg/plugins"
@@ -33,7 +30,6 @@ import (
 // if the repository is configured to use in repository configuration then we create the use the repository specific
 // configuration
 func (s *Server) CreateAgent(l *logrus.Entry, owner, repo, ref string) (plugins.Agent, error) {
-	start := time.Now()
 	pc := plugins.NewAgent(s.ConfigAgent, s.Plugins, s.ClientAgent, s.ServerURL, l)
 	fullName := scm.Join(owner, repo)
 	if pc.Config == nil {
@@ -64,16 +60,13 @@ func (s *Server) CreateAgent(l *logrus.Entry, owner, repo, ref string) (plugins.
 		return pc, errors.Wrapf(err, "failed to create agent")
 	}
 	c.Add(key, &pc)
-	duration := time.Now().Sub(start)
-	l.WithField("Duration", duration.String()).Info("created configAgent")
 	return pc, nil
 }
 
 func (s *Server) createAgent(pc *plugins.Agent, owner, repo, ref string) error {
 	var err error
 	cache := inrepo.NewResolverCache()
-	fc := filebrowser.NewFetchCache()
-	pc.Config, pc.PluginConfig, err = inrepo.Generate(s.FileBrowsers, fc, cache, pc.Config, pc.PluginConfig, owner, repo, ref)
+	pc.Config, pc.PluginConfig, err = inrepo.Generate(s.FileBrowsers, cache, pc.Config, pc.PluginConfig, owner, repo, ref)
 	if err != nil {
 		return errors.Wrapf(err, "failed to calculate in repo config")
 	}
diff --git a/pkg/webhook/events.go b/pkg/webhook/events.go
index bfde8367..b91bbb6f 100644
--- a/pkg/webhook/events.go
+++ b/pkg/webhook/events.go
@@ -127,23 +127,16 @@ func (s *Server) handlePullRequestCommentEvent(l *logrus.Entry, pc scm.PullReque
 }
 
 func (s *Server) handleGenericComment(l *logrus.Entry, ce *scmprovider.GenericCommentEvent) {
-	// lets invoke the agent creation async as this can take a little while
-	go func() {
-		agent, err := s.CreateAgent(l, ce.Repo.Namespace, ce.Repo.Name, ce.HeadSha)
-		if err != nil {
-			agent.Logger.WithError(err).Error("Error creating agent for GenericCommentEvent.")
-			return
-		}
-		agent.InitializeCommentPruner(
-			ce.Repo.Namespace,
-			ce.Repo.Name,
-			ce.Number,
-		)
-		s.handleGenericCommentWithAgent(l, ce, agent)
-	}()
-}
-
-func (s *Server) handleGenericCommentWithAgent(l *logrus.Entry, ce *scmprovider.GenericCommentEvent, agent plugins.Agent) {
+	agent, err := s.CreateAgent(l, ce.Repo.Namespace, ce.Repo.Name, ce.HeadSha)
+	if err != nil {
+		agent.Logger.WithError(err).Error("Error creating agent for GenericCommentEvent.")
+		return
+	}
+	agent.InitializeCommentPruner(
+		ce.Repo.Namespace,
+		ce.Repo.Name,
+		ce.Number,
+	)
 	for p, h := range s.getPlugins(ce.Repo.Namespace, ce.Repo.Name) {
 		if h.GenericCommentHandler != nil {
 			s.wg.Add(1)
@@ -182,33 +175,29 @@ func (s *Server) handlePushEvent(l *logrus.Entry, pe *scm.PushHook) {
 		"head":                   pe.After,
 	})
 	l.Info("Push event.")
-
-	// lets invoke the agent creation async as this can take a little while
-	go func() {
-		c := 0
-		ref := pe.After
-		if ref == "" {
-			ref = pe.Ref
-		}
-		agent, err := s.CreateAgent(l, repo.Namespace, repo.Name, ref)
-		if err != nil {
-			agent.Logger.WithError(err).Error("Error creating agent for PushEvent.")
-			return
-		}
-		for p, h := range s.getPlugins(pe.Repo.Namespace, pe.Repo.Name) {
-			if h.PushEventHandler != nil {
-				s.wg.Add(1)
-				c++
-				go func(p string, h plugins.PushEventHandler) {
-					defer s.wg.Done()
-					if err := h(agent, *pe); err != nil {
-						agent.Logger.WithError(err).Error("Error handling PushEvent.")
-					}
-				}(p, h.PushEventHandler)
-			}
+	c := 0
+	ref := pe.After
+	if ref == "" {
+		ref = pe.Ref
+	}
+	agent, err := s.CreateAgent(l, repo.Namespace, repo.Name, ref)
+	if err != nil {
+		agent.Logger.WithError(err).Error("Error creating agent for PushEvent.")
+		return
+	}
+	for p, h := range s.getPlugins(pe.Repo.Namespace, pe.Repo.Name) {
+		if h.PushEventHandler != nil {
+			s.wg.Add(1)
+			c++
+			go func(p string, h plugins.PushEventHandler) {
+				defer s.wg.Done()
+				if err := h(agent, *pe); err != nil {
+					agent.Logger.WithError(err).Error("Error handling PushEvent.")
+				}
+			}(p, h.PushEventHandler)
 		}
-		l.WithField("count", strconv.Itoa(c)).Info("number of push handlers")
-	}()
+	}
+	l.WithField("count", strconv.Itoa(c)).Info("number of push handlers")
 }
 
 func (s *Server) handlePullRequestEvent(l *logrus.Entry, pr *scm.PullRequestHook) {
@@ -221,65 +210,60 @@ func (s *Server) handlePullRequestEvent(l *logrus.Entry, pr *scm.PullRequestHook
 	})
 	action := pr.Action
 	l.Infof("Pull request %s.", action)
+	c := 0
+	repo := pr.PullRequest.Base.Repo
+	if repo.Name == "" {
+		repo = pr.Repo
+	}
+	agent, err := s.CreateAgent(l, repo.Namespace, repo.Name, pr.PullRequest.Sha)
+	if err != nil {
+		agent.Logger.WithError(err).Error("Error creating agent for PullRequestEvent.")
 
-	// lets invoke the agent creation async as this can take a little while
-	go func() {
-		c := 0
-		repo := pr.PullRequest.Base.Repo
-		if repo.Name == "" {
-			repo = pr.Repo
-		}
-		agent, err := s.CreateAgent(l, repo.Namespace, repo.Name, pr.PullRequest.Sha)
-		if err != nil {
-			agent.Logger.WithError(err).Error("Error creating agent for PullRequestEvent.")
-
-			// the error could be related to a bad local triggers.yaml change so lets comment on the Pull Request
-			s.reportErrorToPullRequest(l, agent, repo, pr, err)
-			return
-		}
-		agent.InitializeCommentPruner(
-			pr.Repo.Namespace,
-			pr.Repo.Name,
-			pr.PullRequest.Number,
-		)
-		for p, h := range s.getPlugins(repo.Namespace, repo.Name) {
-			if h.PullRequestHandler != nil {
-				s.wg.Add(1)
-				c++
-				go func(p string, h plugins.PullRequestHandler) {
-					defer s.wg.Done()
-					if err := h(agent, *pr); err != nil {
-						agent.Logger.WithError(err).Error("Error handling PullRequestEvent.")
-					}
-				}(p, h.PullRequestHandler)
-			}
+		// the error could be related to a bad local triggers.yaml change so lets comment on the Pull Request
+		s.reportErrorToPullRequest(l, agent, repo, pr, err)
+		return
+	}
+	agent.InitializeCommentPruner(
+		pr.Repo.Namespace,
+		pr.Repo.Name,
+		pr.PullRequest.Number,
+	)
+	for p, h := range s.getPlugins(repo.Namespace, repo.Name) {
+		if h.PullRequestHandler != nil {
+			s.wg.Add(1)
+			c++
+			go func(p string, h plugins.PullRequestHandler) {
+				defer s.wg.Done()
+				if err := h(agent, *pr); err != nil {
+					agent.Logger.WithError(err).Error("Error handling PullRequestEvent.")
+				}
+			}(p, h.PullRequestHandler)
 		}
-		l.WithField("count", strconv.Itoa(c)).Info("number of PR handlers")
+	}
+	l.WithField("count", strconv.Itoa(c)).Info("number of PR handlers")
 
-		if !actionRelatesToPullRequestComment(action, l) {
-			return
-		}
-		s.handleGenericCommentWithAgent(
-			l,
-			&scmprovider.GenericCommentEvent{
-				GUID:        pr.GUID,
-				IsPR:        true,
-				Action:      action,
-				Body:        pr.PullRequest.Body,
-				Link:        pr.PullRequest.Link,
-				Number:      pr.PullRequest.Number,
-				Repo:        pr.Repo,
-				Author:      pr.PullRequest.Author,
-				IssueAuthor: pr.PullRequest.Author,
-				Assignees:   pr.PullRequest.Assignees,
-				IssueState:  pr.PullRequest.State,
-				IssueBody:   pr.PullRequest.Body,
-				IssueLink:   pr.PullRequest.Link,
-				HeadSha:     pr.PullRequest.Head.Sha,
-			},
-			agent,
-		)
-	}()
+	if !actionRelatesToPullRequestComment(action, l) {
+		return
+	}
+	s.handleGenericComment(
+		l,
+		&scmprovider.GenericCommentEvent{
+			GUID:        pr.GUID,
+			IsPR:        true,
+			Action:      action,
+			Body:        pr.PullRequest.Body,
+			Link:        pr.PullRequest.Link,
+			Number:      pr.PullRequest.Number,
+			Repo:        pr.Repo,
+			Author:      pr.PullRequest.Author,
+			IssueAuthor: pr.PullRequest.Author,
+			Assignees:   pr.PullRequest.Assignees,
+			IssueState:  pr.PullRequest.State,
+			IssueBody:   pr.PullRequest.Body,
+			IssueLink:   pr.PullRequest.Link,
+			HeadSha:     pr.PullRequest.Head.Sha,
+		},
+	)
 }
 
 // handleBranchEvent handles a branch event
@@ -298,57 +282,52 @@ func (s *Server) handleReviewEvent(l *logrus.Entry, re scm.ReviewHook) {
 		"url":                    re.Review.Link,
 	})
 	l.Infof("Review %s.", re.Action)
-
-	// lets invoke the agent creation async as this can take a little while
-	go func() {
-		repo := re.PullRequest.Base.Repo
-		agent, err := s.CreateAgent(l, repo.Namespace, repo.Name, re.PullRequest.Sha)
-		if err != nil {
-			agent.Logger.WithError(err).Error("Error creating agent for ReviewEvent.")
-			return
-		}
-		agent.InitializeCommentPruner(
-			re.Repo.Namespace,
-			re.Repo.Name,
-			re.PullRequest.Number,
-		)
-		for p, h := range s.getPlugins(re.PullRequest.Base.Repo.Namespace, re.PullRequest.Base.Repo.Name) {
-			if h.ReviewEventHandler != nil {
-				s.wg.Add(1)
-				go func(p string, h plugins.ReviewEventHandler) {
-					defer s.wg.Done()
-					if err := h(agent, re); err != nil {
-						agent.Logger.WithError(err).Error("Error handling ReviewEvent.")
-					}
-				}(p, h.ReviewEventHandler)
-			}
+	repo := re.PullRequest.Base.Repo
+	agent, err := s.CreateAgent(l, repo.Namespace, repo.Name, re.PullRequest.Sha)
+	if err != nil {
+		agent.Logger.WithError(err).Error("Error creating agent for ReviewEvent.")
+		return
+	}
+	agent.InitializeCommentPruner(
+		re.Repo.Namespace,
+		re.Repo.Name,
+		re.PullRequest.Number,
+	)
+	for p, h := range s.getPlugins(re.PullRequest.Base.Repo.Namespace, re.PullRequest.Base.Repo.Name) {
+		if h.ReviewEventHandler != nil {
+			s.wg.Add(1)
+			go func(p string, h plugins.ReviewEventHandler) {
+				defer s.wg.Done()
+				if err := h(agent, re); err != nil {
+					agent.Logger.WithError(err).Error("Error handling ReviewEvent.")
+				}
+			}(p, h.ReviewEventHandler)
 		}
+	}
 
-		action := re.Action
-		if !actionRelatesToPullRequestComment(action, l) {
-			return
-		}
-		s.handleGenericCommentWithAgent(
-			l,
-			&scmprovider.GenericCommentEvent{
-				GUID:        re.GUID,
-				IsPR:        true,
-				Action:      action,
-				Body:        re.Review.Body,
-				Link:        re.Review.Link,
-				Number:      re.PullRequest.Number,
-				Repo:        re.Repo,
-				Author:      re.Review.Author,
-				IssueAuthor: re.PullRequest.Author,
-				Assignees:   re.PullRequest.Assignees,
-				IssueState:  re.PullRequest.State,
-				IssueBody:   re.PullRequest.Body,
-				IssueLink:   re.PullRequest.Link,
-				HeadSha:     re.PullRequest.Head.Sha,
-			},
-			agent,
-		)
-	}()
+	action := re.Action
+	if !actionRelatesToPullRequestComment(action, l) {
+		return
+	}
+	s.handleGenericComment(
+		l,
+		&scmprovider.GenericCommentEvent{
+			GUID:        re.GUID,
+			IsPR:        true,
+			Action:      action,
+			Body:        re.Review.Body,
+			Link:        re.Review.Link,
+			Number:      re.PullRequest.Number,
+			Repo:        re.Repo,
+			Author:      re.Review.Author,
+			IssueAuthor: re.PullRequest.Author,
+			Assignees:   re.PullRequest.Assignees,
+			IssueState:  re.PullRequest.State,
+			IssueBody:   re.PullRequest.Body,
+			IssueLink:   re.PullRequest.Link,
+			HeadSha:     re.PullRequest.Head.Sha,
+		},
+	)
 }
 
 func (s *Server) reportErrorToPullRequest(l *logrus.Entry, agent plugins.Agent, repo scm.Repository, pr *scm.PullRequestHook, err error) {
@@ -376,7 +355,6 @@ func actionRelatesToPullRequestComment(action scm.Action, l *logrus.Entry) bool
 		scm.ActionLabel,
 		scm.ActionUnlabel,
 		scm.ActionClose,
-		scm.ActionMerge,
 		scm.ActionReopen,
 		scm.ActionSync:
 		return false
diff --git a/pkg/webhook/webhook.go b/pkg/webhook/webhook.go
index 8d9e9220..6433d839 100644
--- a/pkg/webhook/webhook.go
+++ b/pkg/webhook/webhook.go
@@ -3,7 +3,6 @@ package webhook
 import (
 	"bytes"
 	"fmt"
-	"github.com/jenkins-x/lighthouse/pkg/externalplugincfg"
 	"io/ioutil"
 	"net/http"
 	"net/url"
@@ -31,16 +30,15 @@ import (
 type WebhooksController struct {
 	ConfigMapWatcher *watcher.ConfigMapWatcher
 
-	path                    string
-	namespace               string
-	pluginFilename          string
-	configFilename          string
-	server                  *Server
-	botName                 string
-	gitServerURL            string
-	gitClient               git.Client
-	launcher                launcher.PipelineLauncher
-	disabledExternalPlugins []string
+	path           string
+	namespace      string
+	pluginFilename string
+	configFilename string
+	server         *Server
+	botName        string
+	gitServerURL   string
+	gitClient      git.Client
+	launcher       launcher.PipelineLauncher
 }
 
 // NewWebhooksController creates and configures the controller
@@ -244,22 +242,13 @@ func (o *WebhooksController) HandleWebhookRequests(w http.ResponseWriter, r *htt
 			return
 		}
 	}
-	entry := logrus.WithField("Webhook", webhook.Kind())
-	if o.disabledExternalPlugins == nil {
-		o.disabledExternalPlugins, err = externalplugincfg.LoadDisabledPlugins(entry, kubeClient, o.namespace)
-		if err != nil {
-			err = errors.Wrap(err, "failed to load disabled external plugins")
-			responseHTTPError(w, http.StatusInternalServerError, fmt.Sprintf("500 Internal Server Error: %s", err.Error()))
-			return
-		}
-	}
 
-	l, output, err := o.ProcessWebHook(entry, webhook)
+	l, output, err := o.ProcessWebHook(logrus.WithField("Webhook", webhook.Kind()), webhook)
 	if err != nil {
 		responseHTTPError(w, http.StatusInternalServerError, fmt.Sprintf("500 Internal Server Error: %s", err.Error()))
 	}
 	// Demux events only to external plugins that require this event.
-	if external := util.ExternalPluginsForEvent(o.server.Plugins, string(webhook.Kind()), webhook.Repository().FullName, o.disabledExternalPlugins); len(external) > 0 {
+	if external := util.ExternalPluginsForEvent(o.server.Plugins, string(webhook.Kind()), webhook.Repository().FullName); len(external) > 0 {
 		go util.CallExternalPluginsWithWebhook(l, external, webhook, util.HMACToken(), &o.server.wg)
 	}
 


Test patch:
diff --git a/pkg/config/job/regexpchangematcher_test.go b/pkg/config/job/regexpchangematcher_test.go
index 6a168363..c7a537da 100644
--- a/pkg/config/job/regexpchangematcher_test.go
+++ b/pkg/config/job/regexpchangematcher_test.go
@@ -17,11 +17,10 @@ limitations under the License.
 package job_test
 
 import (
-	"testing"
-
 	"github.com/jenkins-x/lighthouse/pkg/config/job"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"testing"
 )
 
 func TestRegexChangeMatcher(t *testing.T) {
diff --git a/pkg/externalplugincfg/load_test.go b/pkg/externalplugincfg/load_test.go
deleted file mode 100644
index 2a4b4b9d..00000000
--- a/pkg/externalplugincfg/load_test.go
+++ /dev/null
@@ -1,52 +0,0 @@
-package externalplugincfg_test
-
-import (
-	"github.com/jenkins-x/lighthouse/pkg/externalplugincfg"
-	"github.com/sirupsen/logrus"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/client-go/kubernetes/fake"
-	"testing"
-)
-
-var testYaml = `- name: cd-indicators
-  requiredResources:
-  - kind: Service
-    name: cd-indicators
-    namespace: jx
-- name: lighthouse-webui-plugin
-  requiredResources:
-  - kind: Service
-    name: lighthouse-webui-plugin
-    namespace: jx`
-
-func TestLoadExternalPluginConfig(t *testing.T) {
-	ns := "jx"
-
-	expected := []string{"lighthouse-webui-plugin"}
-	l := logrus.StandardLogger().WithField("Testing", true)
-
-	client := fake.NewSimpleClientset(
-		&corev1.ConfigMap{
-			ObjectMeta: metav1.ObjectMeta{
-				Namespace: ns,
-				Name:      externalplugincfg.ConfigMapName,
-			},
-			Data: map[string]string{
-				"config.yaml": testYaml,
-			},
-		},
-		&corev1.Service{
-			ObjectMeta: metav1.ObjectMeta{
-				Namespace: ns,
-				Name:      "cd-indicators",
-			},
-		},
-	)
-
-	got, err := externalplugincfg.LoadDisabledPlugins(l, client, ns)
-	require.NoError(t, err, "failed to load disabled external plugins")
-	assert.Equal(t, expected, got, "for disabled external plugins")
-}
diff --git a/pkg/filebrowser/fetch_cache_test.go b/pkg/filebrowser/fetch_cache_test.go
deleted file mode 100644
index f5e8d079..00000000
--- a/pkg/filebrowser/fetch_cache_test.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package filebrowser_test
-
-import (
-	"testing"
-
-	"github.com/jenkins-x/go-scm/scm"
-	"github.com/jenkins-x/lighthouse/pkg/filebrowser"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestFetchCache(t *testing.T) {
-	c := filebrowser.NewFetchCache()
-
-	testCases := []struct {
-		owner, repo, sha string
-		expected         bool
-	}{
-		{
-			owner:    "myowner",
-			repo:     "myrepo",
-			sha:      "main",
-			expected: true,
-		},
-		{
-			owner:    "myowner",
-			repo:     "myrepo",
-			sha:      "main",
-			expected: false,
-		},
-		{
-			owner:    "myowner",
-			repo:     "myrepo",
-			sha:      "a1234",
-			expected: true,
-		},
-	}
-
-	for _, tc := range testCases {
-		fullName := scm.Join(tc.owner, tc.repo)
-		got := c.ShouldFetch(fullName, tc.sha)
-		assert.Equal(t, tc.expected, got, "for repo %s and sha %s", fullName, tc.sha)
-	}
-}
diff --git a/pkg/filebrowser/git_file_browser_test.go b/pkg/filebrowser/git_file_browser_test.go
index 590cd8ad..3194c67d 100644
--- a/pkg/filebrowser/git_file_browser_test.go
+++ b/pkg/filebrowser/git_file_browser_test.go
@@ -1,8 +1,7 @@
-package filebrowser_test
+package filebrowser
 
 import (
 	"fmt"
-	"github.com/jenkins-x/lighthouse/pkg/filebrowser"
 	"io/ioutil"
 	"os"
 	"path/filepath"
@@ -20,9 +19,7 @@ func TestGitFileBrowser(t *testing.T) {
 
 	cf, err := git.NewClientFactory()
 	require.NoError(t, err, "failed to create git client factory")
-	fb := filebrowser.NewFileBrowserFromGitClient(cf)
-
-	fc := filebrowser.NewFetchCache()
+	fb := NewFileBrowserFromGitClient(cf)
 
 	owner := "jenkins-x-quickstarts"
 	repo := "node-http"
@@ -38,14 +35,14 @@ func TestGitFileBrowser(t *testing.T) {
 		return message() + " file " + fileName
 	}
 
-	files, err := fb.ListFiles(owner, repo, path, ref, fc)
+	files, err := fb.ListFiles(owner, repo, path, ref)
 	require.NoError(t, err, "failed to list files "+message())
 	assert.NotEmpty(t, files, "should not be empty")
 	for _, f := range files {
 		t.Logf("file %s type %s\n", f.Name, f.Type)
 	}
 
-	data, err := fb.GetFile(owner, repo, fileName, ref, fc)
+	data, err := fb.GetFile(owner, repo, fileName, ref)
 	require.NoError(t, err, "failed to get file "+fileMessage())
 	text := string(data)
 
@@ -58,7 +55,7 @@ func TestGitFileBrowser(t *testing.T) {
 	ref = ""
 	fileName = "package.json"
 
-	data, err = fb.GetFile(owner, repo, fileName, ref, fc)
+	data, err = fb.GetFile(owner, repo, fileName, ref)
 	require.NoError(t, err, "failed to get file "+fileMessage())
 	text = string(data)
 
@@ -67,7 +64,7 @@ func TestGitFileBrowser(t *testing.T) {
 
 	// switch back to a old sha
 	ref = "5067522b7ed292bef46570ffe3ab75d3a5428769"
-	files, err = fb.ListFiles(owner, repo, path, ref, fc)
+	files, err = fb.ListFiles(owner, repo, path, ref)
 	require.NoError(t, err, "failed to list files "+message())
 	assert.NotEmpty(t, files, "should not be empty")
 	for _, f := range files {
@@ -77,7 +74,7 @@ func TestGitFileBrowser(t *testing.T) {
 	assertNoScmFileExists(t, files, fileName, message())
 
 	ref = ""
-	files, err = fb.ListFiles(owner, repo, path, ref, fc)
+	files, err = fb.ListFiles(owner, repo, path, ref)
 	require.NoError(t, err, "failed to list files "+message())
 	assertScmFileExists(t, files, fileName, message())
 }
@@ -108,8 +105,6 @@ func TestGitFileBrowser_Clone_CreateTag_FetchRef(t *testing.T) {
 	require.NoError(t, err, "failed to find git binary")
 	fmt.Println(baseDir)
 
-	fc := filebrowser.NewFetchCache()
-
 	defer os.RemoveAll(baseDir)
 
 	repoDir := filepath.Join(baseDir, "org", "repo")
@@ -139,9 +134,9 @@ func TestGitFileBrowser_Clone_CreateTag_FetchRef(t *testing.T) {
 
 	cf, err := git.NewLocalClientFactory(baseDir, userGetter, censor)
 	require.NoError(t, err, "failed to create git client factory")
-	fb := filebrowser.NewFileBrowserFromGitClient(cf)
+	fb := NewFileBrowserFromGitClient(cf)
 
-	files, err := fb.ListFiles("org", "repo", "", "master", fc)
+	files, err := fb.ListFiles("org", "repo", "", "master")
 	require.NoError(t, err, "failed to list files")
 
 	require.True(t, len(files) == 1, "exepecting 1 file")
@@ -159,26 +154,12 @@ func TestGitFileBrowser_Clone_CreateTag_FetchRef(t *testing.T) {
 	_, err = executor.Run("tag", "v0.0.1")
 	require.NoError(t, err, "failed to create v0.0.1 tag")
 
-	files, err = fb.ListFiles("org", "repo", "", "v0.0.1", fc)
+	files, err = fb.ListFiles("org", "repo", "", "v0.0.1")
 	require.NoError(t, err, "failed to lst files in v0.0.1 tag")
 	require.True(t, len(files) == 1, "exepecting 1 file")
 	require.Equal(t, files[0].Name, "README.md")
 
-	data, err := fb.GetFile("org", "repo", "README.md", "v0.0.1", fc)
+	data, err := fb.GetFile("org", "repo", "README.md", "v0.0.1")
 	require.NoError(t, err, "failed to lst files in v0.0.1 tag")
 	require.Equal(t, string(data), "README-update-1")
 }
-
-func TestIsSHA(t *testing.T) {
-	testCases := map[string]bool{
-		"de6cc99": true,
-		"de6cc99a6de8ca34b8884fcc05945bd30033f330": true,
-		"main":    false,
-		"123_567": false,
-	}
-
-	for ref, expected := range testCases {
-		got := filebrowser.IsSHA(ref)
-		assert.Equal(t, expected, got, "for ref: %s", ref)
-	}
-}
diff --git a/pkg/jobutil/jobutil_test.go b/pkg/jobutil/jobutil_test.go
index 79667f53..b351ff23 100644
--- a/pkg/jobutil/jobutil_test.go
+++ b/pkg/jobutil/jobutil_test.go
@@ -17,11 +17,10 @@ limitations under the License.
 package jobutil
 
 import (
+	"github.com/stretchr/testify/assert"
 	"reflect"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/sets"
 
diff --git a/pkg/triggerconfig/inrepo/calculate_test.go b/pkg/triggerconfig/inrepo/calculate_test.go
index 4485fb81..02f01b7e 100644
--- a/pkg/triggerconfig/inrepo/calculate_test.go
+++ b/pkg/triggerconfig/inrepo/calculate_test.go
@@ -47,9 +47,8 @@ func TestCalculate(t *testing.T) {
 
 	fileBrowsers, err := filebrowser.NewFileBrowsers(filebrowser.GitHubURL, filebrowser.NewFileBrowserFromScmClient(scmProvider))
 	require.NoError(t, err, "failed to create filebrowsers")
-	fc := filebrowser.NewFetchCache()
 
-	cfg, pluginsCfg, err := inrepo.Generate(fileBrowsers, fc, inrepo.NewResolverCache(), sharedConfig, sharedPluginConfig, owner, repo, ref)
+	cfg, pluginsCfg, err := inrepo.Generate(fileBrowsers, inrepo.NewResolverCache(), sharedConfig, sharedPluginConfig, owner, repo, ref)
 	require.NoError(t, err, "failed to calculate in repo config")
 
 	require.NoError(t, err, "failed to invoke getClientAndTrigger")
@@ -128,9 +127,8 @@ func TestTriggersInBranchMergeToMaster(t *testing.T) {
 
 	fileBrowsers, err := filebrowser.NewFileBrowsers(filebrowser.GitHubURL, filebrowser.NewFileBrowserFromScmClient(scmProvider))
 	require.NoError(t, err, "failed to create filebrowsers")
-	fc := filebrowser.NewFetchCache()
 
-	cfg, _, err := inrepo.Generate(fileBrowsers, fc, inrepo.NewResolverCache(), sharedConfig, sharedPluginConfig, owner, repo, ref)
+	cfg, _, err := inrepo.Generate(fileBrowsers, inrepo.NewResolverCache(), sharedConfig, sharedPluginConfig, owner, repo, ref)
 	require.NoError(t, err, "failed to calculate in repo config")
 
 	presubmits := cfg.Presubmits[fullName]
@@ -186,9 +184,8 @@ func TestIssue1306(t *testing.T) {
 
 	fileBrowsers, err := filebrowser.NewFileBrowsers(filebrowser.GitHubURL, filebrowser.NewFileBrowserFromScmClient(scmProvider))
 	require.NoError(t, err, "failed to create filebrowsers")
-	fc := filebrowser.NewFetchCache()
 
-	cfg, _, err := inrepo.Generate(fileBrowsers, fc, inrepo.NewResolverCache(), sharedConfig, sharedPluginConfig, owner, repo, "pr1")
+	cfg, _, err := inrepo.Generate(fileBrowsers, inrepo.NewResolverCache(), sharedConfig, sharedPluginConfig, owner, repo, "pr1")
 	require.NoError(t, err, "failed to calculate in repo config")
 
 	assert.Contains(t, cfg.Presubmits[fullName][0].Base.PipelineRunSpec.PipelineSpec.Tasks[0].TaskSpec.Steps[0].Script, "ubuntu-pr1")
diff --git a/pkg/triggerconfig/inrepo/load_integration_test.go b/pkg/triggerconfig/inrepo/load_integration_test.go
index 4bf91dbf..ec6c8a49 100644
--- a/pkg/triggerconfig/inrepo/load_integration_test.go
+++ b/pkg/triggerconfig/inrepo/load_integration_test.go
@@ -32,8 +32,7 @@ func TestMergeConfigIntegration(t *testing.T) {
 	fileBrowsers, err := filebrowser.NewFileBrowsers(filebrowser.GitHubURL, filebrowser.NewFileBrowserFromScmClient(scmProvider))
 	require.NoError(t, err, "failed to create filebrowsers")
 
-	fc := filebrowser.NewFetchCache()
-	flag, err := MergeTriggers(cfg, pluginCfg, fileBrowsers, fc, NewResolverCache(), repoOwner, repoName, sha)
+	flag, err := MergeTriggers(cfg, pluginCfg, fileBrowsers, NewResolverCache(), repoOwner, repoName, sha)
 	require.NoError(t, err, "failed to merge configs")
 	assert.True(t, flag, "did not return merge flag")
 
diff --git a/pkg/triggerconfig/inrepo/load_pipelinerun_test.go b/pkg/triggerconfig/inrepo/load_pipelinerun_test.go
index 2599780a..e3011fb6 100644
--- a/pkg/triggerconfig/inrepo/load_pipelinerun_test.go
+++ b/pkg/triggerconfig/inrepo/load_pipelinerun_test.go
@@ -20,7 +20,7 @@ import (
 
 var (
 	// generateTestOutput enable to regenerate the expected output
-	generateTestOutput = true
+	generateTestOutput = false
 
 	// disabledTests lets us disable one or more tests when refactoring
 	disabledTests = []string{}
@@ -73,11 +73,9 @@ func TestLoadPipelineRunTest(t *testing.T) {
 		}
 		fileBrowsers, err := filebrowser.NewFileBrowsers(sourceURL, fileBrowser)
 		require.NoError(t, err, "failed to create filebrowsers")
-		fc := filebrowser.NewFetchCache()
 
 		resolver := &UsesResolver{
 			FileBrowsers:     fileBrowsers,
-			FetchCache:       fc,
 			OwnerName:        "myorg",
 			LocalFileResolve: true,
 		}
diff --git a/pkg/triggerconfig/inrepo/load_triggers_test.go b/pkg/triggerconfig/inrepo/load_triggers_test.go
index aaabec69..ad704498 100644
--- a/pkg/triggerconfig/inrepo/load_triggers_test.go
+++ b/pkg/triggerconfig/inrepo/load_triggers_test.go
@@ -42,8 +42,7 @@ func TestMergeConfig(t *testing.T) {
 
 	cfg := &config.Config{}
 	pluginCfg := &plugins.Configuration{}
-	fc := filebrowser.NewFetchCache()
-	flag, err := MergeTriggers(cfg, pluginCfg, fileBrowsers, fc, NewResolverCache(), owner, repo, ref)
+	flag, err := MergeTriggers(cfg, pluginCfg, fileBrowsers, NewResolverCache(), owner, repo, ref)
 	require.NoError(t, err, "failed to merge configs")
 	assert.True(t, flag, "did not return merge flag")
 
@@ -60,13 +59,12 @@ func TestInvalidConfigs(t *testing.T) {
 
 	fileBrowsers, err := filebrowser.NewFileBrowsers(filebrowser.GitHubURL, filebrowser.NewFileBrowserFromScmClient(scmProvider))
 	require.NoError(t, err, "failed to create filebrowsers")
-	fc := filebrowser.NewFetchCache()
 
 	invalidRepos := []string{"duplicate-presubmit", "duplicate-postsubmit"}
 	for _, repo := range invalidRepos {
 		owner := "myorg"
 		ref := "master"
-		_, err := LoadTriggerConfig(fileBrowsers, fc, NewResolverCache(), owner, repo, ref)
+		_, err := LoadTriggerConfig(fileBrowsers, NewResolverCache(), owner, repo, ref)
 		require.Errorf(t, err, "should have failed to load triggers from repo %s/%s with ref %s", owner, repo, ref)
 
 		t.Logf("got expected error loading invalid configuration on repo %s of: %s", repo, err.Error())
@@ -76,12 +74,11 @@ func TestInvalidConfigs(t *testing.T) {
 func TestEmptyDirectoryDoesNotFail(t *testing.T) {
 	fileBrowsers, err := filebrowser.NewFileBrowsers(filebrowser.GitHubURL, fbfake.NewFakeFileBrowser(filepath.Join("test_data", "empty_dir")))
 	require.NoError(t, err, "failed to create filebrowsers")
-	fc := filebrowser.NewFetchCache()
 
 	owner := "myorg"
 	repo := "myrepo"
 	ref := "master"
-	config, err := LoadTriggerConfig(fileBrowsers, fc, NewResolverCache(), owner, repo, ref)
+	config, err := LoadTriggerConfig(fileBrowsers, NewResolverCache(), owner, repo, ref)
 	require.NoErrorf(t, err, "should not fail to load triggers for repo %s/%s with ref %s", owner, repo, ref)
 	require.NotNil(t, config, "no config for repo %s/%s with ref %s", owner, repo, ref)
 
@@ -99,8 +96,7 @@ func TestLoadJobFromURL(t *testing.T) {
 		File("test_data/load_url/foo.yaml")
 
 	j := &job.Base{}
-	fc := filebrowser.NewFetchCache()
-	err := loadJobBaseFromSourcePath(nil, fc, NewResolverCache(), j, "", "", "https://raw.githubusercontent.com/rawlingsj/test/master/foo.yaml", "")
+	err := loadJobBaseFromSourcePath(nil, NewResolverCache(), j, "", "", "https://raw.githubusercontent.com/rawlingsj/test/master/foo.yaml", "")
 	assert.NoError(t, err, "should not have an error returned")
 	assert.Equal(t, "jenkinsxio/chuck:0.0.1", j.PipelineRunSpec.PipelineSpec.Tasks[0].TaskSpec.Steps[0].Image, "image name for task is not correct")
 }
diff --git a/pkg/triggerconfig/inrepo/test_data/jenkins-x/jx3-pipeline-catalog/refs/1d39235ee9235d7d52d4025a8e59cb8bda04306a/packs/javascript/.lighthouse/jenkins-x/pullrequest.yaml b/pkg/triggerconfig/inrepo/test_data/jenkins-x/jx3-pipeline-catalog/refs/1d39235ee9235d7d52d4025a8e59cb8bda04306a/packs/javascript/.lighthouse/jenkins-x/pullrequest.yaml
index 2dcd5cc8..26ef9288 100644
--- a/pkg/triggerconfig/inrepo/test_data/jenkins-x/jx3-pipeline-catalog/refs/1d39235ee9235d7d52d4025a8e59cb8bda04306a/packs/javascript/.lighthouse/jenkins-x/pullrequest.yaml
+++ b/pkg/triggerconfig/inrepo/test_data/jenkins-x/jx3-pipeline-catalog/refs/1d39235ee9235d7d52d4025a8e59cb8bda04306a/packs/javascript/.lighthouse/jenkins-x/pullrequest.yaml
@@ -55,12 +55,6 @@ spec:
             #!/usr/bin/env sh
             source .jx/variables.sh
             jx preview create
-        - command:
-          - jx-updatebot
-          - pr
-          image: ghcr.io/jenkins-x/jx-updatebot:0.0.82
-          name: promote-release
-          resources: {}
         volumes:
         - name: npmrc
           secret:
diff --git a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-resources/expected.yaml b/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-resources/expected.yaml
index 10f4a2a3..76fb10d3 100644
--- a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-resources/expected.yaml
+++ b/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-resources/expected.yaml
@@ -241,12 +241,6 @@ spec:
             #!/usr/bin/env sh
             source .jx/variables.sh
             jx preview create
-        - command:
-          - jx-updatebot
-          - pr
-          image: ghcr.io/jenkins-x/jx-updatebot:0.0.82
-          name: promote-release
-          resources: {}
         volumes:
         - name: npmrc
           secret:
diff --git a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/README.md b/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/README.md
deleted file mode 100644
index 1a71ffe2..00000000
--- a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-## Reuse steps in a task and override them
-
-This example shows how we can use `image: uses:sourceURI` and a `name: mystep` to include individual the steps in task and then override (add/replace) properties:
-
-* command to run (either via `script` or `command` and optionally `args`)
-* working directory via `workingDir:`  
-* environment variables via `env:` or `envFrom:`
-* volume mounts via `volumeMounts:`
\ No newline at end of file
diff --git a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/expected.yaml b/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/expected.yaml
deleted file mode 100644
index 32f405d6..00000000
--- a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/expected.yaml
+++ /dev/null
@@ -1,234 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: PipelineRun
-metadata:
-  creationTimestamp: null
-spec:
-  params:
-  - name: BUILD_ID
-    value: ""
-  - name: JOB_NAME
-    value: ""
-  - name: JOB_SPEC
-    value: ""
-  - name: JOB_TYPE
-    value: ""
-  - name: PULL_BASE_REF
-    value: ""
-  - name: PULL_BASE_SHA
-    value: ""
-  - name: PULL_NUMBER
-    value: ""
-  - name: PULL_PULL_REF
-    value: ""
-  - name: PULL_PULL_SHA
-    value: ""
-  - name: PULL_REFS
-    value: ""
-  - name: REPO_NAME
-    value: ""
-  - name: REPO_OWNER
-    value: ""
-  - name: REPO_URL
-    value: ""
-  pipelineSpec:
-    params:
-    - description: the unique build number
-      name: BUILD_ID
-      type: string
-    - description: the name of the job which is the trigger context name
-      name: JOB_NAME
-      type: string
-    - description: the specification of the job
-      name: JOB_SPEC
-      type: string
-    - description: '''the kind of job: postsubmit or presubmit'''
-      name: JOB_TYPE
-      type: string
-    - description: the base git reference of the pull request
-      name: PULL_BASE_REF
-      type: string
-    - description: the git sha of the base of the pull request
-      name: PULL_BASE_SHA
-      type: string
-    - default: ""
-      description: git pull request number
-      name: PULL_NUMBER
-      type: string
-    - default: ""
-      description: git pull request ref in the form 'refs/pull/$PULL_NUMBER/head'
-      name: PULL_PULL_REF
-      type: string
-    - default: ""
-      description: git revision to checkout (branch, tag, sha, ref…)
-      name: PULL_PULL_SHA
-      type: string
-    - description: git pull reference strings of base and latest in the form 'master:$PULL_BASE_SHA,$PULL_NUMBER:$PULL_PULL_SHA:refs/pull/$PULL_NUMBER/head'
-      name: PULL_REFS
-      type: string
-    - description: git repository name
-      name: REPO_NAME
-      type: string
-    - description: git repository owner (user or organisation)
-      name: REPO_OWNER
-      type: string
-    - description: git url to clone
-      name: REPO_URL
-      type: string
-    tasks:
-    - name: from-build-pack
-      params:
-      - name: BUILD_ID
-        value: $(params.BUILD_ID)
-      - name: JOB_NAME
-        value: $(params.JOB_NAME)
-      - name: JOB_SPEC
-        value: $(params.JOB_SPEC)
-      - name: JOB_TYPE
-        value: $(params.JOB_TYPE)
-      - name: PULL_BASE_REF
-        value: $(params.PULL_BASE_REF)
-      - name: PULL_BASE_SHA
-        value: $(params.PULL_BASE_SHA)
-      - name: PULL_NUMBER
-        value: $(params.PULL_NUMBER)
-      - name: PULL_PULL_REF
-        value: $(params.PULL_PULL_REF)
-      - name: PULL_PULL_SHA
-        value: $(params.PULL_PULL_SHA)
-      - name: PULL_REFS
-        value: $(params.PULL_REFS)
-      - name: REPO_NAME
-        value: $(params.REPO_NAME)
-      - name: REPO_OWNER
-        value: $(params.REPO_OWNER)
-      - name: REPO_URL
-        value: $(params.REPO_URL)
-      taskSpec:
-        metadata: {}
-        params:
-        - description: the unique build number
-          name: BUILD_ID
-          type: string
-        - description: the name of the job which is the trigger context name
-          name: JOB_NAME
-          type: string
-        - description: the specification of the job
-          name: JOB_SPEC
-          type: string
-        - description: '''the kind of job: postsubmit or presubmit'''
-          name: JOB_TYPE
-          type: string
-        - description: the base git reference of the pull request
-          name: PULL_BASE_REF
-          type: string
-        - description: the git sha of the base of the pull request
-          name: PULL_BASE_SHA
-          type: string
-        - default: ""
-          description: git pull request number
-          name: PULL_NUMBER
-          type: string
-        - default: ""
-          description: git pull request ref in the form 'refs/pull/$PULL_NUMBER/head'
-          name: PULL_PULL_REF
-          type: string
-        - default: ""
-          description: git revision to checkout (branch, tag, sha, ref…)
-          name: PULL_PULL_SHA
-          type: string
-        - description: git pull reference strings of base and latest in the form 'master:$PULL_BASE_SHA,$PULL_NUMBER:$PULL_PULL_SHA:refs/pull/$PULL_NUMBER/head'
-          name: PULL_REFS
-          type: string
-        - description: git repository name
-          name: REPO_NAME
-          type: string
-        - description: git repository owner (user or organisation)
-          name: REPO_OWNER
-          type: string
-        - description: git url to clone
-          name: REPO_URL
-          type: string
-        stepTemplate:
-          env:
-          - name: BUILD_ID
-            value: $(params.BUILD_ID)
-          - name: JOB_NAME
-            value: $(params.JOB_NAME)
-          - name: JOB_SPEC
-            value: $(params.JOB_SPEC)
-          - name: JOB_TYPE
-            value: $(params.JOB_TYPE)
-          - name: PULL_BASE_REF
-            value: $(params.PULL_BASE_REF)
-          - name: PULL_BASE_SHA
-            value: $(params.PULL_BASE_SHA)
-          - name: PULL_NUMBER
-            value: $(params.PULL_NUMBER)
-          - name: PULL_PULL_REF
-            value: $(params.PULL_PULL_REF)
-          - name: PULL_PULL_SHA
-            value: $(params.PULL_PULL_SHA)
-          - name: PULL_REFS
-            value: $(params.PULL_REFS)
-          - name: REPO_NAME
-            value: $(params.REPO_NAME)
-          - name: REPO_OWNER
-            value: $(params.REPO_OWNER)
-          - name: REPO_URL
-            value: $(params.REPO_URL)
-          name: ""
-          resources:
-            requests:
-              cpu: 400m
-              memory: 512Mi
-          volumeMounts:
-          - mountPath: /tekton/home/npm
-            name: npmrc
-          workingDir: /workspace/source
-        steps:
-        - image: gcr.io/jenkinsxio/jx-boot:3.1.155
-          name: jx-variables
-          resources: {}
-          script: |
-            #!/usr/bin/env sh
-            jx gitops variables
-        - image: node:12-slim
-          name: build-npm-install
-          resources: {}
-          script: |
-            #!/bin/sh
-            npm install
-        - image: node:12-slim
-          name: build-npm-test
-          resources: {}
-          script: |
-            #!/bin/sh
-            CI=true DISPLAY=:99 npm test
-        - image: gcr.io/kaniko-project/executor:debug-v1.3.0
-          name: build-container-build
-          resources: {}
-          script: |
-            #!/busybox/sh
-            source .jx/variables.sh
-            cp /tekton/creds-secrets/tekton-container-registry-auth/.dockerconfigjson /kaniko/.docker/config.json
-            /kaniko/executor $KANIKO_FLAGS --context=/workspace/source --dockerfile=Dockerfile --destination=$DOCKER_REGISTRY/$DOCKER_REGISTRY_ORG/$APP_NAME:$VERSION
-        - image: gcr.io/jenkinsxio/jx-preview:0.0.143
-          name: promote-jx-preview
-          resources: {}
-          script: |
-            #!/usr/bin/env sh
-            source .jx/variables.sh
-            jx preview create
-        - image: ghcr.io/jenkins-x/jx-updatebot:0.0.82
-          name: promote-release
-          resources: {}
-          script: |
-            #!/usr/bin/env sh
-            source .jx/variables.sh
-            jx updatebot argo promote --target-git-url https://github.com/myorg/my-staging-repo
-        volumes:
-        - name: npmrc
-          secret:
-            optional: true
-            secretName: npmrc
-status: {}
diff --git a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/source.yaml b/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/source.yaml
deleted file mode 100644
index 4b7aaf99..00000000
--- a/pkg/triggerconfig/inrepo/test_data/load_pipelinerun/uses-steps-override-script/source.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-apiVersion: tekton.dev/v1beta1
-kind: PipelineRun
-spec:
-  pipelineSpec:
-    tasks:
-    - name: from-build-pack
-      taskSpec:
-        stepTemplate:
-          image: uses:jenkins-x/jx3-pipeline-catalog/packs/javascript/.lighthouse/jenkins-x/pullrequest.yaml@1d39235ee9235d7d52d4025a8e59cb8bda04306a
-        steps:
-        - name: jx-variables
-        - image: uses:https://raw.githubusercontent.com/jenkins-x/jx3-pipeline-catalog/1d39235ee9235d7d52d4025a8e59cb8bda04306a/packs/javascript/.lighthouse/jenkins-x/pullrequest.yaml
-          name: build-npm-install
-        - name: build-npm-test
-        - name: build-container-build
-        - name: promote-jx-preview
-        - name: promote-release
-          script: |
-            #!/usr/bin/env sh
-            source .jx/variables.sh
-            jx updatebot argo promote --target-git-url https://github.com/myorg/my-staging-repo
-
diff --git a/pkg/util/externalplugins_test.go b/pkg/util/externalplugins_test.go
index 41d666c4..5d10f74b 100644
--- a/pkg/util/externalplugins_test.go
+++ b/pkg/util/externalplugins_test.go
@@ -10,6 +10,6 @@ import (
 
 func Test_ExternalPluginsForEvent_returns_empty_slice_for_nil_configuration(t *testing.T) {
 	configAgent := &plugins.ConfigAgent{}
-	plugins := util.ExternalPluginsForEvent(configAgent, util.LighthousePayloadTypeActivity, "myorg/myrepo", nil)
+	plugins := util.ExternalPluginsForEvent(configAgent, util.LighthousePayloadTypeActivity, "myorg/myrepo")
 	require.Empty(t, plugins)
 }
diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go
index 892076a0..1dd0916a 100644
--- a/pkg/webhook/webhook_test.go
+++ b/pkg/webhook/webhook_test.go
@@ -253,7 +253,7 @@ func TestNeedDemux(t *testing.T) {
 			})
 			s := &Server{Plugins: pa}
 
-			gotPlugins := util.ExternalPluginsForEvent(s.Plugins, string(test.eventType), test.srcRepo, nil)
+			gotPlugins := util.ExternalPluginsForEvent(s.Plugins, string(test.eventType), test.srcRepo)
 			if len(gotPlugins) != len(test.expected) {
 				t.Fatalf("expected plugins: %+v, got: %+v", test.expected, gotPlugins)
 			}