Skip to content

Commit c70acd5

Browse files
authored
fix: GetRefSources populates refSources for multi source app with a single source (argoproj#27787)
Signed-off-by: reggie-k <regina.voloshin@codefresh.io>
1 parent 9c3a0fe commit c70acd5

2 files changed

Lines changed: 50 additions & 2 deletions

File tree

util/argo/argo.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,9 @@ func GetSyncedRefSources(refSources argoappv1.RefTargetRevisionMapping, sources
542542
// once (which would lead to ambiguous references).
543543
func GetRefSources(ctx context.Context, sources argoappv1.ApplicationSources, project string, getRepository func(ctx context.Context, url string, project string) (*argoappv1.Repository, error), revisions []string) (argoappv1.RefTargetRevisionMapping, error) {
544544
refSources := make(argoappv1.RefTargetRevisionMapping)
545-
if len(sources) > 1 {
546-
// Validate first to avoid unnecessary DB calls.
545+
if len(sources) > 0 {
546+
// Validate first to avoid unnecessary DB calls. Use len(sources) > 0 (not > 1) so a sole source with ref:
547+
// is populated; otherwise GetSyncedRefSources panics when spec.sources has one element (see #27759).
547548
refKeys := make(map[string]bool)
548549
for _, source := range sources {
549550
if source.Ref == "" {

util/argo/argo_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,6 +1675,25 @@ func Test_GetRefSources(t *testing.T) {
16751675
require.Error(t, err)
16761676
assert.Empty(t, refSources)
16771677
})
1678+
1679+
t.Run("single source with ref populates refSources", func(t *testing.T) {
1680+
argoSpec := getMultiSourceAppSpec(argoappv1.ApplicationSources{
1681+
{RepoURL: "file://" + repoPath, TargetRevision: "HEAD", Ref: "gitops"},
1682+
})
1683+
1684+
refSources, err := GetRefSources(t.Context(), argoSpec.Sources, argoSpec.Project, func(_ context.Context, _ string, _ string) (*argoappv1.Repository, error) {
1685+
return repo, nil
1686+
}, []string{})
1687+
1688+
require.NoError(t, err)
1689+
expected := argoappv1.RefTargetRevisionMapping{
1690+
"$gitops": &argoappv1.RefTarget{
1691+
Repo: *repo,
1692+
TargetRevision: "HEAD",
1693+
},
1694+
}
1695+
assert.Equal(t, expected, refSources)
1696+
})
16781697
}
16791698

16801699
func TestValidatePermissionsMultipleSources(t *testing.T) {
@@ -2304,3 +2323,31 @@ func Test_GetSyncedRefSources(t *testing.T) {
23042323
})
23052324
}
23062325
}
2326+
2327+
// Covers https://github.com/argoproj/argo-cd/issues/27759:
2328+
// spec.sources with one element still sets HasMultipleSources(); GetRefSources must populate refSources so
2329+
// GetSyncedRefSources does not dereference a missing map entry.
2330+
func Test_GetRefSourcesAndSyncedRefSources_SingleSourceWithRef(t *testing.T) {
2331+
repoPath, err := filepath.Abs("./../..")
2332+
require.NoError(t, err)
2333+
repo := &argoappv1.Repository{Repo: "file://" + repoPath}
2334+
sources := argoappv1.ApplicationSources{
2335+
{RepoURL: "file://" + repoPath, TargetRevision: "HEAD", Ref: "gitops"},
2336+
}
2337+
2338+
refSources, err := GetRefSources(t.Context(), sources, "", func(_ context.Context, _ string, _ string) (*argoappv1.Repository, error) {
2339+
return repo, nil
2340+
}, []string{})
2341+
require.NoError(t, err)
2342+
2343+
syncedRevisions := []string{"rev"}
2344+
synced := GetSyncedRefSources(refSources, sources, syncedRevisions)
2345+
2346+
expected := argoappv1.RefTargetRevisionMapping{
2347+
"$gitops": &argoappv1.RefTarget{
2348+
Repo: *repo,
2349+
TargetRevision: "rev",
2350+
},
2351+
}
2352+
assert.Equal(t, expected, synced)
2353+
}

0 commit comments

Comments
 (0)