fix(sync): apply tag filters before destination mapping (#4003)

* fix(sync): apply tag filters before destination mapping

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

* fix(sync): return stable pointer from getContentByUpstreamRepo

Iterate by index and return &cm.contents[i] so callers get the slice
element rather than a copy of the loop variable, matching the existing
GetContentByLocalRepo helper.

Signed-off-by: Akash Kumar <meakash7902@gmail.com>

---------

Signed-off-by: Akash Kumar <meakash7902@gmail.com>
This commit is contained in:
Akash Kumar
2026-04-27 10:57:46 +05:30
committed by GitHub
parent 9e13be8b61
commit bb5b77aeaa
2 changed files with 49 additions and 3 deletions
+5 -3
View File
@@ -50,7 +50,7 @@ func (cm ContentManager) MatchesContent(repo string) bool {
// FilterTags filters a repo tags based on content config rules (semver, regex).
func (cm ContentManager) FilterTags(repo string, tags []string) ([]string, error) {
content := cm.GetContentByLocalRepo(repo)
content := cm.getContentByUpstreamRepo(repo)
var err error
// filter based on tags rules
@@ -106,7 +106,9 @@ func (cm ContentManager) GetRepoSource(repo string) string {
// utilies functions.
func (cm ContentManager) getContentByUpstreamRepo(repo string) *syncconf.Content {
for _, content := range cm.contents {
for i := range cm.contents {
content := &cm.contents[i]
var prefix string
// handle prefixes starting with '/'
if strings.HasPrefix(content.Prefix, "/") {
@@ -125,7 +127,7 @@ func (cm ContentManager) getContentByUpstreamRepo(repo string) *syncconf.Content
}
if matched {
return &content
return content
}
}
+44
View File
@@ -82,6 +82,12 @@ func TestContentManager(t *testing.T) {
}
})
Convey("Test GetRepoSource() no match", t, func() {
content := syncconf.Content{Prefix: "repo", Destination: "/mirror"}
cm := sync.NewContentManager([]syncconf.Content{content}, log.NewTestLogger())
So(cm.GetRepoSource("other"), ShouldEqual, "")
})
Convey("Test MatchesContent() error", t, func() {
content := syncconf.Content{Prefix: "[repo%^&"}
cm := sync.NewContentManager([]syncconf.Content{content}, log.NewTestLogger())
@@ -169,6 +175,8 @@ func TestGetContentByLocalRepo(t *testing.T) {
func TestFilterTags(t *testing.T) {
allTagsRegex := ".*"
emptyRegex := ""
kubeRouterRegex := "1.5.0"
badRegex := "[*"
excludeArchRegex := ".*(x86_64|aarch64|amd64|arm64)$"
semverFalse := false
@@ -216,6 +224,33 @@ func TestFilterTags(t *testing.T) {
filteredTags: []string{"v1.0.1"},
err: false,
},
{
repo: "kubernetes/kube-router",
content: []syncconf.Content{
{
Prefix: "kubernetes/kube-router",
Destination: "/mirror",
Tags: &syncconf.Tags{Regex: &kubeRouterRegex, Semver: &semverTrue},
},
},
tags: []string{"1.5.0", "v2.5.0"},
filteredTags: []string{"1.5.0"},
err: false,
},
{
repo: "kubernetes/kube-router",
content: []syncconf.Content{
{
Prefix: "kubernetes/kube-router",
Destination: "/mirror",
StripPrefix: true,
Tags: &syncconf.Tags{Regex: &kubeRouterRegex, Semver: &semverTrue},
},
},
tags: []string{"1.5.0", "v2.5.0"},
filteredTags: []string{"1.5.0"},
err: false,
},
{
repo: "repo",
content: []syncconf.Content{
@@ -253,6 +288,15 @@ func TestFilterTags(t *testing.T) {
filteredTags: []string{"v1"},
err: false,
},
{
repo: "alpine",
content: []syncconf.Content{
{Prefix: "**", Tags: &syncconf.Tags{ExcludeRegex: &emptyRegex}},
},
tags: []string{"v1", "v2", "v3"},
filteredTags: []string{"v1", "v2", "v3"},
err: false,
},
{
repo: "repo",
content: []syncconf.Content{