Skip to content

Commit

Permalink
Merge pull request #152 from tigera/master
Browse files Browse the repository at this point in the history
Add -latest flag to specify latest release or not
  • Loading branch information
Songmu authored Oct 14, 2024
2 parents ac9295b + daec638 commit 2c84f8d
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 28 deletions.
4 changes: 2 additions & 2 deletions CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================================

github.com/google/go-github/v47
https://github.com/google/go-github/v47
github.com/google/go-github/v55
https://github.com/google/go-github/v55
----------------------------------------------------------------
Copyright (c) 2013 The go-github AUTHORS. All rights reserved.

Expand Down
57 changes: 56 additions & 1 deletion cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import (
"runtime"
"time"

"github.com/google/go-github/v47/github"
"github.com/google/go-github/v55/github"
"github.com/mitchellh/colorstring"
"github.com/tcnksm/go-gitconfig"
"github.com/thediveo/enumflag/v2"
)

const (
Expand Down Expand Up @@ -52,6 +53,20 @@ const (
defaultParallel = -1
)

type SetLatest enumflag.Flag

const (
setLatestFalse SetLatest = iota
setLatestTrue
setLatestAuto
)

var LatestIds = map[SetLatest][]string{
setLatestFalse: {"false"},
setLatestTrue: {"true"},
setLatestAuto: {"auto"},
}

// Debugf prints debug output when EnvDebug is set
func Debugf(format string, args ...interface{}) {
if env := os.Getenv(EnvDebug); len(env) != 0 {
Expand Down Expand Up @@ -86,6 +101,7 @@ func (cli *CLI) Run(args []string) int {
body string
draft bool
prerelease bool
latest SetLatest

parallel int

Expand Down Expand Up @@ -128,6 +144,12 @@ func (cli *CLI) Run(args []string) int {
flags.BoolVar(&draft, "draft", false, "")
flags.BoolVar(&prerelease, "prerelease", false, "")

flags.Var(
enumflag.New(&latest, "true", LatestIds, enumflag.EnumCaseInsensitive),
"latest",
"",
)

flags.IntVar(&parallel, "parallel", defaultParallel, "")
flags.IntVar(&parallel, "p", defaultParallel, "")

Expand Down Expand Up @@ -260,6 +282,8 @@ func (cli *CLI) Run(args []string) int {
}
Debugf("Number of file to upload: %d", len(localAssets))

Debugf("Set this release as latest: %s", latest)

// Create a GitHub client
gitHubClient, err := NewGitHubClient(owner, repo, token, baseURLStr)
if err != nil {
Expand Down Expand Up @@ -287,6 +311,31 @@ func (cli *CLI) Run(args []string) int {

ctx := context.TODO()

if latest == setLatestAuto {
latestRelease, err := ghr.GitHub.GetLatestRelease(ctx)
if err != nil {
fmt.Fprintf(cli.errStream, "Unable to fetch the latest release to compare versions: %s", err)
return ExitCodeError
}

isLatestRelease, err := ghr.IsNewerSemverRelease(req, latestRelease)
if err != nil {
fmt.Fprintf(cli.errStream, "Could not compare current and latest semver releases: %s", err)
return ExitCodeError
}
if isLatestRelease {
latest = setLatestTrue
} else {
latest = setLatestFalse
}

if latest == setLatestTrue {
req.MakeLatest = github.String("true")
} else {
req.MakeLatest = github.String("false")
}
}

if soft {
_, err := ghr.GitHub.GetRelease(ctx, *req.TagName)

Expand Down Expand Up @@ -410,6 +459,12 @@ Options:
-draft
Release as draft (Unpublish)
-latest
Set the release as the 'latest' release. Can be true, false, or auto.
Auto will set the release as 'latest' if the release names are valid
semver names and the current release is the highest version of recent
releases.
-prerelease
Create prerelease
Expand Down
27 changes: 26 additions & 1 deletion ghr.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
"path/filepath"
"time"

"github.com/google/go-github/v47/github"
"github.com/google/go-github/v55/github"
"github.com/hashicorp/go-version"
"golang.org/x/sync/errgroup"
)

Expand Down Expand Up @@ -74,6 +75,30 @@ func (g *GHR) CreateRelease(ctx context.Context, req *github.RepositoryRelease,
return g.GitHub.CreateRelease(ctx, req)
}

func (g *GHR) GetLatestRelease(ctx context.Context) (*github.RepositoryRelease, error) {
release, err := g.GitHub.GetLatestRelease(ctx)
if err != nil {
return nil, fmt.Errorf("Unable to fetch latest Github release: %w", err)
}
return release, err
}

func (g *GHR) IsNewerSemverRelease(newRelease *github.RepositoryRelease, latestRelease *github.RepositoryRelease) (bool, error) {
newReleaseVer, error := version.NewVersion(*newRelease.TagName)
if error != nil {
return false, fmt.Errorf("Unable to parse new release version as semver%s: %w", *newRelease.TagName, error)
}
latestReleaseVer, error := version.NewVersion(*latestRelease.TagName)
if error != nil {
return false, fmt.Errorf("Unable to parse latest release version as semver %s: %w", *newRelease.TagName, error)
}

if latestReleaseVer.LessThan(newReleaseVer) {
return true, nil
}
return false, nil
}

// DeleteRelease removes an existing release, if it exists. If it does not exist,
// DeleteRelease returns an error
func (g *GHR) DeleteRelease(ctx context.Context, releaseID int64, tag string) error {
Expand Down
38 changes: 37 additions & 1 deletion ghr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"testing"
"time"

"github.com/google/go-github/v47/github"
"github.com/google/go-github/v55/github"
)

func TestGHR_CreateRelease(t *testing.T) {
Expand Down Expand Up @@ -34,6 +34,42 @@ func TestGHR_CreateRelease(t *testing.T) {
defer ghr.DeleteRelease(context.TODO(), *release.ID, testTag)
}

func TestGHR_GetLatestRelease(t *testing.T) {
t.Parallel()

githubClient := testGithubClient(t)
ghr := &GHR{
GitHub: githubClient,
outStream: io.Discard,
}

testTag := "v1.2.3"

existingReq := &github.RepositoryRelease{
TagName: github.String(testTag),
Draft: github.Bool(false),
MakeLatest: github.String("true"),
}

newRelease, err := githubClient.CreateRelease(context.TODO(), existingReq)
if err != nil {
t.Fatalf("CreateRelease failed: %s", err)
}

// Create an existing release before
existing, err := ghr.GetLatestRelease(context.TODO())
if err != nil {
t.Fatalf("GetLatestRelease failed: %s", err)
}

if newRelease.Name != existing.Name {
t.Fatalf("GetLatestRelease got release %s instead of release %s", *existing.Name, *newRelease.Name)
}

defer ghr.DeleteRelease(context.TODO(), *existing.ID, testTag)

}

func TestGHR_CreateReleaseWithExistingRelease(t *testing.T) {
t.Parallel()

Expand Down
24 changes: 23 additions & 1 deletion github.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"time"

"github.com/Songmu/retry"
"github.com/google/go-github/v47/github"
"github.com/google/go-github/v55/github"
"golang.org/x/oauth2"
)

Expand All @@ -26,6 +26,7 @@ var (
type GitHub interface {
CreateRelease(ctx context.Context, req *github.RepositoryRelease) (*github.RepositoryRelease, error)
GetRelease(ctx context.Context, tag string) (*github.RepositoryRelease, error)
GetLatestRelease(ctx context.Context) (*github.RepositoryRelease, error)
GetDraftRelease(ctx context.Context, tag string) (*github.RepositoryRelease, error)
EditRelease(ctx context.Context, releaseID int64, req *github.RepositoryRelease) (*github.RepositoryRelease, error)
DeleteRelease(ctx context.Context, releaseID int64) error
Expand Down Expand Up @@ -113,6 +114,7 @@ func (c *GitHubClient) CreateRelease(ctx context.Context, req *github.Repository
func (c *GitHubClient) GetRelease(ctx context.Context, tag string) (*github.RepositoryRelease, error) {
// Check Release whether already exists or not
release, res, err := c.Repositories.GetReleaseByTag(context.TODO(), c.Owner, c.Repo, tag)

if err != nil {
if res == nil {
return nil, fmt.Errorf("failed to get release tag: %s %w", tag, err)
Expand All @@ -129,6 +131,26 @@ func (c *GitHubClient) GetRelease(ctx context.Context, tag string) (*github.Repo
return release, nil
}

// GetRelease queries the GitHub API for a specified release object
func (c *GitHubClient) GetLatestRelease(ctx context.Context) (*github.RepositoryRelease, error) {
// Check Release whether already exists or not
release, res, err := c.Repositories.GetLatestRelease(context.TODO(), c.Owner, c.Repo)
if err != nil {
if res == nil {
return nil, fmt.Errorf("failed to find latest release: %w", err)
}

// TODO(tcnksm): Handle invalid token
if res.StatusCode != http.StatusNotFound {
return nil, fmt.Errorf("get release tag: invalid status: %s %w", res.Status, err)
}

return nil, ErrReleaseNotFound
}

return release, nil
}

// GetDraftRelease queries the GitHub API for draft release with the specified tag
func (c *GitHubClient) GetDraftRelease(ctx context.Context, tag string) (*github.RepositoryRelease, error) {
const perPage = 100
Expand Down
2 changes: 1 addition & 1 deletion github_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"testing"
"time"

"github.com/google/go-github/v47/github"
"github.com/google/go-github/v55/github"
)

const (
Expand Down
14 changes: 10 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,29 @@ go 1.19

require (
github.com/Songmu/retry v0.1.0
github.com/google/go-github/v47 v47.1.0
github.com/google/go-github/v55 v55.0.0
github.com/hashicorp/go-version v1.6.0
github.com/mattn/go-colorable v0.1.13
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db
github.com/tcnksm/go-gitconfig v0.1.2
github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e
github.com/thediveo/enumflag/v2 v2.0.4
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7
)

require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-github v17.0.0+incompatible // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/onsi/gomega v1.5.0 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
Expand Down
Loading

0 comments on commit 2c84f8d

Please sign in to comment.