Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reimplement functions in go-mouff-update, use ghreposervice #5470

Merged
merged 7 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion flytectl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ include ../boilerplate/flyte/docker_build/Makefile
include ../boilerplate/flyte/golang_test_targets/Makefile
include ../boilerplate/flyte/end2end/Makefile

GIT_VERSION := $(shell git describe --always --tags)
GIT_VERSION := $(shell git describe --dirty --tags --long --match 'flytectl/*' --first-parent | sed 's/^flytectl\///')
GIT_HASH := $(shell git rev-parse --short HEAD)
TIMESTAMP := $(shell date '+%Y-%m-%d')
PACKAGE ?=github.com/flyteorg/flyte/flytestdlib
Expand Down
2 changes: 1 addition & 1 deletion flytectl/cmd/upgrade/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func upgrade(u *updater.Updater) (string, error) {
}

func isUpgradeSupported(goos platformutil.Platform) (bool, error) {
latest, err := github.FlytectlReleaseConfig.GetLatestVersion()
latest, err := github.FlytectlReleaseConfig.Provider.(*github.GHProvider).GetCleanLatestVersion()
if err != nil {
return false, err
}
Expand Down
5 changes: 0 additions & 5 deletions flytectl/cmd/upgrade/upgrade_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package upgrade

import (
"fmt"
"sort"
"testing"

Expand Down Expand Up @@ -172,7 +171,3 @@ func TestSelfUpgradeRollback(t *testing.T) {
})

}

func TestMain(_ *testing.M) {
fmt.Println("Skipping due to https://github.com/flyteorg/flyte/issues/5372")
}
2 changes: 1 addition & 1 deletion flytectl/cmd/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func GetVersionCommand(rootCmd *cobra.Command) map[string]cmdCore.CommandEntry {

func getVersion(ctx context.Context, args []string, cmdCtx cmdCore.CommandContext) error {
goos := platformutil.Platform(runtime.GOOS)
version, err := github.FlytectlReleaseConfig.GetLatestVersion()
version, err := github.FlytectlReleaseConfig.Provider.(*github.GHProvider).GetCleanLatestVersion()
if err != nil {
logger.Error(ctx, "Unable to get the latest version because %v", err)
} else {
Expand Down
3 changes: 3 additions & 0 deletions flytectl/cmd/version/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func TestVersionCommand(t *testing.T) {
func TestVersionCommandFunc(t *testing.T) {
ctx := context.Background()
s := testutils.Setup()
defer s.TearDown()
stdlibversion.Build = ""
stdlibversion.BuildTime = ""
stdlibversion.Version = testVersion
Expand All @@ -67,6 +68,7 @@ func TestVersionCommandFunc(t *testing.T) {
func TestVersionCommandFuncError(t *testing.T) {
ctx := context.Background()
s := testutils.Setup()
defer s.TearDown()
stdlibversion.Build = ""
stdlibversion.BuildTime = ""
stdlibversion.Version = "v"
Expand All @@ -79,6 +81,7 @@ func TestVersionCommandFuncError(t *testing.T) {
func TestVersionCommandFuncErr(t *testing.T) {
ctx := context.Background()
s := testutils.Setup()
defer s.TearDown()
stdlibversion.Build = ""
stdlibversion.BuildTime = ""
stdlibversion.Version = testVersion
Expand Down
4 changes: 2 additions & 2 deletions flytectl/pkg/github/githubutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/flyteorg/flyte/flytestdlib/logger"
stdlibversion "github.com/flyteorg/flyte/flytestdlib/version"
"github.com/google/go-github/v42/github"
"github.com/mouuff/go-rocket-update/pkg/provider"
"github.com/mouuff/go-rocket-update/pkg/updater"
"golang.org/x/oauth2"
"golang.org/x/text/cases"
Expand All @@ -39,9 +38,10 @@ var Client GHRepoService

// FlytectlReleaseConfig represent the updater config for flytectl binary
var FlytectlReleaseConfig = &updater.Updater{
Provider: &provider.Github{
Provider: &GHProvider{
RepositoryURL: flytectlRepository,
ArchiveName: getFlytectlAssetName(),
ghRepo: GetGHRepoService(),
},
ExecutableName: flytectl,
Version: stdlibversion.Version,
Expand Down
175 changes: 175 additions & 0 deletions flytectl/pkg/github/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package github

import (
"context"
"errors"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"

go_github "github.com/google/go-github/v42/github"
"github.com/mouuff/go-rocket-update/pkg/provider"
)

// Github provider finds a archive file in the repository's releases to provide files
type GHProvider struct {
RepositoryURL string // Repository URL, example github.com/mouuff/go-rocket-update
ArchiveName string // Archive name (the zip/tar.gz you upload for a release on github), example: binaries.zip

tmpDir string // temporary directory this is used internally
decompressProvider provider.Provider // provider used to decompress the downloaded archive
archivePath string // path to the downloaded archive (should be in tmpDir)
ghRepo GHRepoService // github repository service
}

// githubRepositoryInfo is used to get the name of the project and the owner name
// from this fields we are able to get other links (such as the release and tags link)
type githubRepositoryInfo struct {
RepositoryOwner string
RepositoryName string
}

// getRepositoryInfo parses the github repository URL
func (c *GHProvider) repositoryInfo() (*githubRepositoryInfo, error) {
re := regexp.MustCompile(`github\.com/(.*?)/(.*?)$`)
submatches := re.FindAllStringSubmatch(c.RepositoryURL, 1)
if len(submatches) < 1 {
return nil, errors.New("Invalid github URL:" + c.RepositoryURL)

Check warning on line 41 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L37-L41

Added lines #L37 - L41 were not covered by tests
}
return &githubRepositoryInfo{
RepositoryOwner: submatches[0][1],
RepositoryName: submatches[0][2],
}, nil

Check warning on line 46 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L43-L46

Added lines #L43 - L46 were not covered by tests
}

// getArchiveURL get the archive URL for the github repository
// If no tag is provided then the latest version is selected
func (c *GHProvider) getArchiveURL(tag string) (string, error) {
if len(tag) == 0 {

Check warning on line 52 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L51-L52

Added lines #L51 - L52 were not covered by tests
// Get latest version if no tag is provided
var err error
tag, err = c.GetLatestVersion()
if err != nil {
return "", err

Check warning on line 57 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L54-L57

Added lines #L54 - L57 were not covered by tests
}
}

info, err := c.repositoryInfo()
if err != nil {
return "", err

Check warning on line 63 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L61-L63

Added lines #L61 - L63 were not covered by tests
}
return fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s",
info.RepositoryOwner,
info.RepositoryName,
tag,
c.ArchiveName,
), nil

Check warning on line 70 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L65-L70

Added lines #L65 - L70 were not covered by tests
}

// Open opens the provider
func (c *GHProvider) Open() (err error) {
archiveURL, err := c.getArchiveURL("") // get archive url for latest version
if err != nil {
return err

Check warning on line 77 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L74-L77

Added lines #L74 - L77 were not covered by tests
}
req, err := http.NewRequest("GET", archiveURL, nil)
if err != nil {
return err

Check warning on line 81 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L79-L81

Added lines #L79 - L81 were not covered by tests
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err

Check warning on line 85 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L83-L85

Added lines #L83 - L85 were not covered by tests
}
defer resp.Body.Close()

Check warning on line 87 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L87

Added line #L87 was not covered by tests

c.tmpDir, err = os.MkdirTemp("", "rocket-update")
if err != nil {
return err

Check warning on line 91 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L89-L91

Added lines #L89 - L91 were not covered by tests
}

c.archivePath = filepath.Join(c.tmpDir, c.ArchiveName)
archiveFile, err := os.Create(c.archivePath)
if err != nil {
return err

Check warning on line 97 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L94-L97

Added lines #L94 - L97 were not covered by tests
}
_, err = io.Copy(archiveFile, resp.Body)
archiveFile.Close()
if err != nil {
return err

Check warning on line 102 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L99-L102

Added lines #L99 - L102 were not covered by tests
}
c.decompressProvider, err = provider.Decompress(c.archivePath)
if err != nil {
return err

Check warning on line 106 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L104-L106

Added lines #L104 - L106 were not covered by tests
}
return c.decompressProvider.Open()

Check warning on line 108 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L108

Added line #L108 was not covered by tests
}

// Close closes the provider
func (c *GHProvider) Close() error {
if c.decompressProvider != nil {
c.decompressProvider.Close()
c.decompressProvider = nil

Check warning on line 115 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L112-L115

Added lines #L112 - L115 were not covered by tests
}

if len(c.tmpDir) > 0 {
os.RemoveAll(c.tmpDir)
c.tmpDir = ""
c.archivePath = ""

Check warning on line 121 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L118-L121

Added lines #L118 - L121 were not covered by tests
}
return nil

Check warning on line 123 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L123

Added line #L123 was not covered by tests
}

// GetLatestVersion gets the latest version
func (c *GHProvider) GetLatestVersion() (string, error) {
tags, err := c.getReleases()
if err != nil {
return "", err

Check warning on line 130 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L130

Added line #L130 was not covered by tests
}
latestTag := tags[0].GetTagName()
return latestTag, err
}

// GetCleanLatestVersion gets the latest version without the "flytectl/" prefix
func (c *GHProvider) GetCleanLatestVersion() (string, error) {
latest, err := c.GetLatestVersion()
if err != nil {
return "", err

Check warning on line 140 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L140

Added line #L140 was not covered by tests
}
clearVersion := strings.TrimPrefix(latest, fmt.Sprintf("%s/", flytectl))
return clearVersion, nil
}

func (c *GHProvider) getReleases() ([]*go_github.RepositoryRelease, error) {
g := c.ghRepo
releases, _, err := g.ListReleases(context.Background(), owner, flyte, &go_github.ListOptions{
PerPage: 100,
})
if err != nil {
return nil, err

Check warning on line 152 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L152

Added line #L152 was not covered by tests
}
var filteredReleases []*go_github.RepositoryRelease
for _, release := range releases {
if strings.HasPrefix(release.GetTagName(), flytectl) {
filteredReleases = append(filteredReleases, release)
}
}
return filteredReleases, err
}

// Walk walks all the files provided
func (c *GHProvider) Walk(walkFn provider.WalkFunc) error {
if c.decompressProvider == nil {

Check warning on line 165 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L164-L165

Added lines #L164 - L165 were not covered by tests
// TODO specify error
return provider.ErrNotOpenned

Check warning on line 167 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L167

Added line #L167 was not covered by tests
}
return c.decompressProvider.Walk(walkFn)

Check warning on line 169 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L169

Added line #L169 was not covered by tests
}

// Retrieve file relative to "provider" to destination
func (c *GHProvider) Retrieve(src string, dest string) error {
return c.decompressProvider.Retrieve(src, dest)

Check warning on line 174 in flytectl/pkg/github/provider.go

View check run for this annotation

Codecov / codecov/patch

flytectl/pkg/github/provider.go#L173-L174

Added lines #L173 - L174 were not covered by tests
}
68 changes: 68 additions & 0 deletions flytectl/pkg/github/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package github

import (
"testing"

"github.com/flyteorg/flyte/flytectl/pkg/github/mocks"
go_github "github.com/google/go-github/v42/github"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)

func TestGetLatestFlytectlVersion(t *testing.T) {
t.Run("Get latest release", func(t *testing.T) {
mockGh := &mocks.GHRepoService{}
// return a list of github releases
mockGh.OnListReleasesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(
[]*go_github.RepositoryRelease{
{TagName: go_github.String("flytectl/1.2.4")},
{TagName: go_github.String("flytectl/1.2.3")},
{TagName: go_github.String("other-1.0.0")},
},
nil,
nil,
)
mockProvider := &GHProvider{
RepositoryURL: flytectlRepository,
ArchiveName: getFlytectlAssetName(),
ghRepo: mockGh,
}

latestVersion, err := mockProvider.GetLatestVersion()
assert.Nil(t, err)
assert.Equal(t, "flytectl/1.2.4", latestVersion)
cleanVersion, err := mockProvider.GetCleanLatestVersion()
assert.Nil(t, err)
assert.Equal(t, "1.2.4", cleanVersion)
})
}

func TestGetFlytectlReleases(t *testing.T) {
t.Run("Get releases", func(t *testing.T) {
mockGh := &mocks.GHRepoService{}
allReleases := []*go_github.RepositoryRelease{
{TagName: go_github.String("flytectl/1.2.4")},
{TagName: go_github.String("flytectl/1.2.3")},
{TagName: go_github.String("other-1.0.0")},
}
releases := []*go_github.RepositoryRelease{
{TagName: go_github.String("flytectl/1.2.4")},
{TagName: go_github.String("flytectl/1.2.3")},
}
// return a list of github releases
mockGh.OnListReleasesMatch(mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(
allReleases,
nil,
nil,
)
mockProvider := &GHProvider{
RepositoryURL: flytectlRepository,
ArchiveName: getFlytectlAssetName(),
ghRepo: mockGh,
}

flytectlReleases, err := mockProvider.getReleases()
assert.Nil(t, err)
assert.Equal(t, releases, flytectlReleases)
})
}
Loading