diff --git a/cmd/release-controller/sync_verify.go b/cmd/release-controller/sync_verify.go index f74603252..01fd70b73 100644 --- a/cmd/release-controller/sync_verify.go +++ b/cmd/release-controller/sync_verify.go @@ -187,12 +187,11 @@ func (c *Controller) resolveUpgradeRelease(upgradeRelease *releasecontroller.Upg pullSpec := releasecontroller.ReleasePullSpec(r, latest) return tag, pullSpec, nil } else if upgradeRelease.Candidate != nil { - // create blank semver.Range var constraint semver.Range - stream := fmt.Sprintf("%s.0-0.%s%s", upgradeRelease.Candidate.Version, upgradeRelease.Candidate.Stream, TrimPrefixes(release.Config.To, "release-5", "release")) - r, latest, err := releasecontroller.LatestForStream(c.parsedReleaseConfigCache, c.eventRecorder, c.releaseLister, c.releasePayloadLister, stream, constraint, upgradeRelease.Candidate.Relative, "") + streamName, versionPrefix := candidateStreamName(upgradeRelease.Candidate.Version, upgradeRelease.Candidate.Stream, release.Config.To) + r, latest, err := releasecontroller.LatestForStream(c.parsedReleaseConfigCache, c.eventRecorder, c.releaseLister, c.releasePayloadLister, streamName, constraint, upgradeRelease.Candidate.Relative, versionPrefix) if err != nil { - return "", "", fmt.Errorf("failed to get latest tag for stream %s: %w", stream, err) + return "", "", fmt.Errorf("failed to get latest tag for stream %s: %w", streamName, err) } tag := latest.Name pullSpec := releasecontroller.ReleasePullSpec(r, latest) @@ -217,3 +216,16 @@ func TrimPrefixes(s string, prefixes ...string) string { } return s } + +// candidateStreamName returns the release stream name and an optional version +// prefix filter for a candidate upgrade source. Nightly and CI streams use +// names like "4.22.0-0.nightly"; stable streams use "N-stable" (e.g. "4-stable") +// and need the version prefix to filter to the requested minor version. +func candidateStreamName(version, stream, configTo string) (streamName, versionPrefix string) { + suffix := TrimPrefixes(configTo, "release-5", "release") + if stream == "stable" { + major, _, _ := strings.Cut(version, ".") + return fmt.Sprintf("%s-stable%s", major, suffix), version + "." + } + return fmt.Sprintf("%s.0-0.%s%s", version, stream, suffix), "" +} diff --git a/cmd/release-controller/sync_verify_test.go b/cmd/release-controller/sync_verify_test.go index 9effec4e1..07fca14ae 100644 --- a/cmd/release-controller/sync_verify_test.go +++ b/cmd/release-controller/sync_verify_test.go @@ -116,6 +116,94 @@ var reference4Preview = releasecontroller.StableRelease{ }}, } +func TestCandidateStreamName(t *testing.T) { + t.Parallel() + testCases := []struct { + name string + version string + stream string + configTo string + expectedStreamName string + expectedVersionPrefix string + }{ + { + name: "stable stream, empty configTo", + version: "4.22", + stream: "stable", + configTo: "", + expectedStreamName: "4-stable", + expectedVersionPrefix: "4.22.", + }, + { + name: "stable stream, configTo=release", + version: "4.22", + stream: "stable", + configTo: "release", + expectedStreamName: "4-stable", + expectedVersionPrefix: "4.22.", + }, + { + name: "stable stream, major version 5", + version: "5.1", + stream: "stable", + configTo: "", + expectedStreamName: "5-stable", + expectedVersionPrefix: "5.1.", + }, + { + name: "stable stream, arm64 suffix", + version: "4.22", + stream: "stable", + configTo: "release-arm64", + expectedStreamName: "4-stable-arm64", + expectedVersionPrefix: "4.22.", + }, + { + name: "nightly stream, configTo=release", + version: "4.22", + stream: "nightly", + configTo: "release", + expectedStreamName: "4.22.0-0.nightly", + expectedVersionPrefix: "", + }, + { + name: "nightly stream, configTo=release-5", + version: "4.22", + stream: "nightly", + configTo: "release-5", + expectedStreamName: "4.22.0-0.nightly", + expectedVersionPrefix: "", + }, + { + name: "ci stream", + version: "4.22", + stream: "ci", + configTo: "release", + expectedStreamName: "4.22.0-0.ci", + expectedVersionPrefix: "", + }, + { + name: "nightly stream, arm64 suffix", + version: "4.22", + stream: "nightly", + configTo: "release-arm64", + expectedStreamName: "4.22.0-0.nightly-arm64", + expectedVersionPrefix: "", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + streamName, versionPrefix := candidateStreamName(tc.version, tc.stream, tc.configTo) + if streamName != tc.expectedStreamName { + t.Errorf("Expected stream name %q, got %q", tc.expectedStreamName, streamName) + } + if versionPrefix != tc.expectedVersionPrefix { + t.Errorf("Expected version prefix %q, got %q", tc.expectedVersionPrefix, versionPrefix) + } + }) + } +} + func TestFindLatestStableForVersion(t *testing.T) { t.Parallel() testCases := []struct {