From 94ec9c2bac9d82a33644817f72f019cab9d53ba9 Mon Sep 17 00:00:00 2001 From: Chmouel Boudjnah Date: Tue, 28 Jan 2025 16:58:02 +0100 Subject: [PATCH] feat: add support for authenticated git clone Added support for authenticated git cloning using `gitToken` and `gitTokenKey` parameters. Updated documentation to reflect the new parameters and their usage. Modified resolver functions to handle authentication when cloning repositories. Added tests to verify the functionality of authenticated git cloning. The differences between the two modes are: - The `git clone` method support anonymous cloning and authenticated cloning. - Depending of the Git provider `git clone` has a lower rate limit (if none) than the authenticated API. - The authenticated API supports private repositories and fetches only the file at the specified path rather than doing a full clone. Signed-off-by: Chmouel Boudjnah --- docs/git-resolver.md | 82 +++++++++----- pkg/remoteresolution/resolver/git/resolver.go | 12 +- pkg/resolution/resolver/git/config.go | 1 + pkg/resolution/resolver/git/params.go | 4 + pkg/resolution/resolver/git/resolver.go | 106 +++++++++++++----- pkg/resolution/resolver/git/resolver_test.go | 62 ++++++++-- tools/go.sum | 5 + 7 files changed, 204 insertions(+), 68 deletions(-) diff --git a/docs/git-resolver.md b/docs/git-resolver.md index 826f9a9c0f9..2a1594f8dbc 100644 --- a/docs/git-resolver.md +++ b/docs/git-resolver.md @@ -13,17 +13,19 @@ This Resolver responds to type `git`. ## Parameters -| Param Name | Description | Example Value | -|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------| -| `url` | URL of the repo to fetch and clone anonymously. Either `url`, or `repo` (with `org`) must be specified, but not both. | `https://github.com/tektoncd/catalog.git` | -| `repo` | The repository to find the resource in. Either `url`, or `repo` (with `org`) must be specified, but not both. | `pipeline`, `test-infra` | -| `org` | The organization to find the repository in. Default can be set in [configuration](#configuration). | `tektoncd`, `kubernetes` | -| `token` | An optional secret name in the `PipelineRun` namespace to fetch the token from. Defaults to empty, meaning it will try to use the configuration from the global configmap. | `secret-name`, (empty) | -| `tokenKey` | An optional key in the token secret name in the `PipelineRun` namespace to fetch the token from. Defaults to `token`. | `token` | -| `revision` | Git revision to checkout a file from. This can be commit SHA, branch or tag. | `aeb957601cf41c012be462827053a21a420befca` `main` `v0.38.2` | -| `pathInRepo` | Where to find the file in the repo. | `task/golang-build/0.3/golang-build.yaml` | -| `serverURL` | An optional server URL (that includes the https:// prefix) to connect for API operations | `https:/github.mycompany.com` | -| `scmType` | An optional SCM type to use for API operations | `github`, `gitlab`, `gitea` | +| Param Name | Description | Example Value | +|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------| +| `url` | URL of the repo to fetch and clone anonymously. Either `url`, or `repo` (with `org`) must be specified, but not both. | `https://github.com/tektoncd/catalog.git` | +| `repo` | The repository to find the resource in. Either `url`, or `repo` (with `org`) must be specified, but not both. | `pipeline`, `test-infra` | +| `org` | The organization to find the repository in. Default can be set in [configuration](#configuration). | `tektoncd`, `kubernetes` | +| `token` | An optional secret name in the `PipelineRun` namespace to fetch the token from. Defaults to empty, meaning it will try to use the configuration from the global configmap. | `secret-name`, (empty) | +| `tokenKey` | An optional key in the token secret name in the `PipelineRun` namespace to fetch the token from. Defaults to `token`. | `token` | +| `gitToken` | An optional secret name in the `PipelineRun` namespace to fetch the token from when doing opration with the `git clone`. When empty it will use anonymous cloning. | `secret-gitauth-token` | +| `gitTokenKey` | An optional key in the token secret name in the `PipelineRun` namespace to fetch the token from when using the `git clone`. Defaults to `token`. | `token` | +| `revision` | Git revision to checkout a file from. This can be commit SHA, branch or tag. | `aeb957601cf41c012be462827053a21a420befca` `main` `v0.38.2` | +| `pathInRepo` | Where to find the file in the repo. | `task/golang-build/0.3/golang-build.yaml` | +| `serverURL` | An optional server URL (that includes the https:// prefix) to connect for API operations | `https:/github.mycompany.com` | +| `scmType` | An optional SCM type to use for API operations | `github`, `gitlab`, `gitea` | ## Requirements @@ -55,11 +57,25 @@ for the name, namespace and defaults that the resolver ships with. ## Usage -The `git` resolver has two modes: cloning a repository anonymously, or fetching individual files via an SCM provider's API using an API token. +The `git` resolver has two modes: cloning a repository with `git clone` (with +the `go-git` library), or fetching individual files via an SCM provider's API +using an API token. -### Anonymous Cloning +The differences between the two modes are: -Anonymous cloning is supported only for public repositories. This mode clones the full git repo. +- The `git clone` method support anonymous cloning and authenticated cloning. +- When it comes to throughput, `git clone` is a more efficient option because + it is not subject to the same rate limits as API calls. This is a key + difference between the two modes: `git clone` supports both anonymous and + authenticated cloning, and depending on the Git provider, it often has a + higher rate limit compared to authenticated API calls. +- The `git clone` method is inefficient for larger repositories, as it clones the + entire repository in memory, whereas the authenticated API fetches only the + files at the specified path. + +### Git Clone with git clone + +Git clone with `git clone` is supported for anonymous and authenticated cloning. #### Task Resolution @@ -78,6 +94,11 @@ spec: value: main - name: pathInRepo value: task/git-clone/0.6/git-clone.yaml + # Uncomment the following lines to use a secret with a token + # - name: gitToken + # value: "secret-with-token" + # - name: gitTokenKey (optional, defaults to "token") + # value: "token" ``` #### Pipeline resolution @@ -97,6 +118,11 @@ spec: value: main - name: pathInRepo value: pipeline/simple/0.1/simple.yaml + # Uncomment the following lines to use a secret with a token + # - name: gitToken + # value: "secret-with-token" + # - name: gitTokenKey (optional, defaults to "token") + # value: "token" params: - name: name value: Ranni @@ -108,11 +134,12 @@ The authenticated API supports private repositories, and fetches only the file a When using the authenticated API, [providers with implementations in `go-scm`](https://github.com/jenkins-x/go-scm/tree/main/scm/driver) can be used. Note that not all `go-scm` implementations have been tested with the `git` resolver, but it is known to work with: - * github.com and GitHub Enterprise - * gitlab.com and self-hosted Gitlab - * Gitea - * BitBucket Server - * BitBucket Cloud + +- github.com and GitHub Enterprise +- gitlab.com and self-hosted Gitlab +- Gitea +- BitBucket Server +- BitBucket Cloud #### Task Resolution @@ -193,11 +220,11 @@ spec: ### Specifying Configuration for Multiple Git Providers -It is possible to specify configurations for multiple providers and even multiple configurations for same provider to use in +It is possible to specify configurations for multiple providers and even multiple configurations for same provider to use in different tekton resources. Firstly, details need to be added in configmap with the unique identifier key prefix. -To use them in tekton resources, pass the unique key mentioned in configmap as an extra param to resolver with key -`configKey` and value will be the unique key. If no `configKey` param is passed, `default` will be used. Default -configuration to be used for git resolver can be specified in configmap by either mentioning no unique identifier or +To use them in tekton resources, pass the unique key mentioned in configmap as an extra param to resolver with key +`configKey` and value will be the unique key. If no `configKey` param is passed, `default` will be used. Default +configuration to be used for git resolver can be specified in configmap by either mentioning no unique identifier or using identifier `default` **Note**: `configKey` should not contain `.` while specifying configurations in configmap @@ -253,7 +280,7 @@ data: #### Task Resolution -A specific configurations from the configMap can be selected by passing the parameter `configKey` with the value +A specific configurations from the configMap can be selected by passing the parameter `configKey` with the value matching one of the configuration keys used in the configMap. ```yaml @@ -304,17 +331,21 @@ spec: ``` ## `ResolutionRequest` Status + `ResolutionRequest.Status.RefSource` field captures the source where the remote resource came from. It includes the 3 subfields: `url`, `digest` and `entrypoint`. + - `url` - If users choose to use anonymous cloning, the url is just user-provided value for the `url` param in the [SPDX download format](https://spdx.github.io/spdx-spec/package-information/#77-package-download-location-field). - If scm api is used, it would be the clone URL of the repo fetched from scm repository service in the [SPDX download format](https://spdx.github.io/spdx-spec/package-information/#77-package-download-location-field). - `digest` - - The algorithm name is fixed "sha1", but subject to be changed to "sha256" once Git eventually uses SHA256 at some point later. See https://git-scm.com/docs/hash-function-transition for more details. + - The algorithm name is fixed "sha1", but subject to be changed to "sha256" once Git eventually uses SHA256 at some point later. See for more details. - The value is the actual commit sha at the moment of resolving the resource even if a user provides a tag/branch name for the param `revision`. - `entrypoint`: the user-provided value for the `path` param. Example: + - Pipeline Resolution + ```yaml apiVersion: tekton.dev/v1beta1 kind: PipelineRun @@ -333,6 +364,7 @@ spec: ``` - `ResolutionRequest` + ```yaml apiVersion: resolution.tekton.dev/v1alpha1 kind: ResolutionRequest diff --git a/pkg/remoteresolution/resolver/git/resolver.go b/pkg/remoteresolution/resolver/git/resolver.go index 3a3734d4fbf..1d4890ebc6d 100644 --- a/pkg/remoteresolution/resolver/git/resolver.go +++ b/pkg/remoteresolution/resolver/git/resolver.go @@ -119,11 +119,19 @@ func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSp return nil, err } + g := &git.GitResolver{ + KubeClient: r.kubeClient, + Logger: r.logger, + Cache: r.cache, + TTL: r.ttl, + Params: params, + } + if params[git.UrlParam] != "" { - return git.ResolveAnonymousGit(ctx, params) + return g.ResolveGitClone(ctx) } - return git.ResolveAPIGit(ctx, params, r.kubeClient, r.logger, r.cache, r.ttl, r.clientFunc) + return g.ResolveAPIGit(ctx, r.clientFunc) } // Remove this error once resolution of url has been implemented. return nil, errors.New("the Resolve method has not been implemented.") diff --git a/pkg/resolution/resolver/git/config.go b/pkg/resolution/resolver/git/config.go index 975166d637a..2f7b92cbc19 100644 --- a/pkg/resolution/resolver/git/config.go +++ b/pkg/resolution/resolver/git/config.go @@ -62,6 +62,7 @@ type ScmConfig struct { Org string `json:"default-org"` ServerURL string `json:"server-url"` SCMType string `json:"scm-type"` + GitToken string `json:"git-token"` APISecretName string `json:"api-token-secret-name"` APISecretKey string `json:"api-token-secret-key"` APISecretNamespace string `json:"api-token-secret-namespace"` diff --git a/pkg/resolution/resolver/git/params.go b/pkg/resolution/resolver/git/params.go index d7cd114d8d6..9f627ccbbd1 100644 --- a/pkg/resolution/resolver/git/params.go +++ b/pkg/resolution/resolver/git/params.go @@ -33,6 +33,10 @@ const ( TokenParam string = "token" // TokenKeyParam is an optional reference to a key in the TokenParam secret for SCM API authentication TokenKeyParam string = "tokenKey" + // GitTokenParam is an optional reference to a secret name when using go-git for git authentication + GitTokenParam string = "gitToken" + // GitTokenParam is an optional reference to a secret name when using go-git for git authentication + GitTokenKeyParam string = "gitTokenKey" // DefaultTokenKeyParam is the default key in the TokenParam secret for SCM API authentication DefaultTokenKeyParam string = "token" // scmTypeParam is an optional string overriding the scm-type configuration (ie: github, gitea, gitlab etc..) diff --git a/pkg/resolution/resolver/git/resolver.go b/pkg/resolution/resolver/git/resolver.go index 73815e96bbb..d490f0ca755 100644 --- a/pkg/resolution/resolver/git/resolver.go +++ b/pkg/resolution/resolver/git/resolver.go @@ -31,6 +31,8 @@ import ( "github.com/go-git/go-git/v5" gitcfg "github.com/go-git/go-git/v5/config" "github.com/go-git/go-git/v5/plumbing" + plumbTransport "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/storage/memory" "github.com/jenkins-x/go-scm/scm" "github.com/jenkins-x/go-scm/scm/factory" @@ -129,11 +131,19 @@ func (r *Resolver) Resolve(ctx context.Context, origParams []pipelinev1.Param) ( return nil, err } + g := &GitResolver{ + Params: params, + Logger: r.logger, + Cache: r.cache, + TTL: r.ttl, + KubeClient: r.kubeClient, + } + if params[UrlParam] != "" { - return ResolveAnonymousGit(ctx, params) + return g.ResolveGitClone(ctx) } - return ResolveAPIGit(ctx, params, r.kubeClient, r.logger, r.cache, r.ttl, r.clientFunc) + return g.ResolveAPIGit(ctx, r.clientFunc) } func ValidateParams(ctx context.Context, params []pipelinev1.Param) error { @@ -157,19 +167,27 @@ func validateRepoURL(url string) bool { return re.MatchString(url) } -func ResolveAnonymousGit(ctx context.Context, params map[string]string) (framework.ResolvedResource, error) { - conf, err := GetScmConfigForParamConfigKey(ctx, params) +type GitResolver struct { + Params map[string]string + Logger *zap.SugaredLogger + Cache *cache.LRUExpireCache + TTL time.Duration + KubeClient kubernetes.Interface +} + +func (g *GitResolver) ResolveGitClone(ctx context.Context) (framework.ResolvedResource, error) { + conf, err := GetScmConfigForParamConfigKey(ctx, g.Params) if err != nil { return nil, err } - repo := params[UrlParam] + repo := g.Params[UrlParam] if repo == "" { urlString := conf.URL if urlString == "" { return nil, errors.New("default Git Repo Url was not set during installation of the git resolver") } } - revision := params[RevisionParam] + revision := g.Params[RevisionParam] if revision == "" { revisionString := conf.Revision if revisionString == "" { @@ -180,6 +198,33 @@ func ResolveAnonymousGit(ctx context.Context, params map[string]string) (framewo cloneOpts := &git.CloneOptions{ URL: repo, } + + secretRef := &secretCacheKey{ + name: g.Params[GitTokenParam], + key: g.Params[GitTokenKeyParam], + } + if secretRef.name != "" { + if secretRef.key == "" { + secretRef.key = DefaultTokenKeyParam + } + secretRef.ns = common.RequestNamespace(ctx) + } else { + secretRef = nil + } + + auth := plumbTransport.AuthMethod(nil) + if secretRef != nil { + gitToken, err := g.getAPIToken(ctx, secretRef, GitTokenKeyParam) + if err != nil { + return nil, err + } + auth = &http.BasicAuth{ + Username: "git", + Password: string(gitToken), + } + cloneOpts.Auth = auth + } + filesystem := memfs.New() repository, err := git.Clone(memory.NewStorage(), filesystem, cloneOpts) if err != nil { @@ -190,6 +235,7 @@ func ResolveAnonymousGit(ctx context.Context, params map[string]string) (framewo refSpec := gitcfg.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/remotes/%s", revision, revision)) err = repository.Fetch(&git.FetchOptions{ RefSpecs: []gitcfg.RefSpec{refSpec}, + Auth: auth, }) if err != nil { var fetchErr git.NoMatchingRefSpecError @@ -215,7 +261,7 @@ func ResolveAnonymousGit(ctx context.Context, params map[string]string) (framewo return nil, fmt.Errorf("checkout error: %w", err) } - path := params[PathParam] + path := g.Params[PathParam] f, err := filesystem.Open(path) if err != nil { @@ -231,8 +277,8 @@ func ResolveAnonymousGit(ctx context.Context, params map[string]string) (framewo return &resolvedGitResource{ Revision: h.String(), Content: buf.Bytes(), - URL: params[UrlParam], - Path: params[PathParam], + URL: g.Params[UrlParam], + Path: g.Params[PathParam], }, nil } @@ -387,15 +433,15 @@ type secretCacheKey struct { key string } -func ResolveAPIGit(ctx context.Context, params map[string]string, kubeclient kubernetes.Interface, logger *zap.SugaredLogger, cache *cache.LRUExpireCache, ttl time.Duration, clientFunc func(string, string, string, ...factory.ClientOptionFunc) (*scm.Client, error)) (framework.ResolvedResource, error) { +func (g *GitResolver) ResolveAPIGit(ctx context.Context, clientFunc func(string, string, string, ...factory.ClientOptionFunc) (*scm.Client, error)) (framework.ResolvedResource, error) { // If we got here, the "repo" param was specified, so use the API approach - scmType, serverURL, err := getSCMTypeAndServerURL(ctx, params) + scmType, serverURL, err := getSCMTypeAndServerURL(ctx, g.Params) if err != nil { return nil, err } secretRef := &secretCacheKey{ - name: params[TokenParam], - key: params[TokenKeyParam], + name: g.Params[TokenParam], + key: g.Params[TokenKeyParam], } if secretRef.name != "" { if secretRef.key == "" { @@ -405,7 +451,7 @@ func ResolveAPIGit(ctx context.Context, params map[string]string, kubeclient kub } else { secretRef = nil } - apiToken, err := getAPIToken(ctx, secretRef, kubeclient, logger, cache, ttl, params) + apiToken, err := g.getAPIToken(ctx, secretRef, APISecretNameKey) if err != nil { return nil, err } @@ -414,9 +460,9 @@ func ResolveAPIGit(ctx context.Context, params map[string]string, kubeclient kub return nil, fmt.Errorf("failed to create SCM client: %w", err) } - orgRepo := fmt.Sprintf("%s/%s", params[OrgParam], params[RepoParam]) - path := params[PathParam] - ref := params[RevisionParam] + orgRepo := fmt.Sprintf("%s/%s", g.Params[OrgParam], g.Params[RepoParam]) + path := g.Params[PathParam] + ref := g.Params[RevisionParam] // fetch the actual content from a file in the repo content, _, err := scmClient.Contents.Find(ctx, orgRepo, path, ref) @@ -442,15 +488,15 @@ func ResolveAPIGit(ctx context.Context, params map[string]string, kubeclient kub return &resolvedGitResource{ Content: content.Data, Revision: commit.Sha, - Org: params[OrgParam], - Repo: params[RepoParam], + Org: g.Params[OrgParam], + Repo: g.Params[RepoParam], Path: content.Path, URL: repo.Clone, }, nil } -func getAPIToken(ctx context.Context, apiSecret *secretCacheKey, kubeclient kubernetes.Interface, logger *zap.SugaredLogger, cache *cache.LRUExpireCache, ttl time.Duration, params map[string]string) ([]byte, error) { - conf, err := GetScmConfigForParamConfigKey(ctx, params) +func (g *GitResolver) getAPIToken(ctx context.Context, apiSecret *secretCacheKey, key string) ([]byte, error) { + conf, err := GetScmConfigForParamConfigKey(ctx, g.Params) if err != nil { return nil, err } @@ -467,8 +513,8 @@ func getAPIToken(ctx context.Context, apiSecret *secretCacheKey, kubeclient kube if apiSecret.name == "" { apiSecret.name = conf.APISecretName if apiSecret.name == "" { - err := fmt.Errorf("cannot get API token, required when specifying '%s' param, '%s' not specified in config", RepoParam, APISecretNameKey) - logger.Info(err) + err := fmt.Errorf("cannot get API token, required when specifying '%s' param, '%s' not specified in config", RepoParam, key) + g.Logger.Info(err) return nil, err } } @@ -476,7 +522,7 @@ func getAPIToken(ctx context.Context, apiSecret *secretCacheKey, kubeclient kube apiSecret.key = conf.APISecretKey if apiSecret.key == "" { err := fmt.Errorf("cannot get API token, required when specifying '%s' param, '%s' not specified in config", RepoParam, APISecretKeyKey) - logger.Info(err) + g.Logger.Info(err) return nil, err } } @@ -488,32 +534,32 @@ func getAPIToken(ctx context.Context, apiSecret *secretCacheKey, kubeclient kube } if cacheSecret { - val, ok := cache.Get(apiSecret) + val, ok := g.Cache.Get(apiSecret) if ok { return val.([]byte), nil } } - secret, err := kubeclient.CoreV1().Secrets(apiSecret.ns).Get(ctx, apiSecret.name, metav1.GetOptions{}) + secret, err := g.KubeClient.CoreV1().Secrets(apiSecret.ns).Get(ctx, apiSecret.name, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { notFoundErr := fmt.Errorf("cannot get API token, secret %s not found in namespace %s", apiSecret.name, apiSecret.ns) - logger.Info(notFoundErr) + g.Logger.Info(notFoundErr) return nil, notFoundErr } wrappedErr := fmt.Errorf("error reading API token from secret %s in namespace %s: %w", apiSecret.name, apiSecret.ns, err) - logger.Info(wrappedErr) + g.Logger.Info(wrappedErr) return nil, wrappedErr } secretVal, ok := secret.Data[apiSecret.key] if !ok { err := fmt.Errorf("cannot get API token, key %s not found in secret %s in namespace %s", apiSecret.key, apiSecret.name, apiSecret.ns) - logger.Info(err) + g.Logger.Info(err) return nil, err } if cacheSecret { - cache.Add(apiSecret, secretVal, ttl) + g.Cache.Add(apiSecret, secretVal, ttl) } return secretVal, nil } diff --git a/pkg/resolution/resolver/git/resolver_test.go b/pkg/resolution/resolver/git/resolver_test.go index 9001ab27cbe..dd7bbf8ae86 100644 --- a/pkg/resolution/resolver/git/resolver_test.go +++ b/pkg/resolution/resolver/git/resolver_test.go @@ -280,17 +280,19 @@ func TestResolveNotEnabled(t *testing.T) { } type params struct { - url string - revision string - pathInRepo string - org string - repo string - token string - tokenKey string - namespace string - serverURL string - scmType string - configKey string + url string + revision string + pathInRepo string + org string + repo string + token string + tokenKey string + namespace string + serverURL string + scmType string + configKey string + gitToken string + gitTokenKey string } func TestResolve(t *testing.T) { @@ -419,6 +421,26 @@ func TestResolve(t *testing.T) { url: anonFakeRepoURL, }, expectedErr: createError(`error opening file "foo/non-exist": file does not exist`), + }, { + name: "clone: secret for git clone", + args: ¶ms{ + pathInRepo: "./released", + url: anonFakeRepoURL, + gitToken: "token-secret", + gitTokenKey: "token", + namespace: "foo", + }, + expectedCommitSHA: commitSHAsInAnonRepo[2], + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), + }, { + name: "clone: secret for git clone does not exist", + args: ¶ms{ + pathInRepo: "./released", + url: anonFakeRepoURL, + gitToken: "non-existent", + gitTokenKey: "token", + }, + expectedErr: createError(`cannot get API token, secret non-existent not found in namespace foo`), }, { name: "clone: revision does not exist", args: ¶ms{ @@ -721,9 +743,14 @@ func TestResolve(t *testing.T) { if tc.config[tc.configIdentifer+APISecretNameKey] != "" && tc.config[tc.configIdentifer+APISecretNamespaceKey] != "" && tc.config[tc.configIdentifer+APISecretKeyKey] != "" && tc.apiToken != "" { secretName, secretNameKey, secretNamespace = tc.config[tc.configIdentifer+APISecretNameKey], tc.config[tc.configIdentifer+APISecretKeyKey], tc.config[tc.configIdentifer+APISecretNamespaceKey] } + if tc.args.token != "" && tc.args.namespace != "" && tc.args.tokenKey != "" { secretName, secretNameKey, secretNamespace = tc.args.token, tc.args.tokenKey, tc.args.namespace } + + if tc.args.gitToken != "" && tc.args.gitTokenKey != "" && tc.args.namespace != "" { + secretName, secretNameKey, secretNamespace = tc.args.gitToken, tc.args.gitTokenKey, tc.args.namespace + } if secretName == "" || secretNameKey == "" || secretNamespace == "" { return } @@ -754,6 +781,9 @@ func createTestRepo(t *testing.T, commits []commitForRepo) (string, []string) { tempDir := t.TempDir() repo, err := git.PlainInit(tempDir, false) + if err != nil { + t.Fatalf("couldn't create test repo: %v", err) + } worktree, err := repo.Worktree() if err != nil { @@ -922,6 +952,16 @@ func createRequest(args *params) *v1beta1.ResolutionRequest { Name: UrlParam, Value: *pipelinev1.NewStructuredValues(args.url), }) + if args.gitToken != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: GitTokenParam, + Value: *pipelinev1.NewStructuredValues(args.gitToken), + }) + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: GitTokenKeyParam, + Value: *pipelinev1.NewStructuredValues(args.gitTokenKey), + }) + } } else { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ Name: RepoParam, diff --git a/tools/go.sum b/tools/go.sum index 1064b1b65bd..a698f871485 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -288,6 +288,7 @@ github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3 github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8= +github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs= github.com/hashicorp/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= @@ -412,6 +413,8 @@ github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5co github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= @@ -538,7 +541,9 @@ github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tdakkota/asciicheck v0.3.0 h1:LqDGgZdholxZMaJgpM6b0U9CFIjDCbFdUF00bDnBKOQ= github.com/tdakkota/asciicheck v0.3.0/go.mod h1:KoJKXuX/Z/lt6XzLo8WMBfQGzak0SrAKZlvRr4tg8Ac= +github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.20 h1:z/p8Ek55UdNvzt4TFn2zx2KscpW4rWqcnUrdmvWJj7E= github.com/tetafro/godot v1.4.20/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio=