[bazel] SkCMS: Add Bazel tasks (local and RBE).

Bug: skia:12400
Change-Id: I1a5fe87a2cee7b5a79140e16faa8becbd743bdb5
Reviewed-on: https://skia-review.googlesource.com/c/skcms/+/450816
Commit-Queue: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Eric Boren <borenet@google.com>
diff --git a/infra/bots/bazel.py b/infra/bots/bazel.py
new file mode 100644
index 0000000..420220c
--- /dev/null
+++ b/infra/bots/bazel.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import os
+import subprocess
+import sys
+import tempfile
+
+
+def call(cmd):
+  print("Executing: " + " ".join(cmd))
+  subprocess.check_call(cmd)
+
+
+def main():
+  build_or_test = sys.argv[1]
+  assert build_or_test in ["build", "test"]
+
+  local_or_rbe = sys.argv[2]
+  assert local_or_rbe in ["local", "rbe"]
+
+  print("Hello from {platform} in {cwd}!".format(platform=sys.platform,
+                                                 cwd=os.getcwd()))
+
+  # Create a temporary directory for the Bazel cache.
+  #
+  # We cannot use the default Bazel cache location ($HOME/.cache/bazel) because:
+  #
+  #  - The cache can be large (>10G).
+  #  - Swarming bots have limited storage space on the root partition (15G).
+  #  - Because the above, the Bazel build fails with a "no space left on
+  #    device" error.
+  #  - The Bazel cache under $HOME/.cache/bazel lingers after the tryjob
+  #    completes, causing the Swarming bot to be quarantined due to low disk
+  #    space.
+  #  - Generally, it's considered poor hygiene to leave a bot in a different
+  #    state.
+  #
+  # The temporary directory created by the below function call lives under
+  # /mnt/pd0, which has significantly more storage space, and will be wiped
+  # after the tryjob completes.
+  #
+  # Reference: https://docs.bazel.build/versions/master/output_directories.html#current-layout.
+  with tempfile.TemporaryDirectory(prefix="bazel-cache-",
+                                   dir=os.environ["TMPDIR"]) as cache_dir:
+    def bazel(args):
+      cmd = ["bazel", "--output_user_root=" + cache_dir] + args
+      call(cmd)
+
+    # Print the Bazel version.
+    bazel(["version"])
+
+    # Run the requested Bazel command.
+    os.chdir("skcms")
+    cmd = [build_or_test, "//..."]
+    if local_or_rbe == "rbe":
+      cmd += ["--config=linux-rbe", "--google_default_credentials"]
+    bazel(cmd)
+
+
+if __name__ == "__main__":
+  main()
diff --git a/infra/bots/tasks.json b/infra/bots/tasks.json
index a936cf3..4165f68 100644
--- a/infra/bots/tasks.json
+++ b/infra/bots/tasks.json
@@ -11,7 +11,13 @@
   },
   "jobs": {
     "skcms": {
-      "tasks": ["skcms-Linux", "skcms-Mac", "skcms-Win"]
+      "tasks": [
+        "skcms-Linux",
+        "skcms-Mac",
+        "skcms-Win",
+        "skcms-Linux-Bazel-Build-RBE",
+        "skcms-Linux-Bazel-Test-RBE"
+      ]
     },
     "skcms-Linux": {
       "tasks": ["skcms-Linux"]
@@ -21,6 +27,12 @@
     },
     "skcms-Win": {
       "tasks": ["skcms-Win"]
+    },
+    "skcms-Linux-Bazel-Build-RBE": {
+      "tasks": ["skcms-Linux-Bazel-Build-RBE"]
+    },
+    "skcms-Linux-Bazel-Test-RBE": {
+      "tasks": ["skcms-Linux-Bazel-Test-RBE"]
     }
   },
   "tasks": {
@@ -140,6 +152,100 @@
       "dimensions": ["os:Windows-Server-17763", "gpu:none", "pool:Skia"],
       "max_attempts": 1,
       "service_account": "skia-external-compile-tasks@skia-swarming-bots.iam.gserviceaccount.com"
+    },
+    "skcms-Linux-Bazel-Build-RBE": {
+      "caches": [
+        {
+          "name": "vpython",
+          "path": "cache/vpython"
+        }
+      ],
+      "casSpec": "whole-repo",
+      "cipd_packages": [
+        {
+          "name": "infra/3pp/tools/cpython3/linux-amd64",
+          "path": "cipd_bin_packages/cpython3",
+          "version": "version:2@3.8.10.chromium.19"
+        },
+        {
+          "name": "skia/bots/bazel",
+          "path": "bazel",
+          "version": "version:3"
+        }
+      ],
+      "command": [
+        "cipd_bin_packages/cpython3/bin/python3",
+        "skcms/infra/bots/bazel.py",
+        "build",
+        "rbe"
+      ],
+      "dimensions": [
+        "pool:Skia",
+        "os:Debian-10.3",
+        "gpu:none",
+        "cpu:x86-64-Haswell_GCE",
+        "machine_type:n1-highcpu-64",
+        "docker_installed:true"
+      ],
+      "env_prefixes": {
+        "PATH": [
+          "cipd_bin_packages/cpython3",
+          "cipd_bin_packages/cpython3/bin",
+          "bazel/bin"
+        ],
+        "VPYTHON_VIRTUALENV_ROOT": [
+          "cache/vpython"
+        ]
+      },
+      "max_attempts": 1,
+      "service_account": "skia-external-compile-tasks@skia-swarming-bots.iam.gserviceaccount.com"
+    },
+    "skcms-Linux-Bazel-Test-RBE": {
+      "caches": [
+        {
+          "name": "vpython",
+          "path": "cache/vpython"
+        }
+      ],
+      "casSpec": "whole-repo",
+      "cipd_packages": [
+        {
+          "name": "infra/3pp/tools/cpython3/linux-amd64",
+          "path": "cipd_bin_packages/cpython3",
+          "version": "version:2@3.8.10.chromium.19"
+        },
+        {
+          "name": "skia/bots/bazel",
+          "path": "bazel",
+          "version": "version:3"
+        }
+      ],
+      "command": [
+        "cipd_bin_packages/cpython3/bin/python3",
+        "skcms/infra/bots/bazel.py",
+        "test",
+        "rbe"
+      ],
+      "dimensions": [
+        "pool:Skia",
+        "os:Debian-10.3",
+        "gpu:none",
+        "cpu:x86-64-Haswell_GCE",
+        "machine_type:n1-highcpu-64",
+        "docker_installed:true"
+      ],
+      "env_prefixes": {
+        "PATH": [
+          "cipd_bin_packages/cpython3",
+          "cipd_bin_packages/cpython3/bin",
+          "bazel/bin"
+        ],
+        "VPYTHON_VIRTUALENV_ROOT": [
+          "cache/vpython"
+        ]
+      },
+      "max_attempts": 1,
+      "service_account": "skia-external-compile-tasks@skia-swarming-bots.iam.gserviceaccount.com"
     }
   }
 }