Implement git tag semver filter
This commit is contained in:
parent
98901f2909
commit
62350a944b
|
@ -37,6 +37,10 @@ type GitRepositorySpec struct {
|
|||
// The git tag to checkout, takes precedence over branch.
|
||||
// +optional
|
||||
Tag string `json:"tag"`
|
||||
|
||||
// The git tag semver expression, takes precedence over tag.
|
||||
// +optional
|
||||
SemVer string `json:"semver"`
|
||||
}
|
||||
|
||||
// GitRepositoryStatus defines the observed state of GitRepository
|
||||
|
|
|
@ -55,6 +55,9 @@ spec:
|
|||
interval:
|
||||
description: The interval at which to check for repository updates.
|
||||
type: string
|
||||
semver:
|
||||
description: The git tag semver expression, takes precedence over tag.
|
||||
type: string
|
||||
tag:
|
||||
description: The git tag to checkout, takes precedence over branch.
|
||||
type: string
|
||||
|
|
|
@ -23,10 +23,10 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-logr/logr"
|
||||
|
@ -35,6 +35,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||
|
||||
sourcerv1 "github.com/fluxcd/sourcer/api/v1alpha1"
|
||||
|
@ -141,6 +142,7 @@ func (r *GitRepositoryReconciler) sync(gr sourcerv1.GitRepository) (sourcerv1.Re
|
|||
refName = plumbing.NewTagReferenceName(gr.Spec.Tag)
|
||||
}
|
||||
|
||||
// create tmp dir
|
||||
dir, err := ioutil.TempDir("", gr.Name)
|
||||
if err != nil {
|
||||
ex := fmt.Errorf("tmp dir error %w", err)
|
||||
|
@ -159,6 +161,7 @@ func (r *GitRepositoryReconciler) sync(gr sourcerv1.GitRepository) (sourcerv1.Re
|
|||
Depth: 2,
|
||||
ReferenceName: refName,
|
||||
SingleBranch: true,
|
||||
Tags: git.AllTags,
|
||||
})
|
||||
if err != nil {
|
||||
ex := fmt.Errorf("git clone error %w", err)
|
||||
|
@ -170,6 +173,86 @@ func (r *GitRepositoryReconciler) sync(gr sourcerv1.GitRepository) (sourcerv1.Re
|
|||
}, "", ex
|
||||
}
|
||||
|
||||
// checkout tag based on semver expression
|
||||
if gr.Spec.SemVer != "" {
|
||||
rng, err := semver.ParseRange(gr.Spec.SemVer)
|
||||
if err != nil {
|
||||
ex := fmt.Errorf("semver parse range error %w", err)
|
||||
return sourcerv1.RepositoryCondition{
|
||||
Type: sourcerv1.RepositoryConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
Reason: "GitCloneFailed",
|
||||
Message: ex.Error(),
|
||||
}, "", ex
|
||||
}
|
||||
|
||||
repoTags, err := repo.Tags()
|
||||
if err != nil {
|
||||
ex := fmt.Errorf("git list tags error %w", err)
|
||||
return sourcerv1.RepositoryCondition{
|
||||
Type: sourcerv1.RepositoryConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
Reason: "GitCloneFailed",
|
||||
Message: ex.Error(),
|
||||
}, "", ex
|
||||
}
|
||||
|
||||
tags := make(map[string]string)
|
||||
_ = repoTags.ForEach(func(t *plumbing.Reference) error {
|
||||
tags[t.Name().Short()] = t.Strings()[1]
|
||||
return nil
|
||||
})
|
||||
|
||||
svTags := make(map[string]string)
|
||||
svers := []semver.Version{}
|
||||
for tag, _ := range tags {
|
||||
v, _ := semver.ParseTolerant(tag)
|
||||
if rng(v) {
|
||||
svers = append(svers, v)
|
||||
svTags[v.String()] = tag
|
||||
}
|
||||
}
|
||||
|
||||
if len(svers) > 0 {
|
||||
semver.Sort(svers)
|
||||
v := svers[len(svers)-1]
|
||||
t := svTags[v.String()]
|
||||
commit := tags[t]
|
||||
|
||||
w, err := repo.Worktree()
|
||||
if err != nil {
|
||||
ex := fmt.Errorf("git worktree error %w", err)
|
||||
return sourcerv1.RepositoryCondition{
|
||||
Type: sourcerv1.RepositoryConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
Reason: "GitCheckoutFailed",
|
||||
Message: ex.Error(),
|
||||
}, "", ex
|
||||
}
|
||||
|
||||
err = w.Checkout(&git.CheckoutOptions{
|
||||
Hash: plumbing.NewHash(commit),
|
||||
})
|
||||
if err != nil {
|
||||
ex := fmt.Errorf("git checkout error %w", err)
|
||||
return sourcerv1.RepositoryCondition{
|
||||
Type: sourcerv1.RepositoryConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
Reason: "GitCheckoutFailed",
|
||||
Message: ex.Error(),
|
||||
}, "", ex
|
||||
}
|
||||
} else {
|
||||
ex := fmt.Errorf("no match found for semver %s", gr.Spec.SemVer)
|
||||
return sourcerv1.RepositoryCondition{
|
||||
Type: sourcerv1.RepositoryConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
Reason: "GitCheckoutFailed",
|
||||
Message: ex.Error(),
|
||||
}, "", ex
|
||||
}
|
||||
}
|
||||
|
||||
// read commit hash
|
||||
ref, err := repo.Head()
|
||||
if err != nil {
|
||||
|
@ -233,7 +316,9 @@ func (r *GitRepositoryReconciler) sync(gr sourcerv1.GitRepository) (sourcerv1.Re
|
|||
func (r *GitRepositoryReconciler) shouldResetStatus(gr sourcerv1.GitRepository) bool {
|
||||
resetStatus := false
|
||||
if gr.Status.Artifacts != "" {
|
||||
if _, err := os.Stat(filepath.Join(r.StoragePath, gr.Status.Artifacts)); err != nil {
|
||||
pathParts := strings.Split(gr.Status.Artifacts, "/")
|
||||
path := fmt.Sprintf("repositories/%s-%s/%s", gr.Name, gr.Namespace, pathParts[len(pathParts)-1])
|
||||
if _, err := os.Stat(filepath.Join(r.StoragePath, path)); err != nil {
|
||||
resetStatus = true
|
||||
}
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/fluxcd/sourcer
|
|||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/blang/semver v3.5.0+incompatible
|
||||
github.com/go-git/go-git/v5 v5.0.0
|
||||
github.com/go-logr/logr v0.1.0
|
||||
github.com/onsi/ginkgo v1.11.0
|
||||
|
|
1
go.sum
1
go.sum
|
@ -37,6 +37,7 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
|||
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
|
|
Loading…
Reference in New Issue