Skip to content

Commit 124fd9f

Browse files
authored
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
2 parents b8e667d + 3999c65 commit 124fd9f

File tree

4 files changed

+72
-7
lines changed

4 files changed

+72
-7
lines changed

internal/controller/imageupdateautomation_controller.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,10 @@ func (r *ImageUpdateAutomationReconciler) reconcile(ctx context.Context, sp *pat
396396
if r.features[features.GitShallowClone] {
397397
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionShallowClone())
398398
}
399+
if r.features[features.GitSparseCheckout] && obj.Spec.Update.Path != "" {
400+
checkoutOpts = append(checkoutOpts, source.WithCheckoutOptionSparseCheckoutDirectories(obj.Spec.Update.Path))
401+
}
402+
399403
// If full sync is still not needed, configure last observed commit to
400404
// perform optimized clone and obtain a non-concrete commit if the remote
401405
// has not changed.

internal/features/features.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const (
3434
// GitAllBranchReferences enables the download of all branch head references
3535
// when push branches are configured. When enabled fixes fluxcd/flux2#3384.
3636
GitAllBranchReferences = "GitAllBranchReferences"
37+
// GitSparseCheckout enables the use of sparse checkout when pulling source from
38+
// Git repositories.
39+
GitSparseCheckout = "GitSparseCheckout"
3740
// CacheSecretsAndConfigMaps controls whether Secrets and ConfigMaps should
3841
// be cached.
3942
//
@@ -55,6 +58,10 @@ var features = map[string]bool{
5558
// opt-out from v0.28
5659
GitAllBranchReferences: true,
5760

61+
// GitSparseCheckout
62+
// opt-in from v0.42
63+
GitSparseCheckout: false,
64+
5865
// CacheSecretsAndConfigMaps
5966
// opt-in from v0.29
6067
CacheSecretsAndConfigMaps: false,

internal/source/source.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"errors"
2222
"fmt"
2323
"os"
24+
"path/filepath"
2425
"strings"
2526
"text/template"
2627
"time"
@@ -196,6 +197,19 @@ func WithCheckoutOptionShallowClone() CheckoutOption {
196197
}
197198
}
198199

200+
// WithCheckoutOptionSparseCheckoutDirectories is a CheckoutOption option to configure
201+
// SparseCheckoutDirectories.
202+
func WithCheckoutOptionSparseCheckoutDirectories(updatePath string) CheckoutOption {
203+
return func(cc *repository.CloneConfig) {
204+
cleanedPath := filepath.Clean(updatePath)
205+
if cleanedPath == "." {
206+
// Do not set SparseCheckoutDirectories if repository root is specified
207+
return
208+
}
209+
cc.SparseCheckoutDirectories = []string{cleanedPath}
210+
}
211+
}
212+
199213
// CheckoutSource clones and checks out the source. If a push branch is
200214
// configured that doesn't match with the checkout branch, a checkout to the
201215
// push branch is also performed. This ensures any change and push operation

internal/source/source_test.go

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,14 @@ func TestSourceManager_CheckoutSource(t *testing.T) {
222222

223223
func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
224224
tests := []struct {
225-
name string
226-
autoGitSpec *imagev1.GitSpec
227-
gitRepoRef *sourcev1.GitRepositoryRef
228-
shallowClone bool
229-
lastObserved bool
230-
wantErr bool
231-
wantRef string
225+
name string
226+
autoGitSpec *imagev1.GitSpec
227+
gitRepoRef *sourcev1.GitRepositoryRef
228+
shallowClone bool
229+
sparseCheckoutDirectory string
230+
lastObserved bool
231+
wantErr bool
232+
wantRef string
232233
}{
233234
{
234235
name: "checkout for single branch",
@@ -275,6 +276,42 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
275276
wantErr: false,
276277
wantRef: "main",
277278
},
279+
{
280+
name: "with sparse checkout",
281+
autoGitSpec: &imagev1.GitSpec{
282+
Push: &imagev1.PushSpec{Branch: "main"},
283+
Checkout: &imagev1.GitCheckoutSpec{
284+
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
285+
},
286+
},
287+
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
288+
wantErr: false,
289+
wantRef: "main",
290+
},
291+
{
292+
name: "with sparse checkout for current directory",
293+
autoGitSpec: &imagev1.GitSpec{
294+
Push: &imagev1.PushSpec{Branch: "main"},
295+
Checkout: &imagev1.GitCheckoutSpec{
296+
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
297+
},
298+
},
299+
sparseCheckoutDirectory: "./",
300+
wantErr: false,
301+
wantRef: "main",
302+
},
303+
{
304+
name: "with sparse checkout for different push branch",
305+
autoGitSpec: &imagev1.GitSpec{
306+
Push: &imagev1.PushSpec{Branch: "foo"},
307+
Checkout: &imagev1.GitCheckoutSpec{
308+
Reference: sourcev1.GitRepositoryRef{Branch: "main"},
309+
},
310+
},
311+
sparseCheckoutDirectory: "testdata/appconfig/deploy.yaml",
312+
wantErr: false,
313+
wantRef: "foo",
314+
},
278315
{
279316
name: "with last observed commit",
280317
autoGitSpec: &imagev1.GitSpec{
@@ -386,6 +423,9 @@ func test_sourceManager_CheckoutSource(t *testing.T, proto string) {
386423
if tt.shallowClone {
387424
opts = append(opts, WithCheckoutOptionShallowClone())
388425
}
426+
if tt.sparseCheckoutDirectory != "" {
427+
opts = append(opts, WithCheckoutOptionSparseCheckoutDirectories(tt.sparseCheckoutDirectory))
428+
}
389429
if tt.lastObserved {
390430
opts = append(opts, WithCheckoutOptionLastObserved(headRev))
391431
}

0 commit comments

Comments
 (0)