diff --git a/hack/get-previous-release/get-previous-version-for-release-notes.go b/hack/get-previous-release/get-previous-version-for-release-notes.go index 58a8e1f77c36d..1118357324af9 100644 --- a/hack/get-previous-release/get-previous-version-for-release-notes.go +++ b/hack/get-previous-release/get-previous-version-for-release-notes.go @@ -51,50 +51,59 @@ func extractPatchAndRC(tag string) (string, string, error) { return patch, rc, nil } -func findPreviousTag(proposedTag string, tags []string) (string, error) { - var previousTag string - proposedMinor := semver.MajorMinor(proposedTag) - - proposedPatch, proposedRC, err := extractPatchAndRC(proposedTag) - if err != nil { - return "", err +func removeInvalidTags(tags []string) []string { + var validTags []string + for _, tag := range tags { + if _, _, err := extractPatchAndRC(tag); err == nil { + validTags = append(validTags, tag) + } } + return validTags +} +func removeNewerOrEqualTags(proposedTag string, tags []string) []string { + var validTags []string for _, tag := range tags { - // If this tag is newer than the proposed tag, skip it. - if semver.Compare(tag, proposedTag) > 0 { - continue + if semver.Compare(tag, proposedTag) < 0 { + validTags = append(validTags, tag) } + } + return validTags +} - // If this tag is older than a tag we've already decided is a candidate, skip it. - if semver.Compare(tag, previousTag) <= 0 { - continue - } - tagPatch, tagRC, err := extractPatchAndRC(tag) - if err != nil { - continue +func removeTagsFromSameMinorSeries(proposedTag string, tags []string) []string { + var validTags []string + proposedMinor := semver.MajorMinor(proposedTag) + for _, tag := range tags { + if semver.MajorMinor(tag) != proposedMinor { + validTags = append(validTags, tag) } + } + return validTags +} - // If it's a non-RC release... - if proposedRC == "0" { - if proposedPatch == "0" { - // ...and we're cutting the first patch of a new minor release series, don't consider tags in the same - // minor release series. - if semver.MajorMinor(tag) != proposedMinor { - previousTag = tag - } - } else { - - previousTag = tag - } - } else { - if tagRC != "0" && tagPatch == proposedPatch { - previousTag = tag - } else if tagRC == "0" { - previousTag = tag - } +func getMostRecentTag(tags []string) string { + var mostRecentTag string + for _, tag := range tags { + if mostRecentTag == "" || semver.Compare(tag, mostRecentTag) > 0 { + mostRecentTag = tag } } + return mostRecentTag +} + +func findPreviousTag(proposedTag string, tags []string) (string, error) { + tags = removeInvalidTags(tags) + tags = removeNewerOrEqualTags(proposedTag, tags) + + proposedPatch, proposedRC, _ := extractPatchAndRC(proposedTag) // Ignore the error, we already filtered out invalid tags. + if proposedRC == "0" && proposedPatch == "0" { + // If we're cutting the first patch of a new minor release series, don't consider tags in the same minor release + // series. We want to compare to the latest tag in the previous minor release series. + tags = removeTagsFromSameMinorSeries(proposedTag, tags) + } + + previousTag := getMostRecentTag(tags) if previousTag == "" { return "", fmt.Errorf("no matching tag found for tags: " + strings.Join(tags, ", ")) } diff --git a/hack/get-previous-release/get-previous-version-for-release-notes_test.go b/hack/get-previous-release/get-previous-version-for-release-notes_test.go index 473462dcbb793..8b5f70fcdbe64 100644 --- a/hack/get-previous-release/get-previous-version-for-release-notes_test.go +++ b/hack/get-previous-release/get-previous-version-for-release-notes_test.go @@ -81,6 +81,8 @@ func TestFindPreviousTagRules(t *testing.T) { // Rule 6: If we're releasing a major version, get the most recent tag on the previous major release series, // even if it's an RC. {"Rule 6: major version", "v3.0.0", "v2.13.0-rc3", false}, + // Rule 7: If the proposed tag already exists, don't return it. + {"Rule 7: proposed tag already exists", "v2.12.5", "v2.12.4", false}, } for _, test := range tests {