Skip to content

Commit

Permalink
return error instead
Browse files Browse the repository at this point in the history
  • Loading branch information
nawazkh committed Mar 15, 2024
1 parent 798a388 commit 4132310
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 67 deletions.
53 changes: 14 additions & 39 deletions hack/tools/release/internal/update_providers/provider_issues.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import (
"strings"
"text/template"
"time"

"github.com/pkg/errors"
)

const (
Expand Down Expand Up @@ -59,28 +61,6 @@ var (
}
)

// Exiter is a simple interface to exit the program.
type Exiter interface {
Exit(code int)
}

// RealExiter is the real implementation of the Exiter interface.
type RealExiter struct{}

// Exit exits the program with the given code.
func (re *RealExiter) Exit(code int) {
os.Exit(code)
}

// ProviderIssues is a struct that contains the Exiter interface.
type ProviderIssues struct {
Exiter Exiter
}

func newProviderIssues() *ProviderIssues {
return &ProviderIssues{Exiter: &RealExiter{}}
}

// Issue is the struct for the issue.
type Issue struct {
Title string `json:"title"`
Expand Down Expand Up @@ -132,8 +112,11 @@ func main() {
fmt.Printf("\n")

// get release details
m := newProviderIssues()
details := m.getReleaseDetails()
details, releaseDetailsErr := getReleaseDetails()
if releaseDetailsErr != nil {
fmt.Println(releaseDetailsErr.Error())
os.Exit(1)
}

// generate title
titleBuffer := bytes.NewBuffer([]byte{})
Expand Down Expand Up @@ -274,21 +257,18 @@ func continueOrAbort() {
}

// getReleaseDetails returns the release details from the environment variables.
func (m *ProviderIssues) getReleaseDetails() releaseDetails {
func getReleaseDetails() (releaseDetails, error) {
// Parse the release tag
releaseSemVer, keySet := os.LookupEnv("RELEASE_TAG")
if !keySet || releaseSemVer == "" {
fmt.Println("RELEASE_TAG is a required environmental variable.")
fmt.Println("Refer to README.md in folder for more information.")
m.Exiter.Exit(1)
return releaseDetails{}, errors.New("release tag is a required. Refer to README.md in folder for more information")
}

// allow patterns like v1.7.0-beta.0
pattern := `^v\d+\.\d+\.\d+-beta\.\d+$`
match, err := regexp.MatchString(pattern, releaseSemVer)
if err != nil || !match {
fmt.Println("RELEASE_TAG must be in format `^v\\d+\\.\\d+\\.\\d+-beta\\.\\d+$` e.g. v1.7.0-beta.0")
m.Exiter.Exit(1)
return releaseDetails{}, errors.New("release tag must be in format `^v\\d+\\.\\d+\\.\\d+-beta\\.\\d+$` e.g. v1.7.0-beta.0")
}

major, minor, patch := "", "", ""
Expand All @@ -300,23 +280,18 @@ func (m *ProviderIssues) getReleaseDetails() releaseDetails {
minor = releaseSemVerMatch[2]
patch = releaseSemVerMatch[3]
} else {
fmt.Println("RELEASE_TAG contains invalid Major.Minor.Patch SemVer. It must be in format v(\\d+)\\.(\\d+)\\.(\\d+) e.g. v1.7.0")
m.Exiter.Exit(1)
return releaseDetails{}, errors.New("release tag contains invalid Major.Minor.Patch SemVer. It must be in format v(\\d+)\\.(\\d+)\\.(\\d+) e.g. v1.7.0")
}

// Parse the release date
releaseDate, keySet := os.LookupEnv("RELEASE_DATE")
if !keySet || releaseDate == "" {
fmt.Println("RELEASE_DATE is a required environmental variable.")
fmt.Println("Refer to README.md in folder for more information.")
m.Exiter.Exit(1)
return releaseDetails{}, errors.New("release date is a required environmental variable. Refer to README.md in folder for more information")
}

formattedReleaseDate, err := formatDate(releaseDate)
if err != nil {
fmt.Println("Unable to parse the date.", err)
fmt.Println("Refer to README.md in folder for more information.")
m.Exiter.Exit(1)
return releaseDetails{}, errors.New("unable to parse the date")
}

majorMinorWithoutPrefixV := fmt.Sprintf("%s.%s", major, minor) // e.g. 1.7 . Note that there is no "v" in the majorMinor
Expand All @@ -331,7 +306,7 @@ func (m *ProviderIssues) getReleaseDetails() releaseDetails {
BetaTag: betaTag,
ReleaseLink: releaseLink,
ReleaseNotesLink: releaseNotesLink,
}
}, nil
}

// formatDate takes a date in ISO format i.e "2006-01-02" and returns it in the format "Monday 2nd January 2006".
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,14 @@ import (
. "github.com/onsi/gomega"
)

// MockExiter is a mock implementation of the Exiter interface.
type MockExiter struct {
ExitCalled bool
ExitCode int
}

// Exit is a mock implementation of the Exiter interface.
func (me *MockExiter) Exit(code int) {
me.ExitCalled = true
me.ExitCode = code
}

func Test_GetReleaseDetails(t *testing.T) {
tests := []struct {
name string
releaseTag string
releaseDate string
want releaseDetails
expectExit bool
expectErr bool
err string
}{
{
name: "Correct RELEASE_TAG and RELEASE_DATE are set",
Expand All @@ -57,62 +46,63 @@ func Test_GetReleaseDetails(t *testing.T) {
ReleaseLink: "https://github.com/kubernetes-sigs/cluster-api/tree/main/docs/release/releases/release-1.7.md#timeline",
ReleaseNotesLink: "https://github.com/kubernetes-sigs/cluster-api/releases/tag/v1.7.0-beta.0",
},
expectExit: false,
expectErr: false,
},
{
name: "RELEASE_TAG is not in the format ^v\\d+\\.\\d+\\.\\d+-beta\\.\\d+$",
releaseTag: "v1.7.0.1",
releaseDate: "2024-04-16",
expectExit: true,
expectErr: true,
err: "release tag must be in format `^v\\d+\\.\\d+\\.\\d+-beta\\.\\d+$` e.g. v1.7.0-beta.0",
},
{
name: "RELEASE_TAG does not have prefix 'v' in its semver",
releaseTag: "1.7.0-beta.0",
releaseDate: "2024-04-16",
expectExit: true,
expectErr: true,
err: "release tag must be in format `^v\\d+\\.\\d+\\.\\d+-beta\\.\\d+$` e.g. v1.7.0-beta.0",
},
{
name: "RELEASE_TAG contains invalid Major.Minor.Patch SemVer",
releaseTag: "v1.x.0-beta.0",
releaseDate: "2024-04-16",
expectExit: true,
expectErr: true,
err: "release tag must be in format `^v\\d+\\.\\d+\\.\\d+-beta\\.\\d+$` e.g. v1.7.0-beta.0",
},
{
name: "invalid yyyy-dd-mm RELEASE_DATE entered",
releaseTag: "v1.7.0-beta.0",
releaseDate: "2024-16-4",
expectExit: true,
expectErr: true,
err: "unable to parse the date",
},
{
name: "invalid yyyy/dd/mm RELEASE_DATE entered",
releaseTag: "v1.7.0-beta.0",
releaseDate: "2024/16/4",
expectExit: true,
expectErr: true,
err: "unable to parse the date",
},
{
name: "invalid yyyy/mm/dd RELEASE_DATE entered",
releaseTag: "v1.7.0-beta.0",
releaseDate: "2024/4/16",
expectExit: true,
expectErr: true,
err: "unable to parse the date",
},
}

for _, tt := range tests {
mockExiter := &MockExiter{}
m := &ProviderIssues{Exiter: mockExiter}

t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

_ = os.Setenv("RELEASE_TAG", tt.releaseTag)
_ = os.Setenv("RELEASE_DATE", tt.releaseDate)

got := m.getReleaseDetails()
if tt.expectExit {
g.Expect(mockExiter.ExitCalled).To(BeTrue())
g.Expect(mockExiter.ExitCode).To(Equal(1))
got, err := getReleaseDetails()
if tt.expectErr {
g.Expect(err.Error()).To(Equal(tt.err))
} else {
g.Expect(mockExiter.ExitCalled).To(BeFalse())
g.Expect(got.ReleaseDate).To(Equal(tt.want.ReleaseDate))
g.Expect(got.ReleaseTag).To(Equal(tt.want.ReleaseTag))
g.Expect(got.BetaTag).To(Equal(tt.want.BetaTag))
Expand Down

0 comments on commit 4132310

Please sign in to comment.