From 23e4b331e83488a3b22243cb79bf3f89dc07d878 Mon Sep 17 00:00:00 2001 From: bnkai <48220860+bnkai@users.noreply.github.com> Date: Tue, 31 Dec 2019 03:45:58 +0200 Subject: [PATCH] * switch to Releases Github API endpoint, add latest Release URL to UI --- graphql/documents/queries/misc.graphql | 1 + graphql/schema/types/version.graphql | 1 + pkg/api/check_version.go | 114 +++++++++++++++--- pkg/api/resolver.go | 3 +- .../Settings/SettingsAboutPanel.tsx | 11 +- 5 files changed, 105 insertions(+), 25 deletions(-) diff --git a/graphql/documents/queries/misc.graphql b/graphql/documents/queries/misc.graphql index df8f0cd5549..65b0a59e1df 100644 --- a/graphql/documents/queries/misc.graphql +++ b/graphql/documents/queries/misc.graphql @@ -70,5 +70,6 @@ query Version { query LatestVersion { latestversion { shorthash + url } } diff --git a/graphql/schema/types/version.graphql b/graphql/schema/types/version.graphql index 14916f996bf..305c431cf0e 100644 --- a/graphql/schema/types/version.graphql +++ b/graphql/schema/types/version.graphql @@ -6,4 +6,5 @@ type Version { type ShortVersion { shorthash: String! + url: String! } diff --git a/pkg/api/check_version.go b/pkg/api/check_version.go index 6711af462db..aced04906e1 100644 --- a/pkg/api/check_version.go +++ b/pkg/api/check_version.go @@ -6,13 +6,24 @@ import ( "github.com/stashapp/stash/pkg/logger" "io/ioutil" "net/http" + "runtime" "time" ) //we use the github REST V3 API as no login is required const apiURL string = "https://api.github.com/repos/stashapp/stash/tags" +const apiReleases string = "https://api.github.com/repos/stashapp/stash/releases" const apiAcceptHeader string = "application/vnd.github.v3+json" +var stashReleases = func() map[string]string { + return map[string]string{ + "windows/amd64": "stash-win.exe", + "linux/amd64": "stash-linux", + "darwin/amd64": "stash-osx", + "linux/arm": "stash-pi", + } +} + type githubTagResponse struct { Name string Zipball_url string @@ -24,70 +35,137 @@ type githubTagResponse struct { Node_id string } +type githubReleasesResponse struct { + Url string + Assets_url string + Upload_url string + Html_url string + Id int64 + Node_id string + Tag_name string + Target_commitish string + Name string + Draft bool + Author githubAuthor + Prerelease bool + Created_at string + Published_at string + Assets []githubAsset + Tarball_url string + Zipball_url string + Body string +} + +type githubAuthor struct { + Login string + Id int64 + Node_id string + Avatar_url string + Gravatar_id string + Url string + Html_url string + Followers_url string + Following_url string + Gists_url string + Starred_url string + Subscriptions_url string + Organizations_url string + Repos_url string + Events_url string + Received_events_url string + Type string + Site_admin bool +} + +type githubAsset struct { + Url string + Id int64 + Node_id string + Name string + Label string + Uploader githubAuthor + Content_type string + State string + Size int64 + Download_count int64 + Created_at string + Updated_at string + Browser_download_url string +} + //gets latest version (git commit hash) from github API //the repo's tags are used to find the latest version //of the "master" or "develop" branch -func GetLatestVersion(shortHash bool) (string, error) { +func GetLatestVersion(shortHash bool) (latestVersion string, latestRelease string, err error) { + + platform := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) + wantedRelease := stashReleases()[platform] branch, _, _ := GetVersion() if branch == "" { - return "", fmt.Errorf("Stash doesn't have a version. Version check not supported.") + return "", "", fmt.Errorf("Stash doesn't have a version. Version check not supported.") } - latestVersion := "" - client := &http.Client{ Timeout: 3 * time.Second, } - req, _ := http.NewRequest("GET", apiURL, nil) + req, _ := http.NewRequest("GET", apiReleases, nil) req.Header.Add("Accept", apiAcceptHeader) // gh api recommendation , send header with api version response, err := client.Do(req) - input := make([]githubTagResponse, 0) + input := make([]githubReleasesResponse, 0) if err != nil { - return "", fmt.Errorf("Github API request failed: %s", err) + return "", "", fmt.Errorf("Github API request failed: %s", err) } else { defer response.Body.Close() data, err := ioutil.ReadAll(response.Body) if err != nil { - return "", fmt.Errorf("Github API read response failed: %s", err) + return "", "", fmt.Errorf("Github API read response failed: %s", err) } else { - err := json.Unmarshal(data, &input) + err = json.Unmarshal(data, &input) if err != nil { - return "", fmt.Errorf("Unmarshalling Github API response failed: %s", err) + return "", "", fmt.Errorf("Unmarshalling Github API response failed: %s", err) } else { for _, ghApi := range input { - if ghApi.Name == branch { + if ghApi.Tag_name == branch { if shortHash { - latestVersion = ghApi.Commit.Sha[0:7] //shorthash is first 7 digits of git commit hash + latestVersion = ghApi.Target_commitish[0:7] //shorthash is first 7 digits of git commit hash } else { - latestVersion = ghApi.Commit.Sha + latestVersion = ghApi.Target_commitish } - + if wantedRelease != "" { + for _, asset := range ghApi.Assets { + if asset.Name == wantedRelease { + latestRelease = asset.Browser_download_url + break + } + + } + } + break } } } } if latestVersion == "" { - return "", fmt.Errorf("No version found for \"%s\"", branch) + return "", "", fmt.Errorf("No version found for \"%s\"", branch) } - } - return latestVersion, nil + return latestVersion, latestRelease, nil } func printLatestVersion() { _, githash, _ = GetVersion() - latest, err := GetLatestVersion(true) + latest, _, err := GetLatestVersion(true) if err != nil { logger.Errorf("Couldn't find latest version :%s\n", err) } else { diff --git a/pkg/api/resolver.go b/pkg/api/resolver.go index fb76e03490e..126003a6f74 100644 --- a/pkg/api/resolver.go +++ b/pkg/api/resolver.go @@ -118,7 +118,7 @@ func (r *queryResolver) Version(ctx context.Context) (*models.Version, error) { //Gets latest version (git shorthash commit for now) func (r *queryResolver) Latestversion(ctx context.Context) (*models.ShortVersion, error) { - ver, err := GetLatestVersion(true) + ver, url, err := GetLatestVersion(true) if err == nil { logger.Infof("Retrieved latest hash: %s", ver) } else { @@ -127,6 +127,7 @@ func (r *queryResolver) Latestversion(ctx context.Context) (*models.ShortVersion return &models.ShortVersion{ Shorthash: ver, + URL: url, }, err } diff --git a/ui/v2/src/components/Settings/SettingsAboutPanel.tsx b/ui/v2/src/components/Settings/SettingsAboutPanel.tsx index 20b0b5c7012..dc94f211475 100644 --- a/ui/v2/src/components/Settings/SettingsAboutPanel.tsx +++ b/ui/v2/src/components/Settings/SettingsAboutPanel.tsx @@ -17,7 +17,7 @@ interface IProps { } export const SettingsAboutPanel: FunctionComponent = (props: IProps) => { const { data, error, loading } = StashService.useVersion(); const { data: dt, error: er, loading: ld, refetch, networkStatus } = StashService.useLatestVersion(); - + function maybeRenderTag() { if (!data || !data.version || !data.version.version) { return; } return ( @@ -29,7 +29,7 @@ export const SettingsAboutPanel: FunctionComponent = (props: IProps) => } function maybeRenderLatestVersion() { - if (!dt || !dt.latestversion || !dt.latestversion.shorthash) { return; } + if (!dt || !dt.latestversion || !dt.latestversion.shorthash || !dt.latestversion.url) { return; } if (!data || !data.version || !data.version.hash) { return ( <>{dt.latestversion.shorthash} @@ -38,7 +38,9 @@ export const SettingsAboutPanel: FunctionComponent = (props: IProps) => if (data.version.hash !== dt.latestversion.shorthash) { return ( - {dt.latestversion.shorthash} (NEW) + <> + {dt.latestversion.shorthash} [NEW] Download + ); } @@ -55,9 +57,6 @@ export const SettingsAboutPanel: FunctionComponent = (props: IProps) => < td>Latest Version Build Hash: < td>{maybeRenderLatestVersion()} - - Get latest releases on Github -