blob: 57e2c9a46bef54eba725ad9b26fc49ffdfd33840 [file] [log] [blame]
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@bazel_gazelle//:def.bzl", "gazelle")
load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")
load("@com_github_bazelbuild_buildtools//buildifier:def.bzl", "buildifier")
load("@io_bazel_rules_docker//container:container.bzl", "container_push")
load("@io_bazel_rules_docker//docker/util:run.bzl", "container_run_and_commit")
load("//:elements-sk-scss.bzl", "generate_tilde_prefixed_elements_sk_scss_files")
load("@io_bazel_rules_docker//docker/toolchain_container:toolchain_container.bzl", "language_tool_layer", "toolchain_container")
load("@exec_properties//:constants.bzl", "NETWORK_ON")
# Disable generation of go_proto_library targets. Let Gazelle use checked-in .pb.go files instead.
#
# We opt out of this feature for the following reasons:
#
# 1) Generated files are invisible to code editors and IDEs, which breaks features such as code
# completion, automated refactors, etc. This can be fixed with editor plugins (see
# https://github.com/bazelbuild/rules_go/issues/512), but none are available at this time.
#
# 2) Leveraging the preexisting, checked-in .pb.go is the fastest way to roll out Bazel as the build
# system for our repository, and is the recommended approach for already established projects, or
# for projects that also need to build with "go build". See
# https://github.com/bazelbuild/rules_go/blob/master/proto/core.rst#option-2-use-pre-generated-pbgo-files.
#
# In the future, we might decide to leverage Gazelle's generation of go_proto_library rules. To
# address point 1) above, a potential approach is to check in any files generated via
# go_proto_library targets. This works because if there's a source file checked in the repository,
# and a build target that generates a file of the same name, Bazel will ignore the checked in file
# and use the generated file instead. To keep the checked in and generated files in sync, a rule
# such as generated_file_test can be used, as mentioned here:
# https://github.com/bazelbuild/rules_go/issues/512#issuecomment-747844469.
#
# Documentation for this directive: https://github.com/bazelbuild/bazel-gazelle#directives.
#
# gazelle:proto disable
# This directive tells Gazelle to use a custom macro instead of rules_go's go_test rule for any
# Gazelle-generated Go test targets.
#
# The custom macro generates separate go_test targets for manual Go tests, which will be tagged as
# manual. The macro relies on the assumption that any manual test cases will be placed on Go source
# files ending in "_manual_test.go". This convention is enforced by unittest.ManualTest(). If the
# test target does not contain any manual test, the custom macro behaves exactly like rules_go's
# go_test rule.
#
# See the macro's docstring for details.
#
# Documentation for this directive: https://github.com/bazelbuild/bazel-gazelle#directives.
#
# gazelle:map_kind go_test go_test //bazel/go:go_test.bzl
# Exclude directories with Bazel outputs. The "_bazel_" prefix is defined in //.bazelrc.
#
# Without this, Gazelle can take several minutes to complete.
#
# gazelle:exclude _bazel_*
# gazelle:prefix go.skia.org/infra
gazelle(
name = "gazelle",
# We use a custom Gazelle binary that adds support for our front-end Bazel rules and macros.
gazelle = "//bazel/gazelle",
)
exports_files(
["tsconfig.json"],
visibility = ["//visibility:public"],
)
buildifier(
name = "buildifier",
exclude_patterns = [
"./node_modules/*",
"./**/node_modules/*",
],
lint_mode = "warn",
)
############################
# Custom platform for RBE. #
############################
platform(
name = "rbe_custom_platform",
# Enable networking. Without this, tests that require network access will fail. Examples include
# go_test targets that try to clone the Skia Git repo from https://skia.googlesource.com/skia,
# tests that hit GCS, etc.
#
# See https://github.com/bazelbuild/bazel-toolchains/tree/master/rules/exec_properties.
#
# Note that depending on network resources breaks test hermeticity.
exec_properties = NETWORK_ON,
# Extend the platform generated with "rbe_configs_gen".
#
# See //bazel/rbe/README.md for details.
parents = ["//bazel/rbe/config:platform"],
)
#############################################################################
# Utility tool to extract screenshots taken by Puppeteer tests under Bazel. #
#############################################################################
# Wrapper script so we can invoke the tool from the workspace root, instead of the directory where
# the tool's go_binary target is located.
genrule(
name = "extract_puppeteer_screenshots_wrapper_script",
srcs = ["//puppeteer-tests/bazel/extract_puppeteer_screenshots"],
outs = ["extract_puppeteer_screenshots.sh"],
cmd = " && ".join([
# The $@ variable holds the path to the genrule's only output file. The $$@ variable is the
# shell's $@ variable ($-escaped), which is used here to pipe through to the underlying Go
# program any command-line arguments passed to the wrapper shell script.
#
# See https://docs.bazel.build/versions/master/be/general.html#genrule.
"echo '#!/bin/bash' >> $@",
"echo '$(rootpath //puppeteer-tests/bazel/extract_puppeteer_screenshots) $$@' >> $@",
]),
)
# Usage: "bazel run //:extract_puppeteer_screenshots -- --output_dir=<output directory>".
sh_binary(
name = "extract_puppeteer_screenshots",
srcs = ["extract_puppeteer_screenshots.sh"],
data = ["//puppeteer-tests/bazel/extract_puppeteer_screenshots"],
)
############################################
# Custom Remote Build Execution toolchain. #
############################################
# Generates a custom toolchain container for Remote Build Execution and any extra dependencies
# needed for Skia Infrastructure build targets.
#
# This container can be pushed to GCR via the :push_rbe_container_skia_infra target defined below.
#
# To debug this image:
#
# # Build the container image.
# $ bazel build //:rbe_container_skia_infra
#
# # Load the container.
# $ docker load -i _bazel_bin/rbe_container_skia_infra_commit.tar
# Loaded image: _bazel_bin/default:rbe_container_skia_infra
#
# # Run the container.
# $ docker run -it bazel/default:rbe_container_skia_infra /bin/bash
#
# Notes:
#
# - These targets are tagged with "no-remote" because the container_run_and_commit rule calls
# the Docker binary, which requires the Docker daemon to be running. This fails on RBE with error
# "Cannot connect to the Docker daemon at [...]. Is the docker daemon running?". By tagging this
# target with "no-remote", we tell Bazel to build this target locally, even with --config=remote.
#
# - The output of this rule is a >3GB .tar with the container image, so this target can take
# several minutes to build. This is OK because we only need to rebuild this container very
# occasionally, and Bazel will cache the output artifact.
#
# Reference:
# https://cloud.google.com/remote-build-execution/docs/create-custom-toolchain#creating_a_custom_toolchain_container
# This target can be used to upload the custom RBE container toolchain to GCR.
#
# Invoke it via `bazel run` to do the actual upload. It will be available as
# gcr.io/skia-public/rbe-container-skia-infra.
#
# Note: this can take several minutes to finish because it will upload a >3GB .tar file to GCR.
container_push(
name = "push_rbe_container_skia_infra",
format = "Docker",
image = ":rbe_container_skia_infra_commit.tar", # Generated by :rbe_container_skia_infra.
registry = "gcr.io",
repository = "skia-public/rbe-container-skia-infra",
tag = "{STABLE_DOCKER_TAG}",
tags = [
"manual", # Exclude it from wildcard queries, e.g. "bazel build //...".
"no-remote", # We cannot build :rbe_container_skia_infra on RBE.
],
)
# We extend the base Debian image with some commands add extra source repos needed to install
# the packages we need.
container_run_and_commit(
name = "rbe_with_setup",
commands = [
# Install the add-apt-repository command, and other packages needed to fetch repositories.
"echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/backports.list",
"apt-get update",
"apt-get install -y software-properties-common apt-transport-https ca-certificates ca-certificates-java gnupg curl",
"update-ca-certificates",
# Add repo/keys to install Chrome (needed for Puppeteer)
"curl -fsSL https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -",
"add-apt-repository 'deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main'",
# Add the Google Cloud SDK repository as per the instructions here:
# https://cloud.google.com/sdk/docs/install#deb.
"echo 'deb [signed-by=/usr/share/keyrings/cloud.google.gpg] " +
" https://packages.cloud.google.com/apt cloud-sdk main'" +
" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list",
"curl https://packages.cloud.google.com/apt/doc/apt-key.gpg" +
" | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -",
"apt-get update",
],
image = "@google_debian10//image", # Defined in WORKSPACE
tags = [
"manual", # Exclude it from wildcard queries, e.g. "bazel build //...".
"no-remote",
],
)
# After installing all of our toolchains (see :rbe_with_toolchains), we have a few more commands
# to run to finish setting up CIPD and other environment settings.
container_run_and_commit(
name = "rbe_container_skia_infra",
commands = [
# Bazel looks for clang and clang++, not the versioned binaries. Symlinks make that happen.
"ln -s /usr/bin/clang-11 /usr/bin/clang",
"ln -s /usr/bin/clang++-11 /usr/bin/clang++",
# Make python3 available via the python symlink
"ln -s /usr/bin/python3 /usr/bin/python",
# Install depot_tools, necessary to pull binaries via CIPD.
"git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /depot_tools",
# Remove the Git distribution included in the base image. We'll install our own from CIPD.
# The Git CLI is invoked from some tests.
"apt-get remove git -y",
# Initialize the CIPD root directory.
"mkdir /cipd",
"/depot_tools/cipd init /cipd -force",
# Install CIPD packages needed by various tests. These should be kept in sync with
# //cipd.ensure.
"/depot_tools/cipd install infra/3pp/tools/git/linux-amd64 version:2.29.2.chromium.6 " +
" -root /cipd",
"/depot_tools/cipd install infra/tools/luci/isolate/linux-amd64 " +
" git_revision:14be8b751c0fb567535f520f8a7bc60c3f40b378 -root /cipd",
"/depot_tools/cipd install infra/tools/luci/isolated/linux-amd64 " +
" git_revision:14be8b751c0fb567535f520f8a7bc60c3f40b378 -root /cipd",
# Include the CIPD-installed binaries (including git) in the PATH. Note that this does
# not persist after the container is created. Said binaries are included in the PATH
# during testing via a --test_env flag defined in //.bazelrc.
"export PATH=$PATH:/cipd:/cipd/bin",
# Create a default Git user. This is necessary for some Git tests to pass.
"mkdir /cipd/etc", # The below commands fail unless this directory exists.
"git config --system user.name 'Bazel RBE Test User'",
"git config --system user.email 'bazel-rbe-test-user@example.com'",
],
# by default, the :rbe_with_toolchains rule refers to the -layer.tar, which is not a valid
# docker image. By specifying .tar, we use the image itself that was output from the rule.
# https://github.com/bazelbuild/rules_docker/issues/1281#issuecomment-555099667
image = ":rbe_with_toolchains.tar",
tags = [
"manual",
"no-remote",
],
)
# As documented in https://github.com/bazelbuild/rules_docker/tree/1bb136eb4661624eb8ac1e607cdf74369987b46d/docker/toolchain_container#toolchain_container
# the toolchain_container is a way to join together multiple language_tool_layers. This is
# effectively like joining together multiple docker layers into one docker image. We chose to
# structure the image with multiple smaller layers to make it more organized/readable and to make
# Bazel caching better - If we make a change to the commands in :rbe_container_skia_infra, we don't
# have to wait for all the prerequisite packages to be re-installed.
# The implementation appears to pool all the packages, environment variables, files, etc from
# language_layers and then installs those on the base docker image.
toolchain_container(
name = "rbe_with_toolchains",
base = ":rbe_with_setup",
# The order of the layers here does matter, so we put them in alphabetical order.
language_layers = [
":rbe_with_clang", # clang is needed to be installed for the Bazel CC toolchain
":rbe_with_cockroachdb",
":rbe_with_golang",
":rbe_with_installed_packages",
":rbe_with_jdk", # jdk is needed to be installed for the Bazel Java toolchain
],
tags = [
"manual",
"no-remote",
],
)
# The pkg_tar command (https://github.com/bazelbuild/rules_pkg/blob/8d542763a3959db79175404758f46c7f3f385fa5/pkg/docs/reference.md#pkg_tar)
# takes a set of file (e.g. the contents of the Golang SDK folder) and puts them in a tar archive
# with a given structure (e.g. /usr/local/go). This structure corresponds to where we want to
# install/extract those files in the final RBE image.
pkg_tar(
name = "go_tar",
srcs = ["@go_sdk_external//:extracted_files"], # Defined in WORKSPACE
package_dir = "/usr/local/go/",
# The need for a ../ prefix was determined by looking at //_bazel_bin/go_tar.args
# and experimentation.
strip_prefix = "../go_sdk_external/go/",
tags = [
"manual",
"no-remote",
],
)
# This language_tool_layer (https://github.com/bazelbuild/rules_docker/tree/1bb136eb4661624eb8ac1e607cdf74369987b46d/docker/toolchain_container#language_tool_layer)
# despite its name, is not related to Bazel Toolchains (https://docs.bazel.build/versions/main/toolchains.html)
# It is just a way to organize the settings needed for a specific dependency, i.e. just the things
# we need to make golang work. It uses the packaged golang files from go_tar.
language_tool_layer(
name = "rbe_with_golang",
base = ":rbe_with_setup",
env = {
"GOPATH": "/opt/go",
"PATH": "$$PATH:/usr/local/go/bin",
},
tags = [
"manual", # Exclude it from wildcard queries, e.g. "bazel build //...".
"no-remote",
],
tars = [":go_tar"],
)
# This sets up the cockroachdb executable to be in /usr/local/bin
pkg_tar(
name = "cockroachdb_tar",
srcs = ["@cockroachdb_external//:extracted_exe"], # Defined in WORKSPACE
package_dir = "/usr/local/bin/",
# The need for a ../ prefix was determined by looking at //_bazel_bin/cockroachdb_tar.args
# and experimentation.
strip_prefix = "../cockroachdb_external/cockroach-v21.1.9.linux-amd64/",
tags = [
"manual",
"no-remote",
],
)
language_tool_layer(
name = "rbe_with_cockroachdb",
base = ":rbe_with_setup",
tags = [
"manual", # Exclude it from wildcard queries, e.g. "bazel build //...".
"no-remote",
],
tars = [":cockroachdb_tar"],
)
# This installs clang-11 (available via buster-backports) and sets the CC environment variable.
# Both of these are required to make the Bazel CC toolchain.
language_tool_layer(
name = "rbe_with_clang",
base = ":rbe_with_setup",
env = {
"CC": "/usr/bin/clang-11",
},
packages = ["clang-11"],
tags = [
"manual", # Exclude it from wildcard queries, e.g. "bazel build //...".
"no-remote",
],
)
# This installs the openjdk and sets the JAVA_HOME environment variable.
# Both of these are required to make the Bazel Java toolchain, which is required for some
# Bazel tasks.
language_tool_layer(
name = "rbe_with_jdk",
base = ":rbe_with_setup",
env = {
"JAVA_HOME": "/usr/lib/jvm/java-11-openjdk-amd64/",
},
packages = ["openjdk-11-jdk-headless"],
tags = [
"manual", # Exclude it from wildcard queries, e.g. "bazel build //...".
"no-remote",
],
)
# This installs all the rest of the debian packages we need to run Skia infra tests and other
# RBE tasks.
language_tool_layer(
name = "rbe_with_installed_packages",
base = ":rbe_with_setup",
packages = [
"binutils",
"git", # temporarily needed to install depot_tools
# Install Chrome and fonts to support major charsets.
#
# This is necessary for the karma_test rule to work, which runs web tests on a headless
# Chrome, and also for the bundled version of Chromium that Puppeteer installs to
# render fonts properly.
#
# Adapted from:
# https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md#running-puppeteer-in-docker
"google-chrome-stable",
"fonts-ipafont-gothic",
"fonts-wqy-zenhei",
"fonts-thai-tlwg",
"fonts-kacst",
"fonts-freefont-ttf",
# Prevent "error while loading shared libraries: libXss.so.1" in Puppeteer tests.
# See https://github.com/puppeteer/puppeteer/issues/6192.
"libxss1",
# Install the Google Cloud SDK and emulators.
"google-cloud-sdk",
"google-cloud-sdk-bigtable-emulator",
"google-cloud-sdk-datastore-emulator",
"google-cloud-sdk-firestore-emulator",
"google-cloud-sdk-pubsub-emulator",
# Applications needed to access test devices in the skia-switchboard cluster.
"adb",
"netcat",
"kubectl",
# Python3 is necessary for some tests/scripts
"python3",
# zip is necessary for the undeclared outputs of tests running on RBE to show up under
# //_bazel_testlogs/path/to/test/test.outputs/outputs.zip. This is the mechanism we use to
# extract screenshots taken by Puppeteer tests. See b/147694106.
"zip",
],
tags = [
"manual", # Exclude it from wildcard queries, e.g. "bazel build //...".
"no-remote",
],
)
# Generate a copy of the elements-sk SCSS stylesheets under //_bazel_bin/~elements-sk for
# compatibility with Webpack-style tilde-prefixed SCSS imports. See the macro docstring for details.
generate_tilde_prefixed_elements_sk_scss_files(
name = "~elements-sk",
)
go_library(
name = "infra_lib",
srcs = ["run_unittests.go"],
importpath = "go.skia.org/infra",
visibility = ["//visibility:private"],
deps = [
"//go/common",
"//go/git",
"//go/skerr",
"//go/sklog",
"//go/testutils/unittest",
"//go/timer",
"//go/util",
],
)
go_binary(
name = "infra",
embed = [":infra_lib"],
visibility = ["//visibility:public"],
)