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.
|
// The git tag to checkout, takes precedence over branch.
|
||||||
// +optional
|
// +optional
|
||||||
Tag string `json:"tag"`
|
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
|
// GitRepositoryStatus defines the observed state of GitRepository
|
||||||
|
|
|
@ -55,6 +55,9 @@ spec:
|
||||||
interval:
|
interval:
|
||||||
description: The interval at which to check for repository updates.
|
description: The interval at which to check for repository updates.
|
||||||
type: string
|
type: string
|
||||||
|
semver:
|
||||||
|
description: The git tag semver expression, takes precedence over tag.
|
||||||
|
type: string
|
||||||
tag:
|
tag:
|
||||||
description: The git tag to checkout, takes precedence over branch.
|
description: The git tag to checkout, takes precedence over branch.
|
||||||
type: string
|
type: string
|
||||||
|
|
|
@ -23,10 +23,10 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/event"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/blang/semver"
|
||||||
"github.com/go-git/go-git/v5"
|
"github.com/go-git/go-git/v5"
|
||||||
"github.com/go-git/go-git/v5/plumbing"
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
|
@ -35,6 +35,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/event"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
"sigs.k8s.io/controller-runtime/pkg/predicate"
|
||||||
|
|
||||||
sourcerv1 "github.com/fluxcd/sourcer/api/v1alpha1"
|
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)
|
refName = plumbing.NewTagReferenceName(gr.Spec.Tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create tmp dir
|
||||||
dir, err := ioutil.TempDir("", gr.Name)
|
dir, err := ioutil.TempDir("", gr.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ex := fmt.Errorf("tmp dir error %w", err)
|
ex := fmt.Errorf("tmp dir error %w", err)
|
||||||
|
@ -159,6 +161,7 @@ func (r *GitRepositoryReconciler) sync(gr sourcerv1.GitRepository) (sourcerv1.Re
|
||||||
Depth: 2,
|
Depth: 2,
|
||||||
ReferenceName: refName,
|
ReferenceName: refName,
|
||||||
SingleBranch: true,
|
SingleBranch: true,
|
||||||
|
Tags: git.AllTags,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ex := fmt.Errorf("git clone error %w", err)
|
ex := fmt.Errorf("git clone error %w", err)
|
||||||
|
@ -170,6 +173,86 @@ func (r *GitRepositoryReconciler) sync(gr sourcerv1.GitRepository) (sourcerv1.Re
|
||||||
}, "", ex
|
}, "", 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
|
// read commit hash
|
||||||
ref, err := repo.Head()
|
ref, err := repo.Head()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -233,7 +316,9 @@ func (r *GitRepositoryReconciler) sync(gr sourcerv1.GitRepository) (sourcerv1.Re
|
||||||
func (r *GitRepositoryReconciler) shouldResetStatus(gr sourcerv1.GitRepository) bool {
|
func (r *GitRepositoryReconciler) shouldResetStatus(gr sourcerv1.GitRepository) bool {
|
||||||
resetStatus := false
|
resetStatus := false
|
||||||
if gr.Status.Artifacts != "" {
|
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
|
resetStatus = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/fluxcd/sourcer
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/blang/semver v3.5.0+incompatible
|
||||||
github.com/go-git/go-git/v5 v5.0.0
|
github.com/go-git/go-git/v5 v5.0.0
|
||||||
github.com/go-logr/logr v0.1.0
|
github.com/go-logr/logr v0.1.0
|
||||||
github.com/onsi/ginkgo v1.11.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 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
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/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/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/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
|
|
Loading…
Reference in New Issue