Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

TEP-0115: Add git revision resolution support in Git Resolver #75

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ spec:
resource:
- name: url
value: ${REPO_URL}
- name: branch
- name: revision
value: add-a-simple-pipeline
- name: path
value: pipeline.yaml
Expand Down
2 changes: 1 addition & 1 deletion gitresolver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ spec:
resource:
- name: url
value: https://github.com/sbwsg/catalog.git
- name: branch
- name: revision
value: main
- name: pathInRepo
value: pipeline/simple/0.1/simple.yaml
Expand Down
4 changes: 2 additions & 2 deletions gitresolver/config/git-resolver-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ data:
fetch-timeout: "1m"
# The git url to fetch the remote resource from.
default-url: "https://github.com/tektoncd/catalog.git"
# The git branch to fetch the remote resource from.
default-branch: "main"
# The git revision to fetch the remote resource from.
default-revision: "main"
4 changes: 2 additions & 2 deletions gitresolver/pkg/git/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ limitations under the License.
package git

const (
// AnnotationKeyCommitHash is the commit hash that was fetched
// AnnotationKeyRevision is the revision that was fetched
// from git
AnnotationKeyCommitHash = "commit"
AnnotationKeyRevision = "revision"
)
6 changes: 3 additions & 3 deletions gitresolver/pkg/git/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ const ConfigFieldTimeout = "fetch-timeout"
// the git url to fetch the remote resource from.
const ConfigURL = "default-url"

// ConfigBranch is the configuration field name for controlling
// the branch name to fetch the remote resource from.
const ConfigBranch = "default-branch"
// ConfigRevision is the configuration field name for controlling
// the revision to fetch the remote resource from.
const ConfigRevision = "default-revision"
7 changes: 2 additions & 5 deletions gitresolver/pkg/git/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,5 @@ const URLParam string = "url"
// PathParam is the pathInRepo into the git repo where a file is located
const PathParam string = "pathInRepo"

// CommitParam is the commit hash that a file should be fetched from
const CommitParam string = "commit"

// BranchParam is the git branch that a file should be fetched from
const BranchParam string = "branch"
// RevisionParam is the commit hash/branch/tag that a file should be fetched from
const RevisionParam string = "revision"
58 changes: 32 additions & 26 deletions gitresolver/pkg/git/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ package git
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"strings"
"time"

"github.com/go-git/go-billy/v5/memfs"
git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/storage/memory"
resolutioncommon "github.com/tektoncd/resolution/pkg/common"
Expand Down Expand Up @@ -88,10 +90,6 @@ func (r *Resolver) ValidateParams(_ context.Context, params map[string]string) e
return fmt.Errorf("missing %v", strings.Join(missing, ", "))
}

if params[CommitParam] != "" && params[BranchParam] != "" {
return fmt.Errorf("supplied both %q and %q", CommitParam, BranchParam)
}

// TODO(sbwsg): validate repo url is well-formed, git:// or https://
// TODO(sbwsg): validate pathInRepo is valid relative pathInRepo

Expand All @@ -107,50 +105,58 @@ func (r *Resolver) Resolve(ctx context.Context, params map[string]string) (frame
if urlString, ok := conf[ConfigURL]; ok {
repo = urlString
} else {
return nil, fmt.Errorf("default Git Repo Url was not set during installation of the git resolver")
return nil, fmt.Errorf("default Git Repo Url was not set during installation of the git resolver")
}
}
commit := params[CommitParam]
branch := params[BranchParam]
if commit == "" && branch == "" {
if branchString, ok := conf[ConfigBranch]; ok {
branch = branchString

revision := params[RevisionParam]
if revision == "" {
if revisionString, ok := conf[ConfigRevision]; ok {
revision = revisionString
} else {
return nil, fmt.Errorf("default Git Revision was not set during installation of the git resolver")
}
}
path := params[PathParam]

cloneOpts := &git.CloneOptions{
URL: repo,
}
filesystem := memfs.New()
if branch != "" {
cloneOpts.SingleBranch = true
cloneOpts.ReferenceName = plumbing.NewBranchReferenceName(branch)
}
repository, err := git.Clone(memory.NewStorage(), filesystem, cloneOpts)
if err != nil {
return nil, fmt.Errorf("clone error: %w", err)
}
if commit == "" {
headRef, err := repository.Head()
if err != nil {
return nil, fmt.Errorf("error reading repository HEAD value: %w", err)

// try fetch the branch when the given revision refers to a branch name
refSpec := config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/remotes/%s", revision, revision))
err = repository.Fetch(&git.FetchOptions{
RefSpecs: []config.RefSpec{refSpec},
})
if err != nil {
var fetchErr git.NoMatchingRefSpecError
if !errors.As(err, &fetchErr) {
return nil, fmt.Errorf("unexpected fetch error: %v", err)
}
commit = headRef.Hash().String()
}

w, err := repository.Worktree()
if err != nil {
return nil, fmt.Errorf("worktree error: %v", err)
}

h, err := repository.ResolveRevision(plumbing.Revision(revision))
if err != nil {
return nil, fmt.Errorf("revision error: %v", err)
}

err = w.Checkout(&git.CheckoutOptions{
Hash: plumbing.NewHash(commit),
Hash: *h,
})
if err != nil {
return nil, fmt.Errorf("checkout error: %v", err)
}

path := params[PathParam]
f, err := filesystem.Open(path)
if err != nil {
return nil, fmt.Errorf("error opening file %q: %v", path, err)
Expand All @@ -163,8 +169,8 @@ func (r *Resolver) Resolve(ctx context.Context, params map[string]string) (frame
}

return &ResolvedGitResource{
Commit: commit,
Content: buf.Bytes(),
Revision: revision,
Content: buf.Bytes(),
}, nil
}

Expand Down Expand Up @@ -194,8 +200,8 @@ func (r *Resolver) GetResolutionTimeout(ctx context.Context, defaultTimeout time
// ResolvedGitResource implements framework.ResolvedResource and returns
// the resolved file []byte data and an annotation map for any metadata.
type ResolvedGitResource struct {
Commit string
Content []byte
Revision string
Content []byte
}

var _ framework.ResolvedResource = &ResolvedGitResource{}
Expand All @@ -209,7 +215,7 @@ func (r *ResolvedGitResource) Data() []byte {
// from git.
func (r *ResolvedGitResource) Annotations() map[string]string {
return map[string]string{
AnnotationKeyCommitHash: r.Commit,
AnnotationKeyRevision: r.Revision,
resolutioncommon.AnnotationKeyContentType: YAMLContentType,
}
}
Loading