Repository: bazelbuild/bazelisk
Pull request #303 (2022-02-22 21:21:36)

Download native macOS arm64 binary on M1
When using macOS on M1 and downloading a commit or any keyword that resolves to a commit (e.g., `last_green`) `bazelisk` was downloading from the url: `https://storage.googleapis.com/bazel-builds/artifacts/macos/[commit]/bazel`.

This PR changes the url to be of the form: `https://storage.googleapis.com/bazel-builds/artifacts/macos_arm64/[commit]/bazel`.

Also, to get tests to now pass on M1, `test.sh` has been updated to insert the arch determined from `uname -m` for the versions that support `arm64`.

See: https://github.com/bazelbuild/continuous-integration/issues/1338


Patch:
diff --git a/bazelisk.go b/bazelisk.go
index 1aebe0d..5cdee07 100644
--- a/bazelisk.go
+++ b/bazelisk.go
@@ -26,9 +26,8 @@ import (
 func main() {
 	gcs := &repositories.GCSRepo{}
 	gitHub := repositories.CreateGitHubRepo(core.GetEnvOrConfig("BAZELISK_GITHUB_TOKEN"))
-	// Fetch LTS releases, release candidates and Bazel-at-commits from GCS, forks and rolling releases from GitHub.
-	// TODO(https://github.com/bazelbuild/bazelisk/issues/228): get rolling releases from GCS, too.
-	repos := core.CreateRepositories(gcs, gcs, gitHub, gcs, gitHub, true)
+	// Fetch LTS releases, release candidates, rolling releases and Bazel-at-commits from GCS, forks from GitHub.
+	repos := core.CreateRepositories(gcs, gcs, gitHub, gcs, gcs, true)
 
 	exitCode, err := core.RunBazelisk(os.Args[1:], repos)
 	if err != nil {
diff --git a/platforms/platforms.go b/platforms/platforms.go
index 8e51ec7..6c6b4e8 100644
--- a/platforms/platforms.go
+++ b/platforms/platforms.go
@@ -13,7 +13,12 @@ var platforms = map[string]string{"darwin": "macos", "linux": "ubuntu1404", "win
 // GetPlatform returns a Bazel CI-compatible platform identifier for the current operating system.
 // TODO(fweikert): raise an error for unsupported platforms
 func GetPlatform() string {
-	return platforms[runtime.GOOS]
+	platform := platforms[runtime.GOOS]
+	arch := runtime.GOARCH
+	if arch == "arm64" {
+		platform = platform + "_arm64"
+	}
+	return platform
 }
 
 // DetermineExecutableFilenameSuffix returns the extension for binaries on the current operating system.
diff --git a/repositories/gcs.go b/repositories/gcs.go
index 82e33dd..170f172 100644
--- a/repositories/gcs.go
+++ b/repositories/gcs.go
@@ -239,3 +239,40 @@ func (gcs *GCSRepo) DownloadAtCommit(commit, destDir, destFile string) (string,
 	url := fmt.Sprintf("%s/%s/%s/bazel", nonCandidateBaseURL, platforms.GetPlatform(), commit)
 	return httputil.DownloadBinary(url, destDir, destFile)
 }
+
+// RollingRepo
+
+// GetRollingVersions returns a list of all available rolling release versions for the newest release.
+func (gcs *GCSRepo) GetRollingVersions(bazeliskHome string) ([]string, error) {
+	history, err := getVersionHistoryFromGCS()
+	if err != nil {
+		return []string{}, err
+	}
+
+	newest := history[len(history)-1]
+	versions, _, err := listDirectoriesInReleaseBucket(newest + "/rolling/")
+	if err != nil {
+		return []string{}, err
+	}
+
+	releases := make([]string, 0)
+	for _, v := range versions {
+		if !strings.Contains(v, "rc") {
+			releases = append(releases, strings.Split(v, "/")[2])
+		}
+	}
+
+	return releases, nil
+}
+
+// DownloadRolling downloads the given Bazel version into the specified location and returns the absolute path.
+func (gcs *GCSRepo) DownloadRolling(version, destDir, destFile string) (string, error) {
+	srcFile, err := platforms.DetermineBazelFilename(version, true)
+	if err != nil {
+		return "", err
+	}
+
+	release_version := strings.Split(version, "-")[0]
+	url := fmt.Sprintf("%s/%s/rolling/%s/%s", candidateBaseURL, release_version, version, srcFile)
+	return httputil.DownloadBinary(url, destDir, destFile)
+}
diff --git a/repositories/github.go b/repositories/github.go
index 60baacb..b75edcd 100644
--- a/repositories/github.go
+++ b/repositories/github.go
@@ -6,7 +6,6 @@ import (
 
 	"github.com/bazelbuild/bazelisk/httputil"
 	"github.com/bazelbuild/bazelisk/platforms"
-	"github.com/bazelbuild/bazelisk/versions"
 )
 
 const (
@@ -89,14 +88,3 @@ func (gh *GitHubRepo) DownloadVersion(fork, version, destDir, destFile string) (
 	url := fmt.Sprintf(urlPattern, fork, version, filename)
 	return httputil.DownloadBinary(url, destDir, destFile)
 }
-
-// GetRollingVersions returns a list of all available rolling release versions.
-func (gh *GitHubRepo) GetRollingVersions(bazeliskHome string) ([]string, error) {
-	// Release candidates are uploaded to GCS only, which means that all prerelease binaries on GitHub belong to rolling releases.
-	return gh.getFilteredVersions(bazeliskHome, versions.BazelUpstream, true)
-}
-
-// DownloadRolling downloads the given Bazel version into the specified location and returns the absolute path.
-func (gh *GitHubRepo) DownloadRolling(version, destDir, destFile string) (string, error) {
-	return gh.DownloadVersion(versions.BazelUpstream, version, destDir, destFile)
-}


Test patch:
diff --git a/bazelisk_version_test.go b/bazelisk_version_test.go
index b754f81..bd83cf7 100644
--- a/bazelisk_version_test.go
+++ b/bazelisk_version_test.go
@@ -208,8 +208,8 @@ func TestResolveLatestVersion_GitHubIsDown(t *testing.T) {
 }
 
 func TestAcceptRollingReleaseName(t *testing.T) {
-	gh := repositories.CreateGitHubRepo("test_token")
-	repos := core.CreateRepositories(nil, nil, nil, nil, gh, false)
+	gcs := &repositories.GCSRepo{}
+	repos := core.CreateRepositories(nil, nil, nil, nil, gcs, false)
 
 	for _, version := range []string{"10.0.0-pre.20201103.4", "10.0.0-pre.20201103.4.2"} {
 		resolvedVersion, _, err := repos.ResolveVersion(tmpDir, "", version)
@@ -225,31 +225,13 @@ func TestAcceptRollingReleaseName(t *testing.T) {
 }
 
 func TestResolveLatestRollingRelease(t *testing.T) {
-	text := `
-	[
-	  {
-		"tag_name": "4.0.0",
-		"prerelease": false
-	  },
-	  {
-		"tag_name": "5.0.0-pre.20210319.1",
-		"prerelease": true
-	  },
-	  {
-		"tag_name": "5.0.0-pre.20210322.4",
-		"prerelease": true
-	  },
-	  {
-		"tag_name": "5.0.0",
-		"prerelease": false
-	  }
-	]
-	`
-	transport := installTransport()
-	transport.AddResponse("https://api.github.com/repos/bazelbuild/bazel/releases", 200, text, nil)
+	s := setUp(t)
+	s.AddVersion("11.0.0", false, nil, []string{"11.0.0/rolling/11.0.0-pre.20210503.1"})
+	s.AddVersion("12.0.0", false, nil, []string{"12.0.0/rolling/12.0.0-pre.20210504.1"})
+	s.Finish()
 
-	gh := repositories.CreateGitHubRepo("test_token")
-	repos := core.CreateRepositories(nil, nil, nil, nil, gh, false)
+	gcs := &repositories.GCSRepo{}
+	repos := core.CreateRepositories(nil, nil, nil, nil, gcs, false)
 
 	version, _, err := repos.ResolveVersion(tmpDir, "", rollingReleaseIdentifier)
 
@@ -257,7 +239,7 @@ func TestResolveLatestRollingRelease(t *testing.T) {
 		t.Fatalf("ResolveVersion(%q, \"\", %q): expected no error, but got %v", tmpDir, rollingReleaseIdentifier, err)
 	}
 
-	want := "5.0.0-pre.20210322.4"
+	want := "12.0.0-pre.20210504.1"
 	if version != want {
 		t.Fatalf("ResolveVersion(%q, \"\", %q) = %v, but expected %v", tmpDir, rollingReleaseIdentifier, version, want)
 	}
@@ -308,9 +290,7 @@ func (g *gcsSetup) AddVersion(version string, hasRelease bool, rcs []int, rollin
 		register(fmt.Sprintf("rc%d", rc))
 	}
 
-	for _, r := range rolling {
-		register(r)
-	}
+	g.addURL(fmt.Sprintf("%s/rolling/", version), false, rolling...)
 
 	// The /release/ URLs have to exist, even if there is no release. In this case GCS returns no items, though.
 	releasePrefix := fmt.Sprintf("%s/release/", version)
diff --git a/test.sh b/test.sh
index 074086d..811bf84 100755
--- a/test.sh
+++ b/test.sh
@@ -3,13 +3,15 @@
 set -euxo pipefail
 
 rm -rf "$HOME/Library/Caches/bazelisk"
-env -u USE_BAZEL_VERSION ./bin/bazelisk-darwin-amd64 version
-USE_BAZEL_VERSION="latest" ./bin/bazelisk-darwin-amd64 version
+
+arch=$(uname -m)
+env -u USE_BAZEL_VERSION ./bin/bazelisk-darwin-"$arch" version
+USE_BAZEL_VERSION="latest" ./bin/bazelisk-darwin-"$arch" version
 USE_BAZEL_VERSION="0.28.0" ./bin/bazelisk-darwin-amd64 version
-USE_BAZEL_VERSION="last_green" ./bin/bazelisk-darwin-amd64 version
-USE_BAZEL_VERSION="last_downstream_green" ./bin/bazelisk-darwin-amd64 version
-USE_BAZEL_VERSION="last_rc" ./bin/bazelisk-darwin-amd64 version
-USE_BAZEL_VERSION="bazelbuild/latest" ./bin/bazelisk-darwin-amd64 version
+USE_BAZEL_VERSION="last_green" ./bin/bazelisk-darwin-"$arch" version
+USE_BAZEL_VERSION="last_downstream_green" ./bin/bazelisk-darwin-"$arch" version
+USE_BAZEL_VERSION="last_rc" ./bin/bazelisk-darwin-"$arch" version
+USE_BAZEL_VERSION="bazelbuild/latest" ./bin/bazelisk-darwin-"$arch" version
 USE_BAZEL_VERSION="bazelbuild/0.27.0" ./bin/bazelisk-darwin-amd64 version
-USE_BAZEL_VERSION="philwo/latest" ./bin/bazelisk-darwin-amd64 version
+USE_BAZEL_VERSION="philwo/latest" ./bin/bazelisk-darwin-"$arch" version
 USE_BAZEL_VERSION="philwo/0.25.0" ./bin/bazelisk-darwin-amd64 version