From e229601014e3c7e13ac030c9905b96b773ead7fc Mon Sep 17 00:00:00 2001 From: Chmouel Boudjnah Date: Tue, 29 Aug 2023 14:04:43 +0200 Subject: [PATCH] Handle branch name with slash We need to handle branch name with slash in the name, eg: feature/branch The user can url encode it with the %2F character, and we are able to parse it properly. Fixes #1395 Signed-off-by: Chmouel Boudjnah --- docs/content/docs/guide/resolver.md | 9 +++++---- pkg/provider/github/github.go | 22 +++++++++++++++++++++- pkg/provider/github/github_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/docs/content/docs/guide/resolver.md b/docs/content/docs/guide/resolver.md index 93ba49d5b..027a3a9db 100644 --- a/docs/content/docs/guide/resolver.md +++ b/docs/content/docs/guide/resolver.md @@ -139,12 +139,13 @@ and the remote HTTP URLs is a referenced GitHub "blob" URL: -or a GitHub rawURL (rawurl reference is only working on public GitHub): +if the remote HTTP url has a slash (/) in the branch name you will need to html encode with the %20F character, eg: - - -It will be able to fetch the files from that private repository with the GitHub app token. +```text +https://github.com/organization/repository/blob/feature%20Fmainbranch/path/file +``` +It will be use the GitHub API with the generated token to fetch that file. This allows you to reference a task or a pipeline from a private repository easily. GitHub app token are scoped to the owner or organization where the repository is located. diff --git a/pkg/provider/github/github.go b/pkg/provider/github/github.go index b1080922d..faa6e2741 100644 --- a/pkg/provider/github/github.go +++ b/pkg/provider/github/github.go @@ -77,7 +77,14 @@ func detectGHERawURL(event *info.Event, taskHost string) bool { // splitGithubURL Take a Github url and split it with org/repo path ref, supports rawURL func splitGithubURL(event *info.Event, uri string) (string, string, string, string, error) { pURL, err := url.Parse(uri) - splitted := strings.Split(pURL.Path, "/") + if err != nil { + return "", "", "", "", fmt.Errorf("URL %s does not seem to be a proper provider url: %w", uri, err) + } + path := pURL.Path + if pURL.RawPath != "" { + path = pURL.RawPath + } + splitted := strings.Split(path, "/") if len(splitted) <= 3 { return "", "", "", "", fmt.Errorf("URL %s does not seem to be a proper provider url: %w", uri, err) } @@ -96,6 +103,19 @@ func splitGithubURL(event *info.Event, uri string) (string, string, string, stri default: return "", "", "", "", fmt.Errorf("cannot recognize task as a Github URL to fetch: %s", uri) } + // url decode the org, repo, ref and path + if spRef, err = url.QueryUnescape(spRef); err != nil { + return "", "", "", "", fmt.Errorf("cannot decode ref: %w", err) + } + if spPath, err = url.QueryUnescape(spPath); err != nil { + return "", "", "", "", fmt.Errorf("cannot decode path: %w", err) + } + if spOrg, err = url.QueryUnescape(spOrg); err != nil { + return "", "", "", "", fmt.Errorf("cannot decode org: %w", err) + } + if spRepo, err = url.QueryUnescape(spRepo); err != nil { + return "", "", "", "", fmt.Errorf("cannot decode repo: %w", err) + } return spOrg, spRepo, spPath, spRef, nil } diff --git a/pkg/provider/github/github_test.go b/pkg/provider/github/github_test.go index af6258093..a37b5bd81 100644 --- a/pkg/provider/github/github_test.go +++ b/pkg/provider/github/github_test.go @@ -119,6 +119,30 @@ func TestGithubSplitURL(t *testing.T) { wantRef: "main", wantPath: "testdatas/remote_task.yaml", }, + { + name: "Split URL with slash in branch", + url: "https://github.com/openshift-pipelines/pipelines-as-code/blob/feature%2Fbranch/testdatas/remote_task.yaml", + wantOrg: "openshift-pipelines", + wantRepo: "pipelines-as-code", + wantRef: "feature/branch", + wantPath: "testdatas/remote_task.yaml", + }, + { + name: "Split URL with encoding emoji in branch", + url: "https://github.com/openshift-pipelines/pipelines-as-code/blob/%F0%9F%99%83/filename.yaml", + wantOrg: "openshift-pipelines", + wantRepo: "pipelines-as-code", + wantRef: "🙃", + wantPath: "filename.yaml", + }, + { + name: "Split URL with url encoding emoji in filename", + url: "https://github.com/openshift-pipelines/pipelines-as-code/blob/branch/anemoji%F0%9F%99%83.yaml", + wantOrg: "openshift-pipelines", + wantRepo: "pipelines-as-code", + wantRef: "branch", + wantPath: "anemoji🙃.yaml", + }, { name: "Split raw URL", url: "https://raw.githubusercontent.com/openshift-pipelines/pipelines-as-code/main/testdatas/remote_task.yaml",