Repository: openshift-pipelines/pipelines-as-code
Pull request #141 (2021-06-18 07:12:55)

Improve coverage in github.go
Add some unit tests, they were actually tested but i think coverage detection is screwed up, anyhoo not hard to write not bad to have,


Patch:
diff --git a/.tekton/pull-request.yaml b/.tekton/pull-request.yaml
index 160cfb8a..7a0468f0 100644
--- a/.tekton/pull-request.yaml
+++ b/.tekton/pull-request.yaml
@@ -74,7 +74,7 @@ spec:
 
       - name: unitlint
         runAfter:
-          - getcache
+          - fetchit
         taskSpec:
           workspaces:
             - name: source
diff --git a/README.md b/README.md
index b46d594b..ce0de6b4 100644
--- a/README.md
+++ b/README.md
@@ -78,21 +78,6 @@ main into the namespace `my-pipeline-ci`
 For security reasons, the Repository CR needs to be created
 in the namespace where Tekton Pipelines associated with the source code repository would be executed.
 
-There is another optional layer of security where PipelineRun can have an
-annotation to explicitely target a specific namespace. It would stilll need to
-have a Repository CRD created in that namespace to be able to be matched.
-
-With this annotation there is no way a bad actor on a cluster can hijack the
-pipelineRun execution to a namespace they don't have access to. To use that
-feature you need to add this annotation :
-
-```yaml
-pipelinesascode.tekton.dev/target-namespace: "mynamespace"
-```
-
-and Pipeline as Code will only match the repository in the mynamespace Namespace
-instead of trying to match it from all available repository on cluster.
-
 ### Writting Tekton pipelines in `.tekton/` directory
 
 - Pipelines as Code tries to be as close to the tekton template as possible.
@@ -186,11 +171,11 @@ based on the Pipeline name as well.
 This allows you to have multiple runs in the same namespace from the same
 PipelineRun with no risk of conflicts.
 
-Everything that runs your pipelinerun and its references need to be inside the
-`.tekton/` directory or referenced via a remote task (see below on how the remote
-tasks are referenced).
-
-If pipelines as code cannot resolve the referenced tasks in the `Pipeline` or `PipelineSpec` it will fails before applying the pipelinerun onto the cluster.
+Everything that runs your pipelinerun and its references neeed to inside the
+`.tekton/` directory or referenced as remote tasks (see below on how the remote
+tasks are specified).  If pipelines as code cannot resolve the referenced tasks
+in the `Pipeline` or `PipelineSpec` it will fails before applying the
+pipelinerun onto the cluster.
 
 If you need to test your `PipelineRun` locally before sending it in a PR, you can use
 the `tkresolver` CLI, by installing it like this :
@@ -225,7 +210,7 @@ You can have multiple tasks in there if you separate  them by a comma `,`:
 pipelinesascode.tekton.dev/task: "[git-clone, golang-test, tkn]"
 ```
 
-You can have multiple lines if you add a `-NUMBER` suffix to the annotation, for example :
+You can have multiple lines if you add a `-NUMBER` prefix to the annotation, for example :
 
 ```yaml
   pipelinesascode.tekton.dev/task: "[git-clone]"
@@ -235,20 +220,21 @@ You can have multiple lines if you add a `-NUMBER` suffix to the annotation, for
 
 By default `Pipelines as Code` will interpret the string as the `latest` task to grab from [tekton hub](https://hub.tekton.dev).
 
-If you want to have a specific version of the task, you can add a colon `:` to the string and a version number, like in this example :
+If instead you want to have a specific task, you can add a colon `:` to the string and a version number, like in this example :
 
 ```yaml
   pipelinesascode.tekton.dev/task: "[git-clone:0.1]" # will install git-clone 0.1 from tekton.hub
   ```
 
 If you have a string starting with http:// or https://, `Pipelines as Code`
-will fetch the task directly from that remote url :
+will fetch the task directly from that remote url instead of going via the
+`tekton hub` :
 
 ```yaml
   pipelinesascode.tekton.dev/task: "[https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.3/git-clone.yaml]"
 ```
 
-Additionally you can as well a reference to a task from a yaml file inside your repo if you specify the relative path to it, for example :
+You can as well a reference to a task from a yaml file inside your repo if you specify the relative path to it, for example :
 
   ```yaml
   pipelinesascode.tekton.dev/task: "[.tekton/tasks/git-clone.yaml]"
@@ -257,7 +243,6 @@ Additionally you can as well a reference to a task from a yaml file inside your
 will grab the `.tekton/tasks/git-clone.yaml` from the current repository on the `SHA` where the event come from (i.e: the current pull request or the current branch push).
 
 If there is any error fetching those resources, `Pipelines as Code` will error out and not process the pipeline.
-
 If the object fetched cannot be parsed as a Tekton `Task` it will error out.
 
 ### Running the Pipeline
diff --git a/go.mod b/go.mod
index f8a1749d..fd6ad6cf 100644
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,7 @@ require (
 	github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1
 	github.com/pkg/errors v0.9.1
 	github.com/spf13/cobra v1.1.3
-	github.com/tektoncd/pipeline v0.24.3
+	github.com/tektoncd/pipeline v0.24.1
 	go.uber.org/zap v1.16.0
 	golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013
 	gotest.tools/v3 v3.0.3
diff --git a/go.sum b/go.sum
index 496cd9c3..8a8a6579 100644
--- a/go.sum
+++ b/go.sum
@@ -711,9 +711,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/tektoncd/pipeline v0.24.3 h1:hfMDwkAa5D4BMKUI0ojivXa1Vw5ls+N3KROtwK8sNd0=
-github.com/tektoncd/pipeline v0.24.3/go.mod h1:8yXwJvaRU+cDH6fjwJFvKFOnB/WYHrRUD66TTR7l1eg=
-github.com/tektoncd/plumbing v0.0.0-20210514044347-f8a9689d5bd5/go.mod h1:WTWwsg91xgm+jPOKoyKVK/yRYxnVDlUYeDlypB1lDdQ=
+github.com/tektoncd/pipeline v0.24.1 h1:c+Odgmf8dkUVRdQ5NVbOliwFB8608kM9i+18t5QDO+g=
+github.com/tektoncd/pipeline v0.24.1/go.mod h1:ChFD/vfu14VOtCVlLWdtlvOwXfBfVotULoNV6yz+CKY=
+github.com/tektoncd/plumbing v0.0.0-20210420200944-17170d5e7bc9/go.mod h1:WTWwsg91xgm+jPOKoyKVK/yRYxnVDlUYeDlypB1lDdQ=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
diff --git a/pkg/apis/pipelinesascode/v1alpha1/types.go b/pkg/apis/pipelinesascode/v1alpha1/types.go
index 2a0902e7..7f58f580 100644
--- a/pkg/apis/pipelinesascode/v1alpha1/types.go
+++ b/pkg/apis/pipelinesascode/v1alpha1/types.go
@@ -31,14 +31,6 @@ type RepositoryRunStatus struct {
 	// CompletionTime is the time the PipelineRun completed.
 	// +optional
 	CompletionTime *metav1.Time `json:"completionTime,omitempty"`
-
-	// SHA is the name of the SHA that has been tested
-	// +optional
-	SHA *string `json:"sha,omitempty"`
-
-	// Title is the title of the commit SHA that has been tested
-	// +optional
-	Title *string `json:"title,omitempty"`
 }
 
 // RepositorySpec is the spec of a repo
diff --git a/pkg/config/annotation_matcher.go b/pkg/config/annotation_matcher.go
index 8548fa69..79311340 100644
--- a/pkg/config/annotation_matcher.go
+++ b/pkg/config/annotation_matcher.go
@@ -1,14 +1,12 @@
 package config
 
 import (
-	"context"
 	"errors"
 	"fmt"
 	"regexp"
 	"strings"
 
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode"
-	apipac "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/webvcs"
 	"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
@@ -17,7 +15,6 @@ import (
 const (
 	onEventAnnotation        = "on-event"
 	onTargetBranchAnnotation = "on-target-branch"
-	onTargetNamespace        = "target-namespace"
 	reValidateTag            = `^\[(.*)\]$`
 )
 
@@ -42,33 +39,19 @@ func getAnnotationValues(annotation string) ([]string, error) {
 	return splitted, nil
 }
 
-func MatchPipelinerunByAnnotation(ctx context.Context, pruns []*v1beta1.PipelineRun, cs *cli.Clients,
-	runinfo *webvcs.RunInfo) (*v1beta1.PipelineRun, *apipac.Repository, error) {
-	configurations := map[string]map[string]string{}
-	repo := &apipac.Repository{}
+func MatchPipelinerunByAnnotation(pruns []*v1beta1.PipelineRun, cs *cli.Clients,
+	runinfo *webvcs.RunInfo) (*v1beta1.PipelineRun, error) {
 	for _, prun := range pruns {
-		configurations[prun.GetGenerateName()] = map[string]string{}
 		if prun.GetObjectMeta().GetAnnotations() == nil {
 			cs.Log.Warnf("PipelineRun %s does not have any annotations", prun.GetName())
 			continue
 		}
 
-		if targetNS, ok := prun.GetObjectMeta().GetAnnotations()[pipelinesascode.
-			GroupName+"/"+onTargetNamespace]; ok {
-			configurations[prun.GetGenerateName()]["target-namespace"] = targetNS
-			repo, _ = GetRepoByCR(ctx, cs, targetNS, runinfo)
-			if repo == nil {
-				cs.Log.Warnf("could not find Repository CRD in %s while pipelineRun %s targets it", targetNS, prun.GetGenerateName())
-				continue
-			}
-		}
-
 		if targetEvent, ok := prun.GetObjectMeta().GetAnnotations()[pipelinesascode.
 			GroupName+"/"+onEventAnnotation]; ok {
 			matched, err := matchOnAnnotation(targetEvent, runinfo.EventType, false)
-			configurations[prun.GetGenerateName()]["target-event"] = targetEvent
 			if err != nil {
-				return nil, nil, err
+				return nil, err
 			}
 			if !matched {
 				continue
@@ -78,31 +61,18 @@ func MatchPipelinerunByAnnotation(ctx context.Context, pruns []*v1beta1.Pipeline
 		if targetBranch, ok := prun.GetObjectMeta().GetAnnotations()[pipelinesascode.
 			GroupName+"/"+onTargetBranchAnnotation]; ok {
 			matched, err := matchOnAnnotation(targetBranch, runinfo.BaseBranch, true)
-			configurations[prun.GetGenerateName()]["target-branch"] = targetBranch
 			if err != nil {
-				return nil, nil, err
+				return nil, err
 			}
 			if !matched {
 				continue
 			}
 		}
 
-		return prun, repo, nil
+		return prun, nil
 	}
-
-	cs.Log.Infof("cannot match between event and pipelineRuns: URL=%s baseBranch=%s, "+
-		"eventType=%s", runinfo.URL,
-		runinfo.BaseBranch,
-		runinfo.EventType)
-
-	cs.Log.Info("available configuration in pipelineRuns annotations")
-	for prunname, maps := range configurations {
-		cs.Log.Infof("pipelineRun: %s, baseBranch=%s, targetEvent=%s, targetNs=%s",
-			prunname, maps["target-branch"], maps["target-event"], maps["target-namespace"])
-	}
-
 	// TODO: more descriptive error message
-	return nil, nil, fmt.Errorf("cannot match pipeline from webhook to pipelineruns")
+	return nil, fmt.Errorf("cannot match any pipeline on EventType: %s, TargetBranch: %s", runinfo.EventType, runinfo.BaseBranch)
 }
 
 func matchOnAnnotation(annotations string, runinfoValue string, branchMatching bool) (bool, error) {
diff --git a/pkg/config/repo_runinfo_matcher.go b/pkg/config/repo_runinfo_matcher.go
index 633270fd..c57f7061 100644
--- a/pkg/config/repo_runinfo_matcher.go
+++ b/pkg/config/repo_runinfo_matcher.go
@@ -24,18 +24,16 @@ func branchMatch(prunBranch, baseBranch string) bool {
 	return g.Match(baseBranch)
 }
 
-func GetRepoByCR(ctx context.Context, cs *cli.Clients, ns string, runinfo *webvcs.RunInfo) (*apipac.Repository, error) {
-	repositories, err := cs.PipelineAsCode.PipelinesascodeV1alpha1().Repositories(ns).List(
+func GetRepoByCR(ctx context.Context, cs *cli.Clients, runinfo *webvcs.RunInfo) (apipac.Repository, error) {
+	var repository apipac.Repository
+
+	repositories, err := cs.PipelineAsCode.PipelinesascodeV1alpha1().Repositories("").List(
 		ctx, metav1.ListOptions{})
 	if err != nil {
-		return nil, err
+		return repository, err
 	}
-	matches := []string{}
-	for _, value := range repositories.Items {
-		matches = append(matches,
-			fmt.Sprintf("RepositoryValue: URL=%s, eventType=%s BaseBranch:=%s", value.Spec.URL,
-				value.Spec.EventType, value.Spec.Branch))
 
+	for _, value := range repositories.Items {
 		if value.Spec.URL == runinfo.URL &&
 			value.Spec.EventType == runinfo.EventType {
 			if value.Spec.Branch != runinfo.BaseBranch {
@@ -47,18 +45,14 @@ func GetRepoByCR(ctx context.Context, cs *cli.Clients, ns string, runinfo *webvc
 			// Disallow attempts for hijacks. If the installed CR is not configured on the
 			// Namespace the Spec is targeting then disallow it.
 			if value.Namespace != value.Spec.Namespace {
-				return nil, fmt.Errorf("repo CR %s matches but belongs to %s while it should be in %s",
+				return repository, fmt.Errorf("repo CR %s matches but belongs to %s while it should be in %s",
 					value.Name,
 					value.Namespace,
 					value.Spec.Namespace)
 			}
 
-			return &value, nil
+			return value, nil
 		}
 	}
-	for _, value := range matches {
-		cs.Log.Debug(value)
-	}
-
-	return nil, nil
+	return repository, nil
 }
diff --git a/pkg/pipelineascode/pipelineascode.go b/pkg/pipelineascode/pipelineascode.go
index a3e58153..6f9ff00b 100644
--- a/pkg/pipelineascode/pipelineascode.go
+++ b/pkg/pipelineascode/pipelineascode.go
@@ -70,14 +70,12 @@ func Run(ctx context.Context, cs *cli.Clients, k8int cli.KubeInteractionIntf, ru
 	}
 
 	// Match the Event to a Repository Resource,
-	// We are going to match on targetNamespace annotation later on in
-	// `MatchPipelinerunByAnnotation`
-	repo, err := config.GetRepoByCR(ctx, cs, "", runinfo)
+	// TODO: we need to be able to force a Namespace from the configuration as annotation as an extra layer of security for // hijacking
+	repo, err := config.GetRepoByCR(ctx, cs, runinfo)
 	if err != nil {
 		return err
 	}
-
-	if repo == nil || repo.Spec.Namespace == "" {
+	if repo.Spec.Namespace == "" {
 		msg := fmt.Sprintf("Could not find a namespace match for %s/%s on target-branch:%s event-type: %s", runinfo.Owner, runinfo.Repository, runinfo.BaseBranch, runinfo.EventType)
 		if runinfo.EventType == "pull_request" || runinfo.TriggerTarget == "issue-recheck" {
 			err = createStatus(ctx, cs, runinfo, "completed", "skipped", msg, "https://tenor.com/search/sad-cat-gifs", true)
@@ -146,13 +144,10 @@ func Run(ctx context.Context, cs *cli.Clients, k8int cli.KubeInteractionIntf, ru
 	}
 
 	// Match the pipelinerun with annotation
-	pipelineRun, annotationRepo, err := config.MatchPipelinerunByAnnotation(ctx, pipelineRuns, cs, runinfo)
+	pipelineRun, err := config.MatchPipelinerunByAnnotation(pipelineRuns, cs, runinfo)
 	if err != nil {
 		return err
 	}
-	if annotationRepo.Spec.Namespace != "" {
-		repo = annotationRepo
-	}
 
 	// Add labels on the soon to be created pipelinerun so UI/CLI can easily
 	// query them. Since K8s do not like slash in labels value and on push we
@@ -206,8 +201,6 @@ func Run(ctx context.Context, cs *cli.Clients, k8int cli.KubeInteractionIntf, ru
 		PipelineRunName: newPr.Name,
 		StartTime:       newPr.Status.StartTime,
 		CompletionTime:  newPr.Status.CompletionTime,
-		SHA:             &runinfo.SHA,
-		Title:           &runinfo.SHATitle,
 	}
 
 	// Get repo again in case it was updated while we were running the CI
diff --git a/pkg/webvcs/github.go b/pkg/webvcs/github.go
index fbd331bc..a86cadaa 100644
--- a/pkg/webvcs/github.go
+++ b/pkg/webvcs/github.go
@@ -37,7 +37,6 @@ type RunInfo struct {
 	TriggerTarget string
 	URL           string
 	WebConsoleURL string
-	SHATitle      string
 }
 
 // Check check if the runinfo is properly set
@@ -200,7 +199,6 @@ func (v GithubVCS) ParsePayload(ctx context.Context, log *zap.SugaredLogger, eve
 			DefaultBranch: event.GetRepo().GetDefaultBranch(),
 			URL:           event.GetRepo().GetHTMLURL(),
 			SHA:           event.GetHeadCommit().GetID(),
-			SHATitle:      event.GetHeadCommit().GetMessage(),
 			Sender:        event.GetSender().GetLogin(),
 			BaseBranch:    event.GetRef(),
 			EventType:     eventType,
@@ -222,14 +220,6 @@ func (v GithubVCS) ParsePayload(ctx context.Context, log *zap.SugaredLogger, eve
 	default:
 		return &runinfo, errors.New("this event is not supported")
 	}
-
-	if runinfo.SHATitle == "" {
-		runinfo.SHATitle, err = v.GetSHACommitTitle(ctx, &runinfo)
-		if err != nil {
-			return nil, err
-		}
-	}
-
 	runinfo.Event = event
 	runinfo.TriggerTarget = triggerTarget
 	return &runinfo, nil
@@ -282,15 +272,6 @@ func (v GithubVCS) GetStringPullRequestComment(ctx context.Context, runinfo *Run
 	return ret, nil
 }
 
-// GetSHACommitTitle Retrieve the commit title of the SHA
-func (v GithubVCS) GetSHACommitTitle(ctx context.Context, runinfo *RunInfo) (string, error) {
-	c, _, err := v.Client.Repositories.GetCommit(ctx, runinfo.Owner, runinfo.Repository, runinfo.SHA)
-	if err != nil {
-		return "", err
-	}
-	return strings.Split(c.Commit.GetMessage(), "\n\n")[0], nil
-}
-
 // GetTektonDir Get tekton directory from a repository
 func (v GithubVCS) GetTektonDir(ctx context.Context, path string, runinfo *RunInfo) ([]*github.RepositoryContent, error) {
 	fp, objects, resp, err := v.Client.Repositories.GetContents(ctx, runinfo.Owner,
diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go
index dd12266c..8b47e4b4 100644
--- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go
+++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/openapi_generated.go
@@ -2687,7 +2687,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm
 							Format:      "",
 						},
 					},
-					"workspaces": {
+					"Workspaces": {
 						SchemaProps: spec.SchemaProps{
 							Description: "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Sidecar wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.",
 							Type:        []string{"array"},
diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json
index bf507e9e..3eec4b49 100644
--- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json
+++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/swagger.json
@@ -1496,6 +1496,14 @@
         "name"
       ],
       "properties": {
+        "Workspaces": {
+          "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Sidecar wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.",
+          "type": "array",
+          "items": {
+            "default": {},
+            "$ref": "#/definitions/v1beta1.WorkspaceUsage"
+          }
+        },
         "args": {
           "description": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. The $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME). Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell",
           "type": "array",
@@ -1630,14 +1638,6 @@
         "workingDir": {
           "description": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.",
           "type": "string"
-        },
-        "workspaces": {
-          "description": "This is an alpha field. You must set the \"enable-api-fields\" feature flag to \"alpha\" for this field to be supported.\n\nWorkspaces is a list of workspaces from the Task that this Sidecar wants exclusive access to. Adding a workspace to this list means that any other Step or Sidecar that does not also request this Workspace will not have access to it.",
-          "type": "array",
-          "items": {
-            "default": {},
-            "$ref": "#/definitions/v1beta1.WorkspaceUsage"
-          }
         }
       }
     },
diff --git a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_types.go b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_types.go
index 05fb550c..53e5d4f0 100644
--- a/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_types.go
+++ b/vendor/github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1/task_types.go
@@ -161,7 +161,7 @@ type Sidecar struct {
 	// other Step or Sidecar that does not also request this Workspace will
 	// not have access to it.
 	// +optional
-	Workspaces []WorkspaceUsage `json:"workspaces,omitempty"`
+	Workspaces []WorkspaceUsage
 }
 
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 4bff51c1..1068bc6b 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -204,7 +204,7 @@ github.com/sirupsen/logrus
 github.com/spf13/cobra
 # github.com/spf13/pflag v1.0.5
 github.com/spf13/pflag
-# github.com/tektoncd/pipeline v0.24.3
+# github.com/tektoncd/pipeline v0.24.1
 ## explicit
 github.com/tektoncd/pipeline/pkg/apis/config
 github.com/tektoncd/pipeline/pkg/apis/pipeline


Test patch:
diff --git a/pkg/cmd/pipelineascode/pipelineascode_test.go b/pkg/cmd/pipelineascode/pipelineascode_test.go
index f5f3388e..ce5502ab 100644
--- a/pkg/cmd/pipelineascode/pipelineascode_test.go
+++ b/pkg/cmd/pipelineascode/pipelineascode_test.go
@@ -45,9 +45,6 @@ func TestRunWrapPR(t *testing.T) {
 	mux.HandleFunc("/repos/chmouel/scratchmyback/check-runs", func(w http.ResponseWriter, r *http.Request) {
 		fmt.Fprintf(w, `{"id": %d}`, checkid)
 	})
-	mux.HandleFunc("/repos/chmouel/scratchmyback/commits/ref", func(w http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprint(w, `{"commit": {"message": "HELLO"}}`)
-	})
 	mux.HandleFunc(fmt.Sprintf("/repos/chmouel/scratchmyback/check-runs/%d", checkid), func(w http.ResponseWriter, r *http.Request) {
 		fmt.Fprintf(w, `{"id": %d}`, checkid)
 	})
@@ -186,9 +183,6 @@ func TestRunWrap(t *testing.T) {
 	mux.HandleFunc(fmt.Sprintf("/repos/chmouel/scratchmyback/check-runs/%d", checkid), func(w http.ResponseWriter, r *http.Request) {
 		fmt.Fprintf(w, `{"id": %d}`, checkid)
 	})
-	mux.HandleFunc("/repos/chmouel/scratchmyback/commits/ref", func(w http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprint(w, `{"commit": {"message": "HELLO"}}`)
-	})
 	kinteract := &kitesthelper.KinterfaceTest{
 		ConsoleURL: "https://console.url",
 	}
diff --git a/pkg/config/annotation_matcher_test.go b/pkg/config/annotation_matcher_test.go
index 097d5f7d..f9f3e381 100644
--- a/pkg/config/annotation_matcher_test.go
+++ b/pkg/config/annotation_matcher_test.go
@@ -1,126 +1,20 @@
 package config
 
 import (
-	"fmt"
 	"reflect"
 	"strings"
 	"testing"
 
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode"
-	"github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
-	testclient "github.com/openshift-pipelines/pipelines-as-code/pkg/test/clients"
-	testnewrepo "github.com/openshift-pipelines/pipelines-as-code/pkg/test/repository"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/webvcs"
 	tektonv1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
 	"go.uber.org/zap"
 	zapobserver "go.uber.org/zap/zaptest/observer"
 	"gotest.tools/v3/assert"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	rtesting "knative.dev/pkg/reconciler/testing"
 )
 
-func TestMatchPipelinerunAnnotationAndRepositories(t *testing.T) {
-	pipelineTargetNSName := "pipeline-target-ns"
-	pipelineTargetNS := &tektonv1beta1.PipelineRun{
-		ObjectMeta: metav1.ObjectMeta{
-			Name: pipelineTargetNSName,
-			Annotations: map[string]string{
-				pipelinesascode.GroupName + "/" + onTargetNamespace:        targetNamespace,
-				pipelinesascode.GroupName + "/" + onEventAnnotation:        "[pull_request]",
-				pipelinesascode.GroupName + "/" + onTargetBranchAnnotation: fmt.Sprintf("[%s]", mainBranch),
-			},
-		},
-	}
-
-	type args struct {
-		pruns   []*tektonv1beta1.PipelineRun
-		runinfo *webvcs.RunInfo
-		data    testclient.Data
-	}
-	tests := []struct {
-		name, wantPRName, wantRepoName, wantLog string
-		args                                    args
-		wantErr                                 bool
-	}{
-		{
-			name:       "match a repository with target NS",
-			wantPRName: pipelineTargetNSName,
-			args: args{
-				pruns:   []*tektonv1beta1.PipelineRun{pipelineTargetNS},
-				runinfo: &webvcs.RunInfo{URL: targetURL, EventType: "pull_request", BaseBranch: mainBranch},
-				data: testclient.Data{
-					Repositories: []*v1alpha1.Repository{
-						testnewrepo.NewRepo("test-good", targetURL, mainBranch, targetNamespace, targetNamespace, "pull_request"),
-					},
-				},
-			},
-		},
-		{
-			name:         "match same webhook on multiple repos with different NS",
-			wantPRName:   pipelineTargetNSName,
-			wantRepoName: "test-good",
-			args: args{
-				pruns:   []*tektonv1beta1.PipelineRun{pipelineTargetNS},
-				runinfo: &webvcs.RunInfo{URL: targetURL, EventType: "pull_request", BaseBranch: mainBranch},
-				data: testclient.Data{
-					Repositories: []*v1alpha1.Repository{
-						testnewrepo.NewRepo("test-other", targetURL, mainBranch, targetNamespace, targetNamespace, "pull_request"),
-						testnewrepo.NewRepo("test-good", targetURL, mainBranch, targetNamespace, targetNamespace, "pull_request"),
-					},
-				},
-			},
-		},
-		{
-			name:    "no match a repository with target NS",
-			wantErr: true,
-			wantLog: "could not find Repository CRD",
-			args: args{
-				pruns:   []*tektonv1beta1.PipelineRun{pipelineTargetNS},
-				runinfo: &webvcs.RunInfo{URL: targetURL, EventType: "pull_request", BaseBranch: mainBranch},
-				data: testclient.Data{
-					Repositories: []*v1alpha1.Repository{
-						testnewrepo.NewRepo("test-good", targetURL, mainBranch, "otherNS", "otherNS", "pull_request"),
-					},
-				},
-			},
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			ctx, _ := rtesting.SetupFakeContext(t)
-			cs, _ := testclient.SeedTestData(t, ctx, tt.args.data)
-			observer, log := zapobserver.New(zap.InfoLevel)
-			logger := zap.New(observer).Sugar()
-			client := &cli.Clients{PipelineAsCode: cs.PipelineAsCode, Log: logger}
-			got, repo, err := MatchPipelinerunByAnnotation(ctx,
-				tt.args.pruns,
-				client, tt.args.runinfo)
-
-			if tt.wantErr && err == nil {
-				t.Error("We should have get an error")
-			}
-
-			if !tt.wantErr && err != nil {
-				t.Errorf("We should have not get an error %s", err)
-			}
-
-			if tt.wantRepoName != "" {
-				assert.Assert(t, tt.wantRepoName == repo.GetName())
-			}
-			if tt.wantPRName != "" {
-				assert.Assert(t, tt.wantPRName == got.GetName())
-			}
-			if tt.wantLog != "" {
-				logmsg := log.TakeAll()
-				assert.Assert(t, len(logmsg) > 0, "We didn't get any log message")
-				assert.Assert(t, strings.Contains(logmsg[0].Message, tt.wantLog), logmsg[0].Message, tt.wantLog)
-			}
-		})
-	}
-}
-
 func TestMatchPipelinerunByAnnotation(t *testing.T) {
 	pipelineGood := &tektonv1beta1.PipelineRun{
 		ObjectMeta: metav1.ObjectMeta{
@@ -206,7 +100,7 @@ func TestMatchPipelinerunByAnnotation(t *testing.T) {
 				runinfo: &webvcs.RunInfo{EventType: "push", BaseBranch: "main"},
 			},
 			wantErr: true,
-			wantLog: "cannot match between event and pipelineRuns",
+			wantLog: "does not have any annotations",
 		},
 		{
 			name: "bad-event-annotation",
@@ -320,8 +214,7 @@ func TestMatchPipelinerunByAnnotation(t *testing.T) {
 
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			ctx, _ := rtesting.SetupFakeContext(t)
-			got, _, err := MatchPipelinerunByAnnotation(ctx, tt.args.pruns, cs, tt.args.runinfo)
+			got, err := MatchPipelinerunByAnnotation(tt.args.pruns, cs, tt.args.runinfo)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("MatchPipelinerunByAnnotation() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -332,8 +225,8 @@ func TestMatchPipelinerunByAnnotation(t *testing.T) {
 			}
 			if tt.wantLog != "" {
 				logmsg := log.TakeAll()
-				assert.Assert(t, len(logmsg) > 0, "We didn't get any log message")
-				assert.Assert(t, strings.Contains(logmsg[0].Message, tt.wantLog), logmsg[0].Message, tt.wantLog)
+				assert.Assert(t, len(logmsg) > 0)
+				assert.Assert(t, strings.Contains(logmsg[0].Message, tt.wantLog))
 			}
 		})
 	}
diff --git a/pkg/config/repo_runinfo_matcher_test.go b/pkg/config/repo_runinfo_matcher_test.go
index 42a8e88e..e9b50aec 100644
--- a/pkg/config/repo_runinfo_matcher_test.go
+++ b/pkg/config/repo_runinfo_matcher_test.go
@@ -8,8 +8,6 @@ import (
 	testclient "github.com/openshift-pipelines/pipelines-as-code/pkg/test/clients"
 	testnewrepo "github.com/openshift-pipelines/pipelines-as-code/pkg/test/repository"
 	"github.com/openshift-pipelines/pipelines-as-code/pkg/webvcs"
-	"go.uber.org/zap"
-	zapobserver "go.uber.org/zap/zaptest/observer"
 	"gotest.tools/v3/assert"
 	rtesting "knative.dev/pkg/reconciler/testing"
 )
@@ -137,20 +135,14 @@ func Test_getRepoByCR(t *testing.T) {
 		t.Run(tt.name, func(t *testing.T) {
 			ctx, _ := rtesting.SetupFakeContext(t)
 			cs, _ := testclient.SeedTestData(t, ctx, tt.args.data)
-			observer, _ := zapobserver.New(zap.InfoLevel)
-			logger := zap.New(observer).Sugar()
-			client := &cli.Clients{PipelineAsCode: cs.PipelineAsCode, Log: logger}
-			got, err := GetRepoByCR(ctx, client, "", tt.args.runinfo)
+			client := &cli.Clients{PipelineAsCode: cs.PipelineAsCode}
+			got, err := GetRepoByCR(ctx, client, tt.args.runinfo)
 			if err == nil && tt.wantErr {
 				assert.NilError(t, err, "GetRepoByCR() error = %v, wantErr %v", err, tt.wantErr)
 			}
-			if tt.wantTargetNS == "" && got != nil {
+			if tt.wantTargetNS == "" && got.Spec.Namespace != "" {
 				t.Errorf("GetRepoByCR() got = '%v', want '%v'", got.Spec.Namespace, tt.wantTargetNS)
 			}
-			if tt.wantTargetNS != "" && got == nil {
-				t.Errorf("GetRepoByCR() got = '%v', want '%v'", got.Spec.Namespace, tt.wantTargetNS)
-			}
-
 			if tt.wantTargetNS != "" && tt.wantTargetNS != got.Spec.Namespace {
 				t.Errorf("GetRepoByCR() got = '%v', want '%v'", got.Spec.Namespace, tt.wantTargetNS)
 			}
diff --git a/pkg/pipelineascode/pipelineascode_test.go b/pkg/pipelineascode/pipelineascode_test.go
index ba4bb822..42413e19 100644
--- a/pkg/pipelineascode/pipelineascode_test.go
+++ b/pkg/pipelineascode/pipelineascode_test.go
@@ -136,7 +136,7 @@ func TestRun(t *testing.T) {
 				EventType:  "pull_request",
 			},
 			tektondir:   "testdata/pull_request",
-			wantErr:     "cannot match pipeline from webhook to pipelineruns",
+			wantErr:     "cannot match any pipeline",
 			finalStatus: "neutral",
 		},
 		{
diff --git a/pkg/webvcs/github_test.go b/pkg/webvcs/github_test.go
index b29e882e..09f2f262 100644
--- a/pkg/webvcs/github_test.go
+++ b/pkg/webvcs/github_test.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"io/ioutil"
 	"net/http"
+	"path/filepath"
 	"reflect"
 	"strings"
 	"testing"
@@ -116,15 +117,7 @@ func TestPayLoadFix(t *testing.T) {
 	b, err := ioutil.ReadFile("testdata/pull_request_with_newlines.json")
 	assert.NilError(t, err)
 	ctx, _ := rtesting.SetupFakeContext(t)
-	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
-	defer teardown()
-	mux.HandleFunc("/repos/repo/owner/commits/SHA", func(w http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprint(w, `{"commit": {"message": "HELLO"}}`)
-	})
-	gvcs := GithubVCS{
-		Client: fakeclient,
-	}
-
+	gvcs := NewGithubVCS("none", "")
 	logger, _ := getLogger()
 	_, err = gvcs.ParsePayload(ctx, logger, "pull_request", "pull_request", string(b))
 	// would bomb out on "assertion failed: error is not nil: invalid character
@@ -134,10 +127,9 @@ func TestPayLoadFix(t *testing.T) {
 
 func TestParsePayloadRerequestFromPullRequest(t *testing.T) {
 	checkrunSender := "jean-pierre"
-	prOwner := "owner"
-	repoName := "repo"
+	prOwner := "openshift"
+	repoName := "pipelines"
 	prNumber := "123"
-	sha := "ParsePayloadRerequestFromPullRequestSHA"
 	checkrunEvent := fmt.Sprintf(`{"action": "rerequested",
 	"sender": {"login": "%s"},
 	"check_run": {"check_suite": {"pull_requests": [{"number": %s}]}},
@@ -146,10 +138,7 @@ func TestParsePayloadRerequestFromPullRequest(t *testing.T) {
 	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 	defer teardown()
 	mux.HandleFunc("/repos/"+prOwner+"/"+repoName+"/pulls/"+prNumber, func(rw http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprintf(rw, `{"head": {"sha": "%s", "ref": "123"}, "user": {"login": "%s"}}`, sha, prOwner)
-	})
-	mux.HandleFunc("/repos/owner/repo/commits/"+sha, func(w http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprint(w, `{"commit": {"message": "HELLO"}}`)
+		_, _ = fmt.Fprintf(rw, `{"head": {"ref": "123"}, "user": {"login": "%s"}}`, prOwner)
 	})
 	ctx, _ := rtesting.SetupFakeContext(t)
 	gvcs := GithubVCS{
@@ -170,9 +159,9 @@ func TestParsePayloadRerequestFromPullRequest(t *testing.T) {
 func TestParsePayloadRerequestFromPush(t *testing.T) {
 	sender := "jean-pierre"
 	headBranch := "tartonpion"
-	headSHA := "TestParsePayloadRerequestFromPushSHA"
+	headSHA := "abcd"
 	owner := "owner"
-	repository := "repo"
+	repository := "repository"
 	url := fmt.Sprintf("https://github.com/%s/%s", owner, repository)
 	checkrunEvent := fmt.Sprintf(`{
   "action": "rerequested",
@@ -197,14 +186,7 @@ func TestParsePayloadRerequestFromPush(t *testing.T) {
 }`,
 		headBranch, headSHA, url, repository, owner, sender)
 	ctx, _ := rtesting.SetupFakeContext(t)
-	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
-	defer teardown()
-	gvcs := GithubVCS{
-		Client: fakeclient,
-	}
-	mux.HandleFunc("/repos/owner/repo/commits/"+headSHA, func(w http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprint(w, `{"commit": {"message": "HELLO"}}`)
-	})
+	gvcs := GithubVCS{}
 	logger, _ := getLogger()
 	runinfo, err := gvcs.ParsePayload(ctx, logger, "check_run", "issue-recheck", checkrunEvent)
 	assert.NilError(t, err)
@@ -223,15 +205,11 @@ func TestParsePayLoadRetest(t *testing.T) {
 	repoOwner := "openshift"
 	repoName := "pipelines"
 	prNumber := "123"
-	sha := "TestParsePayLoadRetestSHA"
 
 	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
 	defer teardown()
 	mux.HandleFunc("/repos/"+prOwner+"/"+repoName+"/pulls/"+prNumber, func(rw http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprintf(rw, `{"head": {"sha": "%s", "ref": "123"}, "user": {"login": "%s"}}`, sha, prOwner)
-	})
-	mux.HandleFunc("/repos/user1/pipelines/commits/"+sha, func(w http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprint(w, `{"commit": {"message": "HELLO"}}`)
+		_, _ = fmt.Fprintf(rw, `{"head": {"ref": "123"}, "user": {"login": "%s"}}`, prOwner)
 	})
 
 	issueEvent := fmt.Sprintf(`{
@@ -271,15 +249,9 @@ func TestParsePayLoadRetest(t *testing.T) {
 func TestParsePayload(t *testing.T) {
 	b, err := ioutil.ReadFile("testdata/pull_request.json")
 	assert.NilError(t, err)
-	fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
-	defer teardown()
-	mux.HandleFunc("/repos/chmouel/scratchpad/commits/cc8334de8e056317d18bd00c2588c3f7c95af294", func(w http.ResponseWriter, r *http.Request) {
-		_, _ = fmt.Fprint(w, `{"commit": {"message": "HELLO"}}`)
-	})
-	gvcs := GithubVCS{
-		Client: fakeclient,
-	}
+
 	ctx, _ := rtesting.SetupFakeContext(t)
+	gvcs := NewGithubVCS("none", "")
 	logger, _ := getLogger()
 
 	runinfo, err := gvcs.ParsePayload(ctx, logger, "pull_request", "pull_request", string(b))
@@ -507,6 +479,112 @@ func TestGithubVCS_CreateCheckRun(t *testing.T) {
 	assert.Equal(t, cr.GetID(), int64(555))
 }
 
+func TestCheckSenderOrgMembership(t *testing.T) {
+	tests := []struct {
+		name, apiReturn  string
+		allowed, wantErr bool
+		runinfo          *RunInfo
+	}{
+		{
+			name: "Check Sender Org Membership",
+			runinfo: &RunInfo{
+				Owner:  "organization",
+				Sender: "me",
+			},
+			apiReturn: `[{"login": "me"}]`,
+			allowed:   true,
+			wantErr:   false,
+		},
+		{
+			name: "Check Sender not in Org Membership",
+			runinfo: &RunInfo{
+				Owner:  "organization",
+				Sender: "me",
+			},
+			apiReturn: `[{"login": "not"}]`,
+			allowed:   false,
+		},
+		{
+			name: "Not found on organization",
+			runinfo: &RunInfo{
+				Owner:  "notfound",
+				Sender: "me",
+			},
+			allowed: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
+			defer teardown()
+			ctx, _ := rtesting.SetupFakeContext(t)
+			gvcs := GithubVCS{
+				Client: fakeclient,
+			}
+			mux.HandleFunc(fmt.Sprintf("/orgs/%s/public_members", tt.runinfo.Owner), func(rw http.ResponseWriter, r *http.Request) {
+				fmt.Fprint(rw, tt.apiReturn)
+			})
+
+			allowed, err := gvcs.CheckSenderOrgMembership(ctx, tt.runinfo)
+			if tt.wantErr && err == nil {
+				t.Error("We didn't get an error when we wanted one")
+			}
+			if !tt.wantErr && err != nil {
+				t.Errorf("We got an error when we didn't want it: %s", err)
+			}
+			assert.Equal(t, tt.allowed, allowed)
+		})
+	}
+}
+
+func TestGetStringPullRequestComment(t *testing.T) {
+	regexp := `(^|\n)/retest(\r\n|$)`
+	tests := []struct {
+		name, apiReturn string
+		wantErr         bool
+		runinfo         *RunInfo
+		wantRet         bool
+	}{
+		{
+			name:      "Get String from comments",
+			runinfo:   &RunInfo{URL: "http://1"},
+			apiReturn: `[{"body": "/retest"}]`,
+			wantRet:   true,
+		},
+		{
+			name:      "Not matching string in comments",
+			runinfo:   &RunInfo{URL: "http://1"},
+			apiReturn: `[{"body": ""}]`,
+			wantRet:   false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
+			defer teardown()
+			ctx, _ := rtesting.SetupFakeContext(t)
+			gvcs := GithubVCS{
+				Client: fakeclient,
+			}
+			mux.HandleFunc(fmt.Sprintf("/repos/issues/%s/comments", filepath.Base(tt.runinfo.URL)), func(rw http.ResponseWriter, r *http.Request) {
+				fmt.Fprint(rw, tt.apiReturn)
+			})
+
+			ret, err := gvcs.GetStringPullRequestComment(ctx, tt.runinfo, regexp)
+			if tt.wantErr && err == nil {
+				t.Error("We didn't get an error when we wanted one")
+			}
+			if !tt.wantErr && err != nil {
+				t.Errorf("We got an error when we didn't want it: %s", err)
+			}
+
+			if tt.wantRet {
+				assert.Assert(t, ret != nil)
+			}
+		})
+	}
+}
+
 func TestRunInfoCheck(t *testing.T) {
 	type fields struct {
 		Owner         string
@@ -566,21 +644,6 @@ func TestRunInfoCheck(t *testing.T) {
 	}
 }
 
-func TestCreateStatus(t *testing.T) {
-	ctx, _ := rtesting.SetupFakeContext(t)
-	gcvs, teardown := setupFakesURLS()
-	checkrunid := int64(2026)
-	defer teardown()
-	runinfo := &RunInfo{
-		Owner:      "check",
-		Repository: "run",
-		CheckRunID: &checkrunid,
-	}
-	cr, err := gcvs.CreateStatus(ctx, runinfo, "completed", "success", "Yay", "https://foo/bar")
-	assert.NilError(t, err)
-	assert.Equal(t, cr.GetID(), int64(666))
-}
-
 func TestGithubVCS_CreateStatus(t *testing.T) {
 	checkrunid := int64(2026)
 	resultid := int64(666)
@@ -707,53 +770,3 @@ func TestGithubVCS_CreateStatus(t *testing.T) {
 		})
 	}
 }
-
-func TestGithubVCSGetSHACommitTitle(t *testing.T) {
-	tests := []struct {
-		runinfo *RunInfo
-		message string
-		name    string
-		want    string
-		wantErr bool
-	}{
-		{
-			runinfo: &RunInfo{
-				SHA:        "sha",
-				Owner:      "owner",
-				Repository: "repo",
-			},
-			message: `Message\n\nFooBar`,
-			name:    "Get only title multiple lines",
-			want:    "Message",
-			wantErr: false,
-		},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			fakeclient, mux, _, teardown := ghtesthelper.SetupGH()
-			defer teardown()
-
-			mux.HandleFunc(
-				fmt.Sprintf("/repos/%s/%s/commits/%s", tt.runinfo.Owner,
-					tt.runinfo.Repository,
-					tt.runinfo.SHA),
-				func(w http.ResponseWriter, r *http.Request) {
-					_, _ = fmt.Fprintf(w, `{"commit": {"message": "%s"}}`, tt.message)
-				})
-
-			ctx, _ := rtesting.SetupFakeContext(t)
-			gvcs := GithubVCS{
-				Client: fakeclient,
-			}
-			got, err := gvcs.GetSHACommitTitle(ctx, tt.runinfo)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("GithubVCS.GetSHACommitTitle() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("GithubVCS.GetSHACommitTitle() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
diff --git a/pkg/webvcs/testdata/pull_request_with_newlines.json b/pkg/webvcs/testdata/pull_request_with_newlines.json
index 0423c295..faa2e317 100644
--- a/pkg/webvcs/testdata/pull_request_with_newlines.json
+++ b/pkg/webvcs/testdata/pull_request_with_newlines.json
@@ -1,3 +1,3 @@
-{"action":"opened","installation":{"id":16557439,"node_id":"MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTY1NTc0Mzk="},"number":3,"organization":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","description":"","events_url":"https://api.github.com/orgs/repo/events","hooks_url":"https://api.github.com/orgs/repo/hooks","id":57996262,"issues_url":"https://api.github.com/orgs/repo/issues","login":"repo","members_url":"https://api.github.com/orgs/repo/members{/member}","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","public_members_url":"https://api.github.com/orgs/repo/public_members{/member}","repos_url":"https://api.github.com/orgs/repo/repos","url":"https://api.github.com/orgs/repo"},"pull_request":{"_links":{"comments":{"href":"https://api.github.com/repos/repo/owner/issues/3/comments"},"commits":{"href":"https://api.github.com/repos/repo/owner/pulls/3/commits"},"html":{"href":"https://github.com/repo/owner/pull/3"},"issue":{"href":"https://api.github.com/repos/repo/owner/issues/3"},"review_comment":{"href":"https://api.github.com/repos/repo/owner/pulls/comments{/number}"},"review_comments":{"href":"https://api.github.com/repos/repo/owner/pulls/3/comments"},"self":{"href":"https://api.github.com/repos/repo/owner/pulls/3"},"statuses":{"href":"https://api.github.com/repos/repo/owner/statuses/SHA"}},"active_lock_reason":null,"additions":38,"assignee":null,"assignees":[],"author_association":"MEMBER","auto_merge":null,"base":{"label":"repo:main","ref":"main","repo":{"allow_merge_commit":true,"allow_rebase_merge":true,"allow_squash_merge":true,"archive_url":"https://api.github.com/repos/repo/owner/{archive_format}{/ref}","archived":false,"assignees_url":"https://api.github.com/repos/repo/owner/assignees{/user}","blobs_url":"https://api.github.com/repos/repo/owner/git/blobs{/sha}","branches_url":"https://api.github.com/repos/repo/owner/branches{/branch}","clone_url":"https://github.com/repo/owner.git","collaborators_url":"https://api.github.com/repos/repo/owner/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/repo/owner/comments{/number}","commits_url":"https://api.github.com/repos/repo/owner/commits{/sha}","compare_url":"https://api.github.com/repos/repo/owner/compare/{base}...{head}","contents_url":"https://api.github.com/repos/repo/owner/contents/{+path}","contributors_url":"https://api.github.com/repos/repo/owner/contributors","created_at":"2021-04-06T13:26:01Z","default_branch":"main","delete_branch_on_merge":false,"deployments_url":"https://api.github.com/repos/repo/owner/deployments","description":"Pipelines as Code","disabled":false,"downloads_url":"https://api.github.com/repos/repo/owner/downloads","events_url":"https://api.github.com/repos/repo/owner/events","fork":false,"forks":3,"forks_count":3,"forks_url":"https://api.github.com/repos/repo/owner/forks","full_name":"repo/owner","git_commits_url":"https://api.github.com/repos/repo/owner/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/repo/owner/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/repo/owner/git/tags{/sha}","git_url":"git://github.com/repo/owner.git","has_downloads":true,"has_issues":true,"has_pages":false,"has_projects":true,"has_wiki":true,"homepage":null,"hooks_url":"https://api.github.com/repos/repo/owner/hooks","html_url":"https://github.com/repo/owner","id":355197825,"issue_comment_url":"https://api.github.com/repos/repo/owner/issues/comments{/number}","issue_events_url":"https://api.github.com/repos/repo/owner/issues/events{/number}","issues_url":"https://api.github.com/repos/repo/owner/issues{/number}","keys_url":"https://api.github.com/repos/repo/owner/keys{/key_id}","labels_url":"https://api.github.com/repos/repo/owner/labels{/name}","language":"Go","languages_url":"https://api.github.com/repos/repo/owner/languages","license":{"key":"apache-2.0","name":"Apache License 2.0","node_id":"MDc6TGljZW5zZTI=","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"merges_url":"https://api.github.com/repos/repo/owner/merges","milestones_url":"https://api.github.com/repos/repo/owner/milestones{/number}","mirror_url":null,"name":"owner","node_id":"MDEwOlJlcG9zaXRvcnkzNTUxOTc4MjU=","notifications_url":"https://api.github.com/repos/repo/owner/notifications{?since,all,participating}","open_issues":1,"open_issues_count":1,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","events_url":"https://api.github.com/users/repo/events{/privacy}","followers_url":"https://api.github.com/users/repo/followers","following_url":"https://api.github.com/users/repo/following{/other_user}","gists_url":"https://api.github.com/users/repo/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/repo","id":57996262,"login":"repo","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","organizations_url":"https://api.github.com/users/repo/orgs","received_events_url":"https://api.github.com/users/repo/received_events","repos_url":"https://api.github.com/users/repo/repos","site_admin":false,"starred_url":"https://api.github.com/users/repo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/repo/subscriptions","type":"Organization","url":"https://api.github.com/users/repo"},"private":false,"pulls_url":"https://api.github.com/repos/repo/owner/pulls{/number}","pushed_at":"2021-04-27T16:10:20Z","releases_url":"https://api.github.com/repos/repo/owner/releases{/id}","size":9122,"ssh_url":"git@github.com:repo/owner.git","stargazers_count":1,"stargazers_url":"https://api.github.com/repos/repo/owner/stargazers","statuses_url":"https://api.github.com/repos/repo/owner/statuses/{sha}","subscribers_url":"https://api.github.com/repos/repo/owner/subscribers","subscription_url":"https://api.github.com/repos/repo/owner/subscription","svn_url":"https://github.com/repo/owner","tags_url":"https://api.github.com/repos/repo/owner/tags","teams_url":"https://api.github.com/repos/repo/owner/teams","trees_url":"https://api.github.com/repos/repo/owner/git/trees{/sha}","updated_at":"2021-04-27T16:10:24Z","url":"https://api.github.com/repos/repo/owner","watchers":1,"watchers_count":1},"sha":"SHA","user":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","events_url":"https://api.github.com/users/repo/events{/privacy}","followers_url":"https://api.github.com/users/repo/followers","following_url":"https://api.github.com/users/repo/following{/other_user}","gists_url":"https://api.github.com/users/repo/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/repo","id":57996262,"login":"repo","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","organizations_url":"https://api.github.com/users/repo/orgs","received_events_url":"https://api.github.com/users/repo/received_events","repos_url":"https://api.github.com/users/repo/repos","site_admin":false,"starred_url":"https://api.github.com/users/repo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/repo/subscriptions","type":"Organization","url":"https://api.github.com/users/repo"}},"body":"- Fix linting error  in payload Replace
+{"action":"opened","installation":{"id":16557439,"node_id":"MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTY1NTc0Mzk="},"number":3,"organization":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","description":"","events_url":"https://api.github.com/orgs/openshift-pipelines/events","hooks_url":"https://api.github.com/orgs/openshift-pipelines/hooks","id":57996262,"issues_url":"https://api.github.com/orgs/openshift-pipelines/issues","login":"openshift-pipelines","members_url":"https://api.github.com/orgs/openshift-pipelines/members{/member}","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","public_members_url":"https://api.github.com/orgs/openshift-pipelines/public_members{/member}","repos_url":"https://api.github.com/orgs/openshift-pipelines/repos","url":"https://api.github.com/orgs/openshift-pipelines"},"pull_request":{"_links":{"comments":{"href":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/3/comments"},"commits":{"href":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/3/commits"},"html":{"href":"https://github.com/openshift-pipelines/pipelines-as-code/pull/3"},"issue":{"href":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/3"},"review_comment":{"href":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/comments{/number}"},"review_comments":{"href":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/3/comments"},"self":{"href":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/3"},"statuses":{"href":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/statuses/857cfa78d2f1f273013702e7151514f4f27d9291"}},"active_lock_reason":null,"additions":38,"assignee":null,"assignees":[],"author_association":"MEMBER","auto_merge":null,"base":{"label":"openshift-pipelines:main","ref":"main","repo":{"allow_merge_commit":true,"allow_rebase_merge":true,"allow_squash_merge":true,"archive_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/{archive_format}{/ref}","archived":false,"assignees_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/assignees{/user}","blobs_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/blobs{/sha}","branches_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/branches{/branch}","clone_url":"https://github.com/openshift-pipelines/pipelines-as-code.git","collaborators_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/comments{/number}","commits_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/commits{/sha}","compare_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/compare/{base}...{head}","contents_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/contents/{+path}","contributors_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/contributors","created_at":"2021-04-06T13:26:01Z","default_branch":"main","delete_branch_on_merge":false,"deployments_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/deployments","description":"Pipelines as Code","disabled":false,"downloads_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/downloads","events_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/events","fork":false,"forks":3,"forks_count":3,"forks_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/forks","full_name":"openshift-pipelines/pipelines-as-code","git_commits_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/tags{/sha}","git_url":"git://github.com/openshift-pipelines/pipelines-as-code.git","has_downloads":true,"has_issues":true,"has_pages":false,"has_projects":true,"has_wiki":true,"homepage":null,"hooks_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/hooks","html_url":"https://github.com/openshift-pipelines/pipelines-as-code","id":355197825,"issue_comment_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/comments{/number}","issue_events_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/events{/number}","issues_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues{/number}","keys_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/keys{/key_id}","labels_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/labels{/name}","language":"Go","languages_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/languages","license":{"key":"apache-2.0","name":"Apache License 2.0","node_id":"MDc6TGljZW5zZTI=","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"merges_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/merges","milestones_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/milestones{/number}","mirror_url":null,"name":"pipelines-as-code","node_id":"MDEwOlJlcG9zaXRvcnkzNTUxOTc4MjU=","notifications_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/notifications{?since,all,participating}","open_issues":1,"open_issues_count":1,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","events_url":"https://api.github.com/users/openshift-pipelines/events{/privacy}","followers_url":"https://api.github.com/users/openshift-pipelines/followers","following_url":"https://api.github.com/users/openshift-pipelines/following{/other_user}","gists_url":"https://api.github.com/users/openshift-pipelines/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/openshift-pipelines","id":57996262,"login":"openshift-pipelines","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","organizations_url":"https://api.github.com/users/openshift-pipelines/orgs","received_events_url":"https://api.github.com/users/openshift-pipelines/received_events","repos_url":"https://api.github.com/users/openshift-pipelines/repos","site_admin":false,"starred_url":"https://api.github.com/users/openshift-pipelines/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift-pipelines/subscriptions","type":"Organization","url":"https://api.github.com/users/openshift-pipelines"},"private":false,"pulls_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls{/number}","pushed_at":"2021-04-27T16:10:20Z","releases_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/releases{/id}","size":9122,"ssh_url":"git@github.com:openshift-pipelines/pipelines-as-code.git","stargazers_count":1,"stargazers_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/stargazers","statuses_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/statuses/{sha}","subscribers_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/subscribers","subscription_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/subscription","svn_url":"https://github.com/openshift-pipelines/pipelines-as-code","tags_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/tags","teams_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/teams","trees_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/trees{/sha}","updated_at":"2021-04-27T16:10:24Z","url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code","watchers":1,"watchers_count":1},"sha":"70e8fe5a8caa7c82239622090b5c141e63c033e6","user":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","events_url":"https://api.github.com/users/openshift-pipelines/events{/privacy}","followers_url":"https://api.github.com/users/openshift-pipelines/followers","following_url":"https://api.github.com/users/openshift-pipelines/following{/other_user}","gists_url":"https://api.github.com/users/openshift-pipelines/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/openshift-pipelines","id":57996262,"login":"openshift-pipelines","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","organizations_url":"https://api.github.com/users/openshift-pipelines/orgs","received_events_url":"https://api.github.com/users/openshift-pipelines/received_events","repos_url":"https://api.github.com/users/openshift-pipelines/repos","site_admin":false,"starred_url":"https://api.github.com/users/openshift-pipelines/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift-pipelines/subscriptions","type":"Organization","url":"https://api.github.com/users/openshift-pipelines"}},"body":"- Fix linting error  in payload Replace
 - Resolve pipelinespec embedded in PipelineRun too
-","changed_files":3,"closed_at":null,"comments":0,"comments_url":"https://api.github.com/repos/repo/owner/issues/3/comments","commits":2,"commits_url":"https://api.github.com/repos/repo/owner/pulls/3/commits","created_at":"2021-04-27T19:26:47Z","deletions":26,"diff_url":"https://github.com/repo/owner/pull/3.diff","draft":false,"head":{"label":"chmouel:fix-resolve-pipelinespec","ref":"fix-resolve-pipelinespec","repo":{"allow_merge_commit":true,"allow_rebase_merge":true,"allow_squash_merge":true,"archive_url":"https://api.github.com/repos/chmouel/owner/{archive_format}{/ref}","archived":false,"assignees_url":"https://api.github.com/repos/chmouel/owner/assignees{/user}","blobs_url":"https://api.github.com/repos/chmouel/owner/git/blobs{/sha}","branches_url":"https://api.github.com/repos/chmouel/owner/branches{/branch}","clone_url":"https://github.com/chmouel/owner.git","collaborators_url":"https://api.github.com/repos/chmouel/owner/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/chmouel/owner/comments{/number}","commits_url":"https://api.github.com/repos/chmouel/owner/commits{/sha}","compare_url":"https://api.github.com/repos/chmouel/owner/compare/{base}...{head}","contents_url":"https://api.github.com/repos/chmouel/owner/contents/{+path}","contributors_url":"https://api.github.com/repos/chmouel/owner/contributors","created_at":"2021-04-06T13:26:51Z","default_branch":"main","delete_branch_on_merge":false,"deployments_url":"https://api.github.com/repos/chmouel/owner/deployments","description":"Pipelines as Code","disabled":false,"downloads_url":"https://api.github.com/repos/chmouel/owner/downloads","events_url":"https://api.github.com/repos/chmouel/owner/events","fork":true,"forks":0,"forks_count":0,"forks_url":"https://api.github.com/repos/chmouel/owner/forks","full_name":"chmouel/owner","git_commits_url":"https://api.github.com/repos/chmouel/owner/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/chmouel/owner/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/chmouel/owner/git/tags{/sha}","git_url":"git://github.com/chmouel/owner.git","has_downloads":true,"has_issues":false,"has_pages":false,"has_projects":true,"has_wiki":true,"homepage":null,"hooks_url":"https://api.github.com/repos/chmouel/owner/hooks","html_url":"https://github.com/chmouel/owner","id":355198074,"issue_comment_url":"https://api.github.com/repos/chmouel/owner/issues/comments{/number}","issue_events_url":"https://api.github.com/repos/chmouel/owner/issues/events{/number}","issues_url":"https://api.github.com/repos/chmouel/owner/issues{/number}","keys_url":"https://api.github.com/repos/chmouel/owner/keys{/key_id}","labels_url":"https://api.github.com/repos/chmouel/owner/labels{/name}","language":null,"languages_url":"https://api.github.com/repos/chmouel/owner/languages","license":{"key":"apache-2.0","name":"Apache License 2.0","node_id":"MDc6TGljZW5zZTI=","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"merges_url":"https://api.github.com/repos/chmouel/owner/merges","milestones_url":"https://api.github.com/repos/chmouel/owner/milestones{/number}","mirror_url":null,"name":"owner","node_id":"MDEwOlJlcG9zaXRvcnkzNTUxOTgwNzQ=","notifications_url":"https://api.github.com/repos/chmouel/owner/notifications{?since,all,participating}","open_issues":0,"open_issues_count":0,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"},"private":false,"pulls_url":"https://api.github.com/repos/chmouel/owner/pulls{/number}","pushed_at":"2021-04-27T19:26:46Z","releases_url":"https://api.github.com/repos/chmouel/owner/releases{/id}","size":5,"ssh_url":"git@github.com:chmouel/owner.git","stargazers_count":0,"stargazers_url":"https://api.github.com/repos/chmouel/owner/stargazers","statuses_url":"https://api.github.com/repos/chmouel/owner/statuses/{sha}","subscribers_url":"https://api.github.com/repos/chmouel/owner/subscribers","subscription_url":"https://api.github.com/repos/chmouel/owner/subscription","svn_url":"https://github.com/chmouel/owner","tags_url":"https://api.github.com/repos/chmouel/owner/tags","teams_url":"https://api.github.com/repos/chmouel/owner/teams","trees_url":"https://api.github.com/repos/chmouel/owner/git/trees{/sha}","updated_at":"2021-04-06T15:19:15Z","url":"https://api.github.com/repos/chmouel/owner","watchers":0,"watchers_count":0},"sha":"SHA","user":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"}},"html_url":"https://github.com/repo/owner/pull/3","id":624596967,"issue_url":"https://api.github.com/repos/repo/owner/issues/3","labels":[],"locked":false,"maintainer_can_modify":true,"merge_commit_sha":null,"mergeable":null,"mergeable_state":"unknown","merged":false,"merged_at":null,"merged_by":null,"milestone":null,"node_id":"MDExOlB1bGxSZXF1ZXN0NjI0NTk2OTY3","number":3,"patch_url":"https://github.com/repo/owner/pull/3.patch","rebaseable":null,"requested_reviewers":[],"requested_teams":[],"review_comment_url":"https://api.github.com/repos/repo/owner/pulls/comments{/number}","review_comments":0,"review_comments_url":"https://api.github.com/repos/repo/owner/pulls/3/comments","state":"open","statuses_url":"https://api.github.com/repos/repo/owner/statuses/SHA","title":"fix resolve pipelinespec","updated_at":"2021-04-27T19:26:47Z","url":"https://api.github.com/repos/repo/owner/pulls/3","user":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"}},"repository":{"archive_url":"https://api.github.com/repos/repo/owner/{archive_format}{/ref}","archived":false,"assignees_url":"https://api.github.com/repos/repo/owner/assignees{/user}","blobs_url":"https://api.github.com/repos/repo/owner/git/blobs{/sha}","branches_url":"https://api.github.com/repos/repo/owner/branches{/branch}","clone_url":"https://github.com/repo/owner.git","collaborators_url":"https://api.github.com/repos/repo/owner/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/repo/owner/comments{/number}","commits_url":"https://api.github.com/repos/repo/owner/commits{/sha}","compare_url":"https://api.github.com/repos/repo/owner/compare/{base}...{head}","contents_url":"https://api.github.com/repos/repo/owner/contents/{+path}","contributors_url":"https://api.github.com/repos/repo/owner/contributors","created_at":"2021-04-06T13:26:01Z","default_branch":"main","deployments_url":"https://api.github.com/repos/repo/owner/deployments","description":"Pipelines as Code","disabled":false,"downloads_url":"https://api.github.com/repos/repo/owner/downloads","events_url":"https://api.github.com/repos/repo/owner/events","fork":false,"forks":3,"forks_count":3,"forks_url":"https://api.github.com/repos/repo/owner/forks","full_name":"repo/owner","git_commits_url":"https://api.github.com/repos/repo/owner/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/repo/owner/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/repo/owner/git/tags{/sha}","git_url":"git://github.com/repo/owner.git","has_downloads":true,"has_issues":true,"has_pages":false,"has_projects":true,"has_wiki":true,"homepage":null,"hooks_url":"https://api.github.com/repos/repo/owner/hooks","html_url":"https://github.com/repo/owner","id":355197825,"issue_comment_url":"https://api.github.com/repos/repo/owner/issues/comments{/number}","issue_events_url":"https://api.github.com/repos/repo/owner/issues/events{/number}","issues_url":"https://api.github.com/repos/repo/owner/issues{/number}","keys_url":"https://api.github.com/repos/repo/owner/keys{/key_id}","labels_url":"https://api.github.com/repos/repo/owner/labels{/name}","language":"Go","languages_url":"https://api.github.com/repos/repo/owner/languages","license":{"key":"apache-2.0","name":"Apache License 2.0","node_id":"MDc6TGljZW5zZTI=","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"merges_url":"https://api.github.com/repos/repo/owner/merges","milestones_url":"https://api.github.com/repos/repo/owner/milestones{/number}","mirror_url":null,"name":"owner","node_id":"MDEwOlJlcG9zaXRvcnkzNTUxOTc4MjU=","notifications_url":"https://api.github.com/repos/repo/owner/notifications{?since,all,participating}","open_issues":1,"open_issues_count":1,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","events_url":"https://api.github.com/users/repo/events{/privacy}","followers_url":"https://api.github.com/users/repo/followers","following_url":"https://api.github.com/users/repo/following{/other_user}","gists_url":"https://api.github.com/users/repo/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/repo","id":57996262,"login":"repo","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","organizations_url":"https://api.github.com/users/repo/orgs","received_events_url":"https://api.github.com/users/repo/received_events","repos_url":"https://api.github.com/users/repo/repos","site_admin":false,"starred_url":"https://api.github.com/users/repo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/repo/subscriptions","type":"Organization","url":"https://api.github.com/users/repo"},"private":false,"pulls_url":"https://api.github.com/repos/repo/owner/pulls{/number}","pushed_at":"2021-04-27T16:10:20Z","releases_url":"https://api.github.com/repos/repo/owner/releases{/id}","size":9122,"ssh_url":"git@github.com:repo/owner.git","stargazers_count":1,"stargazers_url":"https://api.github.com/repos/repo/owner/stargazers","statuses_url":"https://api.github.com/repos/repo/owner/statuses/{sha}","subscribers_url":"https://api.github.com/repos/repo/owner/subscribers","subscription_url":"https://api.github.com/repos/repo/owner/subscription","svn_url":"https://github.com/repo/owner","tags_url":"https://api.github.com/repos/repo/owner/tags","teams_url":"https://api.github.com/repos/repo/owner/teams","trees_url":"https://api.github.com/repos/repo/owner/git/trees{/sha}","updated_at":"2021-04-27T16:10:24Z","url":"https://api.github.com/repos/repo/owner","watchers":1,"watchers_count":1},"sender":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"}}
+","changed_files":3,"closed_at":null,"comments":0,"comments_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/3/comments","commits":2,"commits_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/3/commits","created_at":"2021-04-27T19:26:47Z","deletions":26,"diff_url":"https://github.com/openshift-pipelines/pipelines-as-code/pull/3.diff","draft":false,"head":{"label":"chmouel:fix-resolve-pipelinespec","ref":"fix-resolve-pipelinespec","repo":{"allow_merge_commit":true,"allow_rebase_merge":true,"allow_squash_merge":true,"archive_url":"https://api.github.com/repos/chmouel/pipelines-as-code/{archive_format}{/ref}","archived":false,"assignees_url":"https://api.github.com/repos/chmouel/pipelines-as-code/assignees{/user}","blobs_url":"https://api.github.com/repos/chmouel/pipelines-as-code/git/blobs{/sha}","branches_url":"https://api.github.com/repos/chmouel/pipelines-as-code/branches{/branch}","clone_url":"https://github.com/chmouel/pipelines-as-code.git","collaborators_url":"https://api.github.com/repos/chmouel/pipelines-as-code/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/chmouel/pipelines-as-code/comments{/number}","commits_url":"https://api.github.com/repos/chmouel/pipelines-as-code/commits{/sha}","compare_url":"https://api.github.com/repos/chmouel/pipelines-as-code/compare/{base}...{head}","contents_url":"https://api.github.com/repos/chmouel/pipelines-as-code/contents/{+path}","contributors_url":"https://api.github.com/repos/chmouel/pipelines-as-code/contributors","created_at":"2021-04-06T13:26:51Z","default_branch":"main","delete_branch_on_merge":false,"deployments_url":"https://api.github.com/repos/chmouel/pipelines-as-code/deployments","description":"Pipelines as Code","disabled":false,"downloads_url":"https://api.github.com/repos/chmouel/pipelines-as-code/downloads","events_url":"https://api.github.com/repos/chmouel/pipelines-as-code/events","fork":true,"forks":0,"forks_count":0,"forks_url":"https://api.github.com/repos/chmouel/pipelines-as-code/forks","full_name":"chmouel/pipelines-as-code","git_commits_url":"https://api.github.com/repos/chmouel/pipelines-as-code/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/chmouel/pipelines-as-code/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/chmouel/pipelines-as-code/git/tags{/sha}","git_url":"git://github.com/chmouel/pipelines-as-code.git","has_downloads":true,"has_issues":false,"has_pages":false,"has_projects":true,"has_wiki":true,"homepage":null,"hooks_url":"https://api.github.com/repos/chmouel/pipelines-as-code/hooks","html_url":"https://github.com/chmouel/pipelines-as-code","id":355198074,"issue_comment_url":"https://api.github.com/repos/chmouel/pipelines-as-code/issues/comments{/number}","issue_events_url":"https://api.github.com/repos/chmouel/pipelines-as-code/issues/events{/number}","issues_url":"https://api.github.com/repos/chmouel/pipelines-as-code/issues{/number}","keys_url":"https://api.github.com/repos/chmouel/pipelines-as-code/keys{/key_id}","labels_url":"https://api.github.com/repos/chmouel/pipelines-as-code/labels{/name}","language":null,"languages_url":"https://api.github.com/repos/chmouel/pipelines-as-code/languages","license":{"key":"apache-2.0","name":"Apache License 2.0","node_id":"MDc6TGljZW5zZTI=","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"merges_url":"https://api.github.com/repos/chmouel/pipelines-as-code/merges","milestones_url":"https://api.github.com/repos/chmouel/pipelines-as-code/milestones{/number}","mirror_url":null,"name":"pipelines-as-code","node_id":"MDEwOlJlcG9zaXRvcnkzNTUxOTgwNzQ=","notifications_url":"https://api.github.com/repos/chmouel/pipelines-as-code/notifications{?since,all,participating}","open_issues":0,"open_issues_count":0,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"},"private":false,"pulls_url":"https://api.github.com/repos/chmouel/pipelines-as-code/pulls{/number}","pushed_at":"2021-04-27T19:26:46Z","releases_url":"https://api.github.com/repos/chmouel/pipelines-as-code/releases{/id}","size":5,"ssh_url":"git@github.com:chmouel/pipelines-as-code.git","stargazers_count":0,"stargazers_url":"https://api.github.com/repos/chmouel/pipelines-as-code/stargazers","statuses_url":"https://api.github.com/repos/chmouel/pipelines-as-code/statuses/{sha}","subscribers_url":"https://api.github.com/repos/chmouel/pipelines-as-code/subscribers","subscription_url":"https://api.github.com/repos/chmouel/pipelines-as-code/subscription","svn_url":"https://github.com/chmouel/pipelines-as-code","tags_url":"https://api.github.com/repos/chmouel/pipelines-as-code/tags","teams_url":"https://api.github.com/repos/chmouel/pipelines-as-code/teams","trees_url":"https://api.github.com/repos/chmouel/pipelines-as-code/git/trees{/sha}","updated_at":"2021-04-06T15:19:15Z","url":"https://api.github.com/repos/chmouel/pipelines-as-code","watchers":0,"watchers_count":0},"sha":"857cfa78d2f1f273013702e7151514f4f27d9291","user":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"}},"html_url":"https://github.com/openshift-pipelines/pipelines-as-code/pull/3","id":624596967,"issue_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/3","labels":[],"locked":false,"maintainer_can_modify":true,"merge_commit_sha":null,"mergeable":null,"mergeable_state":"unknown","merged":false,"merged_at":null,"merged_by":null,"milestone":null,"node_id":"MDExOlB1bGxSZXF1ZXN0NjI0NTk2OTY3","number":3,"patch_url":"https://github.com/openshift-pipelines/pipelines-as-code/pull/3.patch","rebaseable":null,"requested_reviewers":[],"requested_teams":[],"review_comment_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/comments{/number}","review_comments":0,"review_comments_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/3/comments","state":"open","statuses_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/statuses/857cfa78d2f1f273013702e7151514f4f27d9291","title":"fix resolve pipelinespec","updated_at":"2021-04-27T19:26:47Z","url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls/3","user":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"}},"repository":{"archive_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/{archive_format}{/ref}","archived":false,"assignees_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/assignees{/user}","blobs_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/blobs{/sha}","branches_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/branches{/branch}","clone_url":"https://github.com/openshift-pipelines/pipelines-as-code.git","collaborators_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/comments{/number}","commits_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/commits{/sha}","compare_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/compare/{base}...{head}","contents_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/contents/{+path}","contributors_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/contributors","created_at":"2021-04-06T13:26:01Z","default_branch":"main","deployments_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/deployments","description":"Pipelines as Code","disabled":false,"downloads_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/downloads","events_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/events","fork":false,"forks":3,"forks_count":3,"forks_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/forks","full_name":"openshift-pipelines/pipelines-as-code","git_commits_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/tags{/sha}","git_url":"git://github.com/openshift-pipelines/pipelines-as-code.git","has_downloads":true,"has_issues":true,"has_pages":false,"has_projects":true,"has_wiki":true,"homepage":null,"hooks_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/hooks","html_url":"https://github.com/openshift-pipelines/pipelines-as-code","id":355197825,"issue_comment_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/comments{/number}","issue_events_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues/events{/number}","issues_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/issues{/number}","keys_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/keys{/key_id}","labels_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/labels{/name}","language":"Go","languages_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/languages","license":{"key":"apache-2.0","name":"Apache License 2.0","node_id":"MDc6TGljZW5zZTI=","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"merges_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/merges","milestones_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/milestones{/number}","mirror_url":null,"name":"pipelines-as-code","node_id":"MDEwOlJlcG9zaXRvcnkzNTUxOTc4MjU=","notifications_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/notifications{?since,all,participating}","open_issues":1,"open_issues_count":1,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/57996262?v=4","events_url":"https://api.github.com/users/openshift-pipelines/events{/privacy}","followers_url":"https://api.github.com/users/openshift-pipelines/followers","following_url":"https://api.github.com/users/openshift-pipelines/following{/other_user}","gists_url":"https://api.github.com/users/openshift-pipelines/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/openshift-pipelines","id":57996262,"login":"openshift-pipelines","node_id":"MDEyOk9yZ2FuaXphdGlvbjU3OTk2MjYy","organizations_url":"https://api.github.com/users/openshift-pipelines/orgs","received_events_url":"https://api.github.com/users/openshift-pipelines/received_events","repos_url":"https://api.github.com/users/openshift-pipelines/repos","site_admin":false,"starred_url":"https://api.github.com/users/openshift-pipelines/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openshift-pipelines/subscriptions","type":"Organization","url":"https://api.github.com/users/openshift-pipelines"},"private":false,"pulls_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/pulls{/number}","pushed_at":"2021-04-27T16:10:20Z","releases_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/releases{/id}","size":9122,"ssh_url":"git@github.com:openshift-pipelines/pipelines-as-code.git","stargazers_count":1,"stargazers_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/stargazers","statuses_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/statuses/{sha}","subscribers_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/subscribers","subscription_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/subscription","svn_url":"https://github.com/openshift-pipelines/pipelines-as-code","tags_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/tags","teams_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/teams","trees_url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code/git/trees{/sha}","updated_at":"2021-04-27T16:10:24Z","url":"https://api.github.com/repos/openshift-pipelines/pipelines-as-code","watchers":1,"watchers_count":1},"sender":{"avatar_url":"https://avatars.githubusercontent.com/u/98980?v=4","events_url":"https://api.github.com/users/chmouel/events{/privacy}","followers_url":"https://api.github.com/users/chmouel/followers","following_url":"https://api.github.com/users/chmouel/following{/other_user}","gists_url":"https://api.github.com/users/chmouel/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/chmouel","id":98980,"login":"chmouel","node_id":"MDQ6VXNlcjk4OTgw","organizations_url":"https://api.github.com/users/chmouel/orgs","received_events_url":"https://api.github.com/users/chmouel/received_events","repos_url":"https://api.github.com/users/chmouel/repos","site_admin":false,"starred_url":"https://api.github.com/users/chmouel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chmouel/subscriptions","type":"User","url":"https://api.github.com/users/chmouel"}}