Skip to content

Commit 51a6c70

Browse files
tsuzusivchari
andcommitted
Add validation for PREVIOUS_RELEASE_TAG in release-notes-tool
Validate that PREVIOUS_RELEASE_TAG uses proper ref format and contains alpha, beta, or rc pre-release identifier. Co-authored-by: sivchari <[email protected]>
1 parent ce4c050 commit 51a6c70

File tree

2 files changed

+117
-7
lines changed

2 files changed

+117
-7
lines changed

hack/tools/release/notes/main.go

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"fmt"
2626
"log"
2727
"os/exec"
28+
"strings"
2829

2930
"github.com/blang/semver/v4"
3031
"github.com/pkg/errors"
@@ -42,6 +43,11 @@ const (
4243
alphaRelease = "ALPHA RELEASE"
4344
betaRelease = "BETA RELEASE"
4445
releaseCandidate = "RELEASE CANDIDATE"
46+
47+
// Pre-release type constants.
48+
preReleaseAlpha = "alpha"
49+
preReleaseBeta = "beta"
50+
preReleaseRC = "rc"
4551
)
4652

4753
func main() {
@@ -140,15 +146,15 @@ func releaseTypeFromNewTag(newTagConfig string) string {
140146
return ""
141147
}
142148

143-
// Only allow RC and beta releases. More types must be defined here.
149+
// Only allow alpha, beta and RC releases. More types must be defined here.
144150
// If a new type is not defined, no warning banner will be printed.
145151
switch newTag.Pre[0].VersionStr {
146-
case "rc":
147-
return releaseCandidate
148-
case "beta":
149-
return betaRelease
150-
case "alpha":
152+
case preReleaseAlpha:
151153
return alphaRelease
154+
case preReleaseBeta:
155+
return betaRelease
156+
case preReleaseRC:
157+
return releaseCandidate
152158
}
153159
return ""
154160
}
@@ -187,6 +193,45 @@ func validateConfig(config *notesCmdConfig) error {
187193
}
188194
}
189195

196+
if config.previousReleaseVersion != "" {
197+
if err := validatePreviousReleaseVersion(config.previousReleaseVersion); err != nil {
198+
return err
199+
}
200+
}
201+
202+
return nil
203+
}
204+
205+
func validatePreviousReleaseVersion(previousReleaseVersion string) error {
206+
// Extract version string from ref format (e.g. "tags/v1.0.0-rc.1" -> "v1.0.0-rc.1")
207+
if !strings.Contains(previousReleaseVersion, "/") {
208+
return errors.New("--previous-release-version must be in ref format (e.g. tags/v1.0.0-rc.1)")
209+
}
210+
211+
parts := strings.SplitN(previousReleaseVersion, "/", 2)
212+
if len(parts) != 2 {
213+
return errors.New("--previous-release-version must be in ref format (e.g. tags/v1.0.0-rc.1)")
214+
}
215+
216+
versionStr := parts[1]
217+
218+
// Parse the version to check if it contains alpha, beta, or rc
219+
version, err := semver.ParseTolerant(versionStr)
220+
if err != nil {
221+
return errors.Wrap(err, "invalid --previous-release-version, is not a valid semver")
222+
}
223+
224+
// Check if the version has pre-release identifiers
225+
if len(version.Pre) == 0 {
226+
return errors.Errorf("--previous-release-version must contain '%s', '%s', or '%s' pre-release identifier", preReleaseAlpha, preReleaseBeta, preReleaseRC)
227+
}
228+
229+
// Check if the first pre-release identifier is 'alpha', 'beta', or 'rc'
230+
preReleaseType := version.Pre[0].VersionStr
231+
if preReleaseType != preReleaseAlpha && preReleaseType != preReleaseBeta && preReleaseType != preReleaseRC {
232+
return errors.Errorf("--previous-release-version must contain '%s', '%s', or '%s' pre-release identifier", preReleaseAlpha, preReleaseBeta, preReleaseRC)
233+
}
234+
190235
return nil
191236
}
192237

hack/tools/release/notes/main_test.go

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ limitations under the License.
2020
package main
2121

2222
import (
23+
"strings"
2324
"testing"
2425

2526
"github.com/blang/semver/v4"
@@ -229,12 +230,76 @@ func Test_validateConfig(t *testing.T) {
229230
},
230231
wantErr: false,
231232
},
233+
{
234+
name: "Invalid previousReleaseVersion without ref format",
235+
args: &notesCmdConfig{
236+
fromRef: "ref1/tags",
237+
toRef: "ref2/tags",
238+
newTag: "v1.0.0",
239+
previousReleaseVersion: "v1.0.0-rc.0",
240+
},
241+
wantErr: true,
242+
errorMessage: "--previous-release-version must be in ref format",
243+
},
244+
{
245+
name: "Valid previousReleaseVersion with rc in ref format",
246+
args: &notesCmdConfig{
247+
fromRef: "ref1/tags",
248+
toRef: "ref2/tags",
249+
newTag: "v1.0.0",
250+
previousReleaseVersion: "tags/v1.0.0-rc.0",
251+
},
252+
wantErr: false,
253+
},
254+
{
255+
name: "Valid previousReleaseVersion with alpha in ref format",
256+
args: &notesCmdConfig{
257+
fromRef: "ref1/tags",
258+
toRef: "ref2/tags",
259+
newTag: "v1.0.0",
260+
previousReleaseVersion: "tags/v1.0.0-alpha.1",
261+
},
262+
wantErr: false,
263+
},
264+
{
265+
name: "Invalid previousReleaseVersion without pre-release in ref format",
266+
args: &notesCmdConfig{
267+
fromRef: "ref1/tags",
268+
toRef: "ref2/tags",
269+
newTag: "v1.0.0",
270+
previousReleaseVersion: "tags/v1.0.0",
271+
},
272+
wantErr: true,
273+
errorMessage: "--previous-release-version must contain 'alpha', 'beta', or 'rc' pre-release identifier",
274+
},
275+
{
276+
name: "Invalid previousReleaseVersion with unsupported pre-release type",
277+
args: &notesCmdConfig{
278+
fromRef: "ref1/tags",
279+
toRef: "ref2/tags",
280+
newTag: "v1.0.0",
281+
previousReleaseVersion: "tags/v1.0.0-dev.1",
282+
},
283+
wantErr: true,
284+
errorMessage: "--previous-release-version must contain 'alpha', 'beta', or 'rc' pre-release identifier",
285+
},
286+
{
287+
name: "Invalid previousReleaseVersion with invalid semver",
288+
args: &notesCmdConfig{
289+
fromRef: "ref1/tags",
290+
toRef: "ref2/tags",
291+
newTag: "v1.0.0",
292+
previousReleaseVersion: "tags/invalid-version",
293+
},
294+
wantErr: true,
295+
errorMessage: "invalid --previous-release-version, is not a valid semver",
296+
},
232297
}
233298
for _, tt := range tests {
234299
t.Run(tt.name, func(t *testing.T) {
235300
err := validateConfig(tt.args)
236301
if tt.wantErr {
237-
if err == nil || err.Error() != tt.errorMessage {
302+
if err == nil || !strings.Contains(err.Error(), tt.errorMessage) {
238303
t.Errorf("expected error '%s', got '%v'", tt.errorMessage, err)
239304
}
240305
} else if err != nil {

0 commit comments

Comments
 (0)