CI: Add artifacts npm commands from grabpl (#61908)
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
package versions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
reGrafanaTag = regexp.MustCompile(`^v(\d+\.\d+\.\d+$)`)
|
||||
reGrafanaTagBeta = regexp.MustCompile(`^v(\d+\.\d+\.\d+-beta)`)
|
||||
reGrafanaTagCustom = regexp.MustCompile(`^v(\d+\.\d+\.\d+-\w+)`)
|
||||
)
|
||||
|
||||
const (
|
||||
Latest = "latest"
|
||||
Next = "next"
|
||||
Test = "test"
|
||||
)
|
||||
|
||||
type Version struct {
|
||||
Version string
|
||||
Channel string
|
||||
}
|
||||
|
||||
type VersionFromAPI struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type LatestGcomAPI = string
|
||||
|
||||
const (
|
||||
LatestStableVersionURL LatestGcomAPI = "https://grafana.com/api/grafana/versions/stable"
|
||||
LatestBetaVersionURL LatestGcomAPI = "https://grafana.com/api/grafana/versions/beta"
|
||||
)
|
||||
|
||||
func GetLatestVersion(url LatestGcomAPI) (string, error) {
|
||||
// nolint:gosec
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
log.Printf("Failed to close body: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("server returned non 200 status code: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var apiResponse VersionFromAPI
|
||||
err = json.Unmarshal(body, &apiResponse)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return apiResponse.Version, nil
|
||||
}
|
||||
|
||||
// IsGreaterThanOrEqual semantically checks whether newVersion is greater than or equal to stableVersion.
|
||||
func IsGreaterThanOrEqual(newVersion, stableVersion string) (bool, error) {
|
||||
v1SemVer, err := semver.NewVersion(newVersion)
|
||||
if err != nil {
|
||||
return isGreaterThanOrEqualFourDigit(newVersion, stableVersion)
|
||||
}
|
||||
|
||||
v2SemVer, err := semver.NewVersion(stableVersion)
|
||||
if err != nil {
|
||||
return isGreaterThanOrEqualFourDigit(newVersion, stableVersion)
|
||||
}
|
||||
|
||||
comp := v1SemVer.Compare(v2SemVer)
|
||||
switch comp {
|
||||
case -1:
|
||||
return false, nil
|
||||
case 1, 0:
|
||||
return true, nil
|
||||
default:
|
||||
return true, fmt.Errorf("unknown comparison value between scemantic versions, err: %q", err)
|
||||
}
|
||||
}
|
||||
|
||||
var fourDigitRe = regexp.MustCompile(`(\d+\.\d+\.\d+)\.(\d+)`)
|
||||
|
||||
func parseFourDigit(version string) (*semver.Version, int, error) {
|
||||
matches := fourDigitRe.FindStringSubmatch(version)
|
||||
if len(matches) < 2 {
|
||||
semVer, err := semver.NewVersion(version)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return semVer, 0, nil
|
||||
}
|
||||
semVer, err := semver.NewVersion(matches[1])
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
i, err := strconv.Atoi(matches[2])
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return semVer, i, nil
|
||||
}
|
||||
|
||||
func isGreaterThanOrEqualFourDigit(newVersion, stableVersion string) (bool, error) {
|
||||
newVersionSemVer, newVersionSemVerNo, err := parseFourDigit(newVersion)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
stableVersionSemVer, stableVersionSemVerNo, err := parseFourDigit(stableVersion)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if stableVersionSemVer.Original() != newVersionSemVer.Original() {
|
||||
return IsGreaterThanOrEqual(newVersionSemVer.Original(), stableVersionSemVer.Original())
|
||||
}
|
||||
|
||||
return newVersionSemVerNo >= stableVersionSemVerNo, nil
|
||||
}
|
||||
|
||||
func GetVersion(tag string) (*Version, error) {
|
||||
var version Version
|
||||
switch {
|
||||
case reGrafanaTag.MatchString(tag):
|
||||
version = Version{
|
||||
Version: reGrafanaTag.FindStringSubmatch(tag)[1],
|
||||
Channel: Latest,
|
||||
}
|
||||
case reGrafanaTagBeta.MatchString(tag):
|
||||
version = Version{
|
||||
Version: reGrafanaTagBeta.FindStringSubmatch(tag)[1],
|
||||
Channel: Next,
|
||||
}
|
||||
case reGrafanaTagCustom.MatchString(tag):
|
||||
version = Version{
|
||||
Version: reGrafanaTagCustom.FindStringSubmatch(tag)[1],
|
||||
Channel: Test,
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("%s not a supported Grafana version, exitting", tag)
|
||||
}
|
||||
|
||||
return &version, nil
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package versions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestIsGreaterThanOrEqual(t *testing.T) {
|
||||
testCases := []struct {
|
||||
newVersion string
|
||||
stableVersion string
|
||||
expected bool
|
||||
}{
|
||||
{newVersion: "9.0.0", stableVersion: "8.0.0", expected: true},
|
||||
{newVersion: "6.0.0", stableVersion: "6.0.0", expected: true},
|
||||
{newVersion: "7.0.0", stableVersion: "8.0.0", expected: false},
|
||||
{newVersion: "8.5.0-beta1", stableVersion: "8.0.0", expected: true},
|
||||
{newVersion: "8.5.0", stableVersion: "8.5.0-beta1", expected: true},
|
||||
{newVersion: "9.0.0.1", stableVersion: "9.0.0", expected: true},
|
||||
{newVersion: "9.0.0.2", stableVersion: "9.0.0.1", expected: true},
|
||||
{newVersion: "9.1.0", stableVersion: "9.0.0.1", expected: true},
|
||||
{newVersion: "9.1-0-beta1", stableVersion: "9.0.0.1", expected: true},
|
||||
{newVersion: "9.0.0.1", stableVersion: "9.0.1.1", expected: false},
|
||||
{newVersion: "9.0.1.1", stableVersion: "9.0.0.1", expected: true},
|
||||
{newVersion: "9.0.0.1", stableVersion: "9.0.0.1", expected: true},
|
||||
{newVersion: "7.0.0.1", stableVersion: "8.0.0", expected: false},
|
||||
{newVersion: "9.1-0-beta1", stableVersion: "9.1-0-beta2", expected: false},
|
||||
{newVersion: "9.1-0-beta3", stableVersion: "9.1-0-beta2", expected: true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
name := fmt.Sprintf("newVersion %s greater than or equal stableVersion %s = %v", tc.newVersion, tc.stableVersion, tc.expected)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
result, err := IsGreaterThanOrEqual(tc.newVersion, tc.stableVersion)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetLatestVersion(t *testing.T) {
|
||||
t.Run("it returns a version", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
response := VersionFromAPI{
|
||||
Version: "8.4.0",
|
||||
}
|
||||
jsonRes, err := json.Marshal(&response)
|
||||
require.NoError(t, err)
|
||||
_, err = w.Write(jsonRes)
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
version, err := GetLatestVersion(server.URL)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "8.4.0", version)
|
||||
})
|
||||
|
||||
t.Run("it handles non 200 responses", func(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}))
|
||||
_, err := GetLatestVersion(server.URL)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user