Merge pull request #920 from kane8n/git-sparse-checkout-when-update-path-specify

Add support for Git sparse checkout when `.spec.update.path` is specified
This commit is contained in:
Stefan Prodan 2025-06-17 12:59:08 +03:00 committed by GitHub
commit 124fd9fe8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 72 additions and 7 deletions

View File

@ -396,6 +396,10 @@ func (r *ImageUpdateAutomationReconciler) reconcile(ctx context.Context, sp *pat
if r.features[features.GitShallowClone] {
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone())
}
if r.features[features.GitSparseCheckout] && obj.Spec.Update.Path != "" {
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionSparseCheckoutDirectories(obj.Spec.Update.Path))
}
// If full sync is still not needed, configure last observed commit to
// perform optimized clone and obtain a non-concrete commit if the remote
// has not changed.

View File

@ -34,6 +34,9 @@ const (
// GitAllBranchReferences enables the download of all branch head references
// when push branches are configured. When enabled fixes fluxcd/flux2#3384.
GitAllBranchReferences = "GitAllBranchReferences"
// GitSparseCheckout enables the use of sparse checkout when pulling source from
// Git repositories.
GitSparseCheckout = "GitSparseCheckout"
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
// be cached.
//
@ -55,6 +58,10 @@ var features = map[string]bool{
// opt-out from v0.28
GitAllBranchReferences: true,
// GitSparseCheckout
// opt-in from v0.42
GitSparseCheckout: false,
// CacheSecretsAndConfigMaps
// opt-in from v0.29
CacheSecretsAndConfigMaps: false,

View File

@ -21,6 +21,7 @@ import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"text/template"
"time"
@ -196,6 +197,19 @@ func WithCheckoutOptionShallowClone() CheckoutOption {
}
}
// WithCheckoutOptionSparseCheckoutDirectories is a CheckoutOption option to configure
// SparseCheckoutDirectories.
func WithCheckoutOptionSparseCheckoutDirectories(updatePath string) CheckoutOption {
return func(cc *repository.CloneConfig) {
cleanedPath := filepath.Clean(updatePath)
if cleanedPath == "." {
// Do not set SparseCheckoutDirectories if repository root is specified
return
}
cc.SparseCheckoutDirectories = []string{cleanedPath}
}
}
// CheckoutSource clones and checks out the source. If a push branch is
// configured that doesn't match with the checkout branch, a checkout to the
// push branch is also performed. This ensures any change and push operation

View File

@ -226,6 +226,7 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
autoGitSpec *imagev1.GitSpec
gitRepoRef *sourcev1.GitRepositoryRef
shallowClone bool
sparseCheckoutDirectory string
lastObserved bool
wantErr bool
wantRef string
@ -275,6 +276,42 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
wantErr: false,
wantRef: "main",
},
{
name: "with sparse checkout",
autoGitSpec: &imagev1.GitSpec{
Push: &imagev1.PushSpec{Branch: "main"},
Checkout: &imagev1.GitCheckoutSpec{
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
},
},
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
wantErr: false,
wantRef: "main",
},
{
name: "with sparse checkout for current directory",
autoGitSpec: &imagev1.GitSpec{
Push: &imagev1.PushSpec{Branch: "main"},
Checkout: &imagev1.GitCheckoutSpec{
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
},
},
sparseCheckoutDirectory: "./",
wantErr: false,
wantRef: "main",
},
{
name: "with sparse checkout for different push branch",
autoGitSpec: &imagev1.GitSpec{
Push: &imagev1.PushSpec{Branch: "foo"},
Checkout: &imagev1.GitCheckoutSpec{
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
},
},
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
wantErr: false,
wantRef: "foo",
},
{
name: "with last observed commit",
autoGitSpec: &imagev1.GitSpec{
@ -386,6 +423,9 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
if tt.shallowClone {
opts = append(opts, WithCheckoutOptionShallowClone())
}
if tt.sparseCheckoutDirectory != "" {
opts = append(opts, WithCheckoutOptionSparseCheckoutDirectories(tt.sparseCheckoutDirectory))
}
if tt.lastObserved {
opts = append(opts, WithCheckoutOptionLastObserved(headRev))
}