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

Switch to docs page to determine latest stable version #175

Merged
merged 1 commit into from Jan 19, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 64 additions & 21 deletions testserver/binaries.go
Expand Up @@ -19,7 +19,6 @@ import (
"archive/zip"
"bytes"
"compress/gzip"
"encoding/json"
"errors"
"fmt"
"io"
Expand All @@ -35,7 +34,9 @@ import (
"strings"
"time"

"github.com/cockroachdb/cockroach-go/v2/testserver/version"
"github.com/gofrs/flock"
"gopkg.in/yaml.v3"
)

const (
Expand All @@ -45,15 +46,17 @@ const (
)

const (
linuxUrlpat = "https://binaries.cockroachdb.com/cockroach-v%s.linux-%s.tgz"
macUrlpat = "https://binaries.cockroachdb.com/cockroach-v%s.darwin-%s-%s.tgz"
winUrlpat = "https://binaries.cockroachdb.com/cockroach-v%s.windows-6.2-amd64.zip"
sourceUrlPat = "https://binaries.cockroachdb.com/cockroach-v%s.src.tgz)"
linuxUrlpat = "https://binaries.cockroachdb.com/cockroach-%s.linux-%s.tgz"
macUrlpat = "https://binaries.cockroachdb.com/cockroach-%s.darwin-%s-%s.tgz"
winUrlpat = "https://binaries.cockroachdb.com/cockroach-%s.windows-6.2-amd64.zip"
)

// updatesUrl is used to get the info of the latest stable version of CRDB.
// Note that it may return a withdrawn version, but the risk is low for local tests here.
const updatesUrl = "https://register.cockroachdb.com/api/updates"
// releaseDataURL is the location of the YAML file maintained by the
// docs team where release information is encoded. This data is used
// to render the public CockroachDB releases page. We leverage the
// data in structured format to generate release information used
// for testing purposes.
const releaseDataURL = "https://raw.githubusercontent.com/cockroachdb/docs/main/src/current/_data/releases.yml"

var muslRE = regexp.MustCompile(`(?i)\bmusl\b`)

Expand Down Expand Up @@ -249,37 +252,77 @@ func DownloadBinary(tc *TestConfig, desiredVersion string, nonStable bool) (stri
}

// GetDownloadFilename returns the local filename of the downloaded CRDB binary file.
func GetDownloadFilename(
desiredVersion string,
) (string, error) {
func GetDownloadFilename(desiredVersion string) (string, error) {
filename := fmt.Sprintf("cockroach-%s", desiredVersion)
if runtime.GOOS == "windows" {
filename += ".exe"
}
return filename, nil
}

// Release contains the information we extract from the YAML file in
// `releaseDataURL`.
type Release struct {
Name string `yaml:"release_name"`
Withdrawn bool `yaml:"withdrawn"`
CloudOnly bool `yaml:"cloud_only"`
}

// getLatestStableVersionInfo returns the latest stable CRDB's download URL,
// and the formatted corresponding version number. The download URL is based
// on the runtime OS.
// Note that it may return a withdrawn version, but the risk is low for local tests here.
func getLatestStableVersionInfo() (string, string, error) {
resp, err := http.Get(updatesUrl)
resp, err := http.Get(releaseDataURL)
if err != nil {
return "", "", err
return "", "", fmt.Errorf("could not download release data: %w", err)
}
var respJson map[string]string
if err := json.NewDecoder(resp.Body).Decode(&respJson); err != nil {
return "", "", err
defer resp.Body.Close()

var blob bytes.Buffer
if _, err := io.Copy(&blob, resp.Body); err != nil {
return "", "", fmt.Errorf("error reading response body: %w", err)
}
latestStableVersion, ok := respJson["version"]
if !ok {
return "", "", fmt.Errorf("api/updates response is of wrong format")

var data []Release
if err := yaml.Unmarshal(blob.Bytes(), &data); err != nil { //nolint:yaml
return "", "", fmt.Errorf("failed to YAML parse release data: %w", err)
}

latestStableVersion := version.MustParse("v0.0.0")

for _, r := range data {
// We ignore versions that cannot be parsed; this should
// correspond to really old beta releases.
v, err := version.Parse(r.Name)
if err != nil {
continue
}

// Skip cloud-only releases, since they cannot be downloaded from
// binaries.cockroachdb.com.
if r.CloudOnly {
continue
}

// Ignore any withdrawn releases, since they are known to be broken.
if r.Withdrawn {
continue
}

// Ignore alphas, betas, and RCs.
if v.PreRelease() != "" {
continue
}

if v.Compare(latestStableVersion) > 0 {
latestStableVersion = v
}
}

downloadUrl := getDownloadUrlForVersion(latestStableVersion)
downloadUrl := getDownloadUrlForVersion(latestStableVersion.String())

latestStableVerFormatted := strings.ReplaceAll(latestStableVersion, ".", "-")
latestStableVerFormatted := strings.ReplaceAll(latestStableVersion.String(), ".", "-")
return downloadUrl, latestStableVerFormatted, nil
}

Expand Down
5 changes: 3 additions & 2 deletions testserver/testserver.go
Expand Up @@ -306,9 +306,10 @@ func NonStableDbOpt() TestServerOpt {

// CustomVersionOpt is a TestServer option that can be passed to NewTestServer to
// download the a specific version of CRDB.
func CustomVersionOpt(version string) TestServerOpt {
func CustomVersionOpt(ver string) TestServerOpt {
return func(args *testServerArgs) {
args.customVersion = version
_ = version.MustParse(ver)
args.customVersion = ver
}
}

Expand Down
2 changes: 1 addition & 1 deletion testserver/testserver_test.go
Expand Up @@ -131,7 +131,7 @@ func TestRunServer(t *testing.T) {
{
name: "InsecureCustomVersion",
instantiation: func(t *testing.T) (*sql.DB, func()) {
return testserver.NewDBForTest(t, testserver.CustomVersionOpt("21.2.15"))
return testserver.NewDBForTest(t, testserver.CustomVersionOpt("v21.2.15"))
},
},
{
Expand Down