ci(buildbot): use Bazelisk to dynamically determine Bazel versions (#3799)

diff --git a/kythe/release/appengine/buildbot/Dockerfile b/kythe/release/appengine/buildbot/Dockerfile
index ccec95d..ae8f709 100644
--- a/kythe/release/appengine/buildbot/Dockerfile
+++ b/kythe/release/appengine/buildbot/Dockerfile
@@ -52,12 +52,9 @@
     rm -rf go*.tar.gz
 ENV PATH=$PATH:/usr/local/go/bin
 
-# Install Bazel minimum supported version
-RUN curl -L -o /usr/bin/bazel-0.25.1 https://github.com/bazelbuild/bazel/releases/download/0.25.1/bazel-0.25.1-linux-x86_64 && chmod +x /usr/bin/bazel-0.25.1
+# Install Bazelisk and wrapper script
 ADD bazel /usr/bin/bazel
-
-# Install latest supported Bazel version (when different from minimum)
-# RUN curl -L -o /usr/bin/bazel-0.25.1 https://github.com/bazelbuild/bazel/releases/download/0.25.1/bazel-0.25.1-linux-x86_64 && chmod +x /usr/bin/bazel-0.25.1
+RUN curl -L -o /usr/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/v0.0.7/bazelisk-linux-amd64 && chmod +x /usr/bin/bazelisk
 
 # Buildbot configuration
 ADD bazelrc /root/.bazelrc
diff --git a/kythe/release/appengine/buildbot/bazel b/kythe/release/appengine/buildbot/bazel
index 43151a1..cb7b323 100755
--- a/kythe/release/appengine/buildbot/bazel
+++ b/kythe/release/appengine/buildbot/bazel
@@ -14,46 +14,23 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-# Script to control which Bazel version is used through env variables.
+# Wrapper script to run Bazel via Bazelisk.
 #
-# By default, this script just runs /usr/bin/bazel with "$@".  The following
-# environmental variables allow the caller to switch which Bazel binary is
-# executed:
-#
-# BAZEL:         override all other variables; run this binary
-# BAZEL_VERSION: Bazel version to execute (e.g. 0.15.2)
-# BAZEL_BIN:     directory of bazel binaries (e.g. $BAZEL_BIN/bazel-0.15.2)
-# DEFAULT_BAZEL: binary to use when BAZEL and BAZEL_VERSION are not set
-#
-# Examples:
-#   ./bazel                                              # executes /usr/bin/bazel
-#   BAZEL_VERSION=0.15.2 ./bazel                         # executes /usr/bin/bazel-0.15.2
-#   BAZEL_VERSION=0.15.2 BAZEL_BIN=/opt/bazel ./bazel    # executes /opt/bazel/bazel-0.15.2
-#   BAZEL=/bin/true ./bazel                              # executes /bin/true
-#   DEFAULT_BAZEL=/bin/true ./bazel                      # executes /bin/true
-#   DEFAULT_BAZEL=/bin/true BAZEL_VERSION=0.15.2 ./bazel # executes /usr/bin/bazel-0.15.2
+# Transforms USE_BAZEL_VERSION=min to USE_BAZEL_VERSION=$(<.bazelminversion).
+# The .bazelminversion file may be in the current working directory or any
+# parent directory.  The first readable file found will be used; if none are
+# found, the script will exit unsuccessfully.
 
-SCRIPT="$(realpath "$0")"
-DEFAULT_BAZEL="${DEFAULT_BAZEL=/usr/bin/bazel}"
-BAZEL_BIN="${BAZEL_BIN:-/usr/bin}"
-
-if [[ -n "$BAZEL" ]]; then
-  exec "$BAZEL" "$@"
-fi
-
-if [[ -z "$BAZEL_VERSION" ]]; then
-  if [[ -n "$DEFAULT_BAZEL" && -x "$DEFAULT_BAZEL" ]]; then
-    DEFAULT_BAZEL="$(realpath "$DEFAULT_BAZEL")"
-    if [[ "$DEFAULT_BAZEL" != "$SCRIPT" ]]; then
-      # Use default bazel version
-      exec "$DEFAULT_BAZEL" "$@"
+if [[ "$USE_BAZEL_VERSION" == "min" ]]; then
+  dir="$PWD"
+  while [[ ! -r "$dir/.bazelminversion" ]]; do
+    if [[ "$dir" == "/" ]]; then
+      echo "ERROR: unable to find .bazelminversion file in cwd or above" >&2
+      exit 1
     fi
-  fi
-
-  # Select latest version available
-  VERSIONS=($(ls "$BAZEL_BIN"/bazel-* | xargs -L1 basename | sort -t. -h -k1,1 -k2,2 -k3,3))
-  LATEST="${VERSIONS[*]: -1}"
-  BAZEL_VERSION="${LATEST#bazel-}"
+    dir="$(dirname "$dir")"
+  done
+  USE_BAZEL_VERSION="$(<"$dir/.bazelminversion")"
 fi
 
-exec "$BAZEL_BIN/bazel-$BAZEL_VERSION" "$@"
+exec bazelisk "$@"
diff --git a/kythe/release/appengine/buildbot/master/master.cfg b/kythe/release/appengine/buildbot/master/master.cfg
index 1269608..8b95490 100644
--- a/kythe/release/appengine/buildbot/master/master.cfg
+++ b/kythe/release/appengine/buildbot/master/master.cfg
@@ -106,14 +106,11 @@
 ####### SCHEDULERS
 
 goVersion = '1.12'
-bazelMinVersion = '0.25.1'
-bazelMaxVersion = '0.25.1'
 
 bazelBuilders = [
-    'bazel-'+bazelMaxVersion,
+    'bazel-minversion',
+    'bazel',
 ]
-if bazelMinVersion != bazelMaxVersion:
-    bazelBuilders += ['bazel-'+bazelMinVersion]
 
 goBuilders = [
     'go-'+goVersion+'-gopath',
@@ -181,7 +178,10 @@
 bazelKytheSteps = util.BuildFactory()
 bazelKytheSteps.addStep(steps.GitHub(repourl=util.Property('repository', 'git://github.com/kythe/kythe.git'),
                                      mode='full', method='copy'))
-bazelBinEnv = {'DEFAULT_BAZEL': '/bin/false', 'BAZEL_VERSION': util.Property('bazel_version', bazelMaxVersion)}
+bazelBinEnv = {'USE_BAZEL_VERSION': util.Property('bazel_version')}
+bazelKytheSteps.addStep(steps.ShellCommand(
+    command=["bazel", "version"],
+    env=bazelBinEnv))
 bazelKytheSteps.addStep(steps.ShellCommand(
     command=["bazel", "test",
              util.Property('bazel_flags', default=[]),
@@ -213,18 +213,17 @@
 build_lock = util.WorkerLock("worker_builds", maxCount=1, maxCountForWorker={'local-worker': 3})
 
 c['builders'] = []
-if bazelMinVersion != bazelMaxVersion:
-  c['builders'].append(
-      util.BuilderConfig(
-          name="bazel-"+bazelMinVersion,
-          workernames=["local-worker"],
-          properties={'bazel_version': bazelMinVersion,
-                      'bazel_flags': ['--config=remote']},
-          locks=[build_lock.access('counting')],
-          factory=bazelKytheSteps))
 c['builders'].append(
     util.BuilderConfig(
-        name="bazel-"+bazelMaxVersion,
+        name="bazel-minversion",
+        workernames=["local-worker"],
+        properties={'bazel_version': 'min',
+                    'bazel_flags': ['--config=remote']},
+        locks=[build_lock.access('counting')],
+        factory=bazelKytheSteps))
+c['builders'].append(
+    util.BuilderConfig(
+        name="bazel",
         workernames=["local-worker"],
         properties={'bazel_flags': ['--config=remote']},
         locks=[build_lock.access('counting')],
diff --git a/tools/arc/linter.sh b/tools/arc/linter.sh
index ced83d7..127cd44 100755
--- a/tools/arc/linter.sh
+++ b/tools/arc/linter.sh
@@ -29,7 +29,7 @@
 readonly dir="$(dirname "$1")"
 
 case $file in
-  AUTHORS|CONTRIBUTORS|WORKSPACE|third_party/*|tools/*|*.md|*BUILD|*/testdata/*|*.yaml|*.json|*.html|*.pb.go|.arclint|.gitignore|*/.gitignore|.arcconfig|*/__phutil_*|*.bzl|.kythe|kythe/web/site/*|go.mod|go.sum|*bazelrc|*.yml)
+  AUTHORS|CONTRIBUTORS|WORKSPACE|third_party/*|tools/*|*.md|*BUILD|*/testdata/*|*.yaml|*.json|*.html|*.pb.go|.arclint|.gitignore|*/.gitignore|.arcconfig|*/__phutil_*|*.bzl|.kythe|kythe/web/site/*|go.mod|go.sum|*bazelrc|*.yml|.bazel*version)
     ;; # skip copyright checks
   *)
     if ! grep -q 'Copyright 201[4-9] The Kythe Authors. All rights reserved.' "$file"; then