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] { if r.features[features.GitShallowClone] {
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone()) 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 // If full sync is still not needed, configure last observed commit to
// perform optimized clone and obtain a non-concrete commit if the remote // perform optimized clone and obtain a non-concrete commit if the remote
// has not changed. // has not changed.

View File

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

View File

@ -21,6 +21,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"path/filepath"
"strings" "strings"
"text/template" "text/template"
"time" "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 // 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 // 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 // push branch is also performed. This ensures any change and push operation

View File

@ -222,13 +222,14 @@ func TestSourceManager_CheckoutSource(t *testing.T) {
func test_sourceManager_CheckoutSource(t *testing.T, proto string) { func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
tests := []struct { tests := []struct {
name string name string
autoGitSpec *imagev1.GitSpec autoGitSpec *imagev1.GitSpec
gitRepoRef *sourcev1.GitRepositoryRef gitRepoRef *sourcev1.GitRepositoryRef
shallowClone bool shallowClone bool
lastObserved bool sparseCheckoutDirectory string
wantErr bool lastObserved bool
wantRef string wantErr bool
wantRef string
}{ }{
{ {
name: "checkout for single branch", name: "checkout for single branch",
@ -275,6 +276,42 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
wantErr: false, wantErr: false,
wantRef: "main", 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", name: "with last observed commit",
autoGitSpec: &imagev1.GitSpec{ autoGitSpec: &imagev1.GitSpec{
@ -386,6 +423,9 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
if tt.shallowClone { if tt.shallowClone {
opts = append(opts, WithCheckoutOptionShallowClone()) opts = append(opts, WithCheckoutOptionShallowClone())
} }
if tt.sparseCheckoutDirectory != "" {
opts = append(opts, WithCheckoutOptionSparseCheckoutDirectories(tt.sparseCheckoutDirectory))
}
if tt.lastObserved { if tt.lastObserved {
opts = append(opts, WithCheckoutOptionLastObserved(headRev)) opts = append(opts, WithCheckoutOptionLastObserved(headRev))
} }