fix(reposerver): honor depth of referenced source instead of primary source (#28339)

Signed-off-by: Alexandre Savicki <[email protected]>
This commit is contained in:
alexandresavicki
2026-06-18 15:53:02 -04:00
committed by GitHub
parent 91214b80b6
commit e36652ca57
2 changed files with 67 additions and 1 deletions
+5 -1
View File
@@ -887,7 +887,11 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA,
return
}
closer, err := s.repoLock.Lock(gitClient.Root(), referencedCommitSHA, true, func(clean bool) (goio.Closer, error) {
return s.checkoutRevision(gitClient, referencedCommitSHA, s.initConstants.SubmoduleEnabled, q.Repo.Depth, clean)
// Use the referenced source's own depth instead of the primary source's depth.
// For multi-source Applications where the primary source is a Helm/OCI artifact,
// q.Repo.Depth is unset (0), which would otherwise force a full fetch of the
// referenced git repository regardless of its configured depth.
return s.checkoutRevision(gitClient, referencedCommitSHA, s.initConstants.SubmoduleEnabled, refSourceMapping.Repo.Depth, clean)
})
if err != nil {
log.Errorf("failed to acquire lock for referenced source %s", normalizedRepoURL)
+62
View File
@@ -683,6 +683,68 @@ func TestHelmChartReferencingExternalValues_InvalidRefs(t *testing.T) {
assert.Nil(t, response)
}
// TestHelmChartReferencingExternalValues_RefSourceDepthIsHonored is a regression
// test for https://github.com/argoproj/argo-cd/issues/27811. For multi-source
// Applications whose primary source is a Helm chart (or any non-git artifact),
// the depth configured on the referenced git source must be propagated to the
// git fetch. Previously the depth of the primary source was incorrectly used,
// which is unset (0) for Helm/OCI primary sources and therefore caused full
// git fetches regardless of the referenced repository's configured depth.
func TestHelmChartReferencingExternalValues_RefSourceDepthIsHonored(t *testing.T) {
const refSourceDepth int64 = 1
service, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, _ *ocimocks.Client, paths *iomocks.TempPaths) {
gitClient.EXPECT().Init().Return(nil)
gitClient.EXPECT().IsRevisionPresent(mock.Anything).Return(false)
// Strict expectation: Fetch must be invoked with the referenced source's
// depth (refSourceDepth), not the primary source's depth (which is 0
// because the primary source is Helm and Repository.Depth is unset).
// Any call with a different depth would fail this assertion.
gitClient.EXPECT().Fetch(mock.Anything, refSourceDepth).Return(nil)
gitClient.EXPECT().Checkout(mock.Anything, mock.Anything, mock.Anything).Return("", nil)
gitClient.EXPECT().LsRemote(mock.Anything).Return(mock.Anything, nil)
gitClient.EXPECT().CommitSHA().Return(mock.Anything, nil)
gitClient.EXPECT().Root().Return(".")
gitClient.EXPECT().RepoURL().Return("https://git.example.com/test/repo")
gitClient.EXPECT().IsAnnotatedTag(mock.Anything).Return(false)
gitClient.EXPECT().VerifyCommitSignature(mock.Anything).Return("", nil)
helmClient.EXPECT().GetIndex(mock.AnythingOfType("bool"), mock.Anything).Return(&helm.Index{Entries: map[string]helm.Entries{
"my-chart": {{Version: "1.0.0"}, {Version: "1.1.0"}},
}}, nil)
helmClient.EXPECT().GetTags(mock.Anything, mock.Anything).Return(nil, nil)
helmClient.EXPECT().ExtractChart("my-chart", "1.1.0", false, int64(0), false).Return("./testdata/my-chart", utilio.NopCloser, nil)
helmClient.EXPECT().CleanChartCache("my-chart", "1.1.0").Return(nil)
paths.EXPECT().Add(mock.Anything, mock.Anything).Return()
paths.EXPECT().GetPath(mock.Anything).Return(".", nil)
paths.EXPECT().GetPathIfExists(mock.Anything).Return(".")
paths.EXPECT().GetPaths().Return(map[string]string{"fake-nonce": "."})
}, ".")
spec := v1alpha1.ApplicationSpec{
Sources: []v1alpha1.ApplicationSource{
{RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &v1alpha1.ApplicationSourceHelm{
ValueFiles: []string{"$ref/testdata/my-chart/my-chart-values.yaml"},
}},
{Ref: "ref", RepoURL: "https://git.example.com/test/repo"},
},
}
refSources, err := argo.GetRefSources(t.Context(), spec.Sources, spec.Project, func(_ context.Context, _ string, _ string) (*v1alpha1.Repository, error) {
return &v1alpha1.Repository{
Repo: "https://git.example.com/test/repo",
Depth: refSourceDepth,
}, nil
}, []string{})
require.NoError(t, err)
request := &apiclient.ManifestRequest{
Repo: &v1alpha1.Repository{}, ApplicationSource: &spec.Sources[0], NoCache: true, RefSources: refSources, HasMultipleSources: true, ProjectName: "something",
ProjectSourceRepos: []string{"*"},
}
response, err := service.GenerateManifest(t.Context(), request)
require.NoError(t, err)
assert.NotNil(t, response)
}
func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) {
service := newService(t, ".")
err := os.Mkdir("testdata/oob-symlink", 0o755)