Skip to main content
The RBS DSL is a Python-like configuration language used to define build targets, dependencies, and project settings. It supports variables, functions, loops, conditionals, and string operations.

WORKSPACE.rbs

The workspace file configures project-wide settings, toolchains, and external dependencies.

config_setting

Define workspace-level configuration values:
config_setting(key = "project_name", value = "my-app")
config_setting(key = "version", value = "1.0.0")
config_setting(key = "debug_mode", value = True)

load

Import rules and functions from RBS SDKs or other .rbs files:
# Load from RBS built-in SDKs
load("@rbs//python/toolchain.rbs", "python_toolchain")
load("@rbs//python/rules.rbs", "py_binary", "py_test")
load("@rbs//java/toolchain.rbs", "java_toolchain")

# Load from local files
load("//tools/rules.rbs", "my_custom_rule")
load("//:infra.rbs", "web_server")

print

Output messages during workspace evaluation:
print("Configuring workspace for", platform.name)

BUILD.rbs

Build files define targets within a package.

native.task

The most basic target — runs a shell command:
native.task(
    name = "hello",                                   # Target name (required)
    command = ["echo", "Hello!"],                      # Command to execute (required)
    description = "Say hello",                         # Human-readable description
    deps = [":other_target"],                          # Dependencies
    outputs = [output_path.out + "/result.txt"],       # Output files
    data = [":config_files"],                          # Runtime data files
    target_compatible_with = ["@platforms//os:linux"],  # Platform constraints
)

native.filegroup

Group files together for use as dependencies:
native.filegroup(
    name = "source_files",
    srcs = glob(["src/**/*.py"], exclude = ["**/*_test.py"]),
)

native.filegroup(
    name = "test_data",
    srcs = glob(["testdata/**/*"]),
    testonly = True,
)

native.genrule

General-purpose rule for custom build steps with file operations:
native.genrule(
    name = "generate_config",
    srcs = ["template.conf"],
    outs = ["config.conf"],
    cmd = "sed 's/VERSION/1.0/' $< > $@",
)
With an action function for advanced control:
def generate_action(ctx):
    content = ctx.file.read(ctx.first_src)
    output = content.replace("{{VERSION}}", "1.0.0")
    ctx.file.write(ctx.first_out, output)

native.genrule(
    name = "generate_config",
    srcs = ["template.conf"],
    outs = ["config.conf"],
    action_fn = generate_action,
)

Built-in variables

VariableTypeDescription
platform.namestringCurrent platform (e.g., darwin-arm64)
platform.osstringOperating system (e.g., darwin, linux)
platform.archstringArchitecture (e.g., arm64, amd64)
output_path.binstringBinary output directory
output_path.outstringGeneral output directory
output_path.testlogsstringTest logs directory

Built-in functions

glob(patterns, exclude=[])

Match files using glob patterns:
# All Python files
all_py = glob(["**/*.py"])

# All source files, excluding tests
srcs = glob(["src/**/*.py"], exclude = ["**/*_test.py"])

# Multiple patterns
assets = glob(["**/*.css", "**/*.js", "**/*.html"])

select(conditions)

Choose values based on platform or configuration:
TOOL_URL = select({
    "//platforms:darwin_arm64": "https://example.com/tool-darwin-arm64",
    "//platforms:linux_amd64": "https://example.com/tool-linux-amd64",
})

Language features

Variables and expressions

version = "1.0.0"
name = "my-app"
full_name = name + "-" + version    # String concatenation
port = 8080                          # Integer
debug = True                         # Boolean
items = ["a", "b", "c"]             # List
config = {"key": "value"}           # Dictionary

Conditionals

if platform.os == "darwin":
    config_setting(key = "signing", value = "enabled")
elif platform.os == "linux":
    config_setting(key = "package_format", value = "deb")

Loops

services = ["api", "worker", "scheduler"]

for svc in services:
    native.task(
        name = svc + "_build",
        command = ["echo", "Building " + svc],
    )

List comprehensions

targets = [
    "//services/" + svc + ":build"
    for svc in ["api", "worker", "scheduler"]
]

Functions

def create_service(name, port):
    native.task(
        name = name + "_start",
        command = ["echo", "Starting " + name + " on port " + str(port)],
    )

create_service("api", 8080)
create_service("worker", 9090)

External dependencies

Declaring dependencies in WORKSPACE.rbs

load("@rbs//python/dependencies.rbs", "py_repository")
load("@rbs//nodejs/dependencies.rbs", "nodejs_repository")
load("@rbs//java/dependencies.rbs", "java_repository")

py_repository(name = "requests_lib", package = "requests", version = "2.31.0")
nodejs_repository(name = "express_repo", package = "express", version = "4.18.2")
java_repository(name = "spring_web", package = "org.springframework.boot:spring-boot-starter-web", version = "3.2.2")

Using dependencies in BUILD.rbs

py_binary(
    name = "app",
    srcs = ["main.py"],
    deps = ["@external://requests:2.31.0"],
)

Toolchains

Register language toolchains in WORKSPACE.rbs:
load("@rbs//python/toolchain.rbs", "python_toolchain")
load("@rbs//nodejs/toolchain.rbs", "nodejs_toolchain")
load("@rbs//java/toolchain.rbs", "java_toolchain")

python_toolchain(name = "python", version = "3.11.0")
nodejs_toolchain(name = "nodejs", version = "20.11.0")
java_toolchain(name = "java", version = "17.0.11")
RBS automatically downloads and manages these toolchains. No system installation required.

Next steps