Skip to main content
function Bazel.build
def Bazel.build(
*targets: str,
build_events: bool | list[bazel.build.BuildEventIter | bazel.build.BuildEventSink] = ,
workspace_events: bool = False,
execution_log: bool | list[bazel.execlog.ExecLogSink] = ,
flags: list[str | (str, str)] = [],
stdout: None | std.io.Writable = ,
stderr: None | std.io.Writable = ,
stdio: None | std.io.Stdio = None,
current_dir: None | str = None,
announce_version: bool = False,
announce_command: bool = False
) -> bazel.build.Build
Build one or more Bazel targets. Returns a Build object. The call does not block — use .wait() to wait for the invocation to finish and retrieve its exit status. Parameters
  • execution_log: Enable Bazel execution log collection. Pass True to enable the in-memory decoded iterator (accessible via build.execution_logs()), or pass a list of sinks such as [execution_log.compact_file(path = "out.binpb.zst")] to write the log to one or more files. Sinks and the iterator can be combined: passing a list of sinks still allows calling build.execution_logs() to iterate entries in-process. “//my/pkg:target”, flags = [ “—config=release”, (“—notmp_sandbox”, ”>=8”), (“—some_legacy_flag”, “<7”), ], stdout = None, # discard child stdout stderr = ctx.std.fs.create(“bazel.err”), # redirect stderr to a file
function Bazel.cancel_invocation
def Bazel.cancel_invocation(
*,
force_kill_after_ms: int = 5000
) -> bazel.build.Cancellation
Cancel whatever invocation is currently running on the Bazel server. Finds the bazel client process holding the server lock and sends it SIGINT (graceful cancellation, like Ctrl+C). The client then forwards a CancelRequest RPC to the server. Returns a Cancellation with status and control methods. Parameters
  • force_kill_after_ms: - If the build is still running after this many milliseconds, wait() will automatically escalate by sending the 2nd and 3rd SIGINT to the Bazel client (the 3rd triggers Bazel’s built-in server kill, equivalent to Ctrl+C three times). If the client still doesn’t exit, falls back to SIGKILL on both client and server. Defaults to 5000ms. Set to 0 to disable auto-escalation and manage cancellation manually via wait(timeout_ms=...) and force().
function Bazel.health_check
def Bazel.health_check() -> bazel.HealthCheckResult
Probe the Bazel server to determine whether it is responsive. Runs bazel --noblock_for_lock info server_pid. If the server is unresponsive, attempts recovery by killing the server process and re-checking. Returns a HealthCheckResult with .success, .healthy, .message, and .exit_code attributes. Examples
function Bazel.info
def Bazel.info() -> dict[str, str]
Run bazel info and return all key/value pairs as a dict. Blocks until the command completes. Raises an error if Bazel exits with a non-zero code. function Bazel.parse_rc
def Bazel.parse_rc(
*,
root: None | str = None,
startup_flags: list = [],
flags: list = [],
skip_config_if_missing: list[str] = []
) -> bazel.BazelRC
Parse .bazelrc files rooted at root and return a BazelRC object. Parameters
  • root: - Bazel workspace root directory. Defaults to env.bazel_root_dir — the deepest MODULE.bazel / WORKSPACE ancestor of cwd. Pass an explicit root only to read a bazelrc outside the surrounding workspace; passing the Aspect root here in a sub-workspace layout would read the outer .bazelrc and leak the parent project’s flags.
  • startup_flags: - Startup flags (e.g. ["--bazelrc=/path/to/extra.bazelrc"]).
  • flags: - Command-line flags to inject as synthetic always options (e.g. ["--config=opt"]). rc = ctx.bazel.parse_rc(flags = [“—config=opt”]) build = ctx.bazel.build(”//…”, flags = rc.expand(command = “build”)) build.wait()
function Bazel.query
def Bazel.query() -> bazel.query.Query
The query system provides a programmatic interface for analyzing build dependencies and target relationships. Queries are constructed using a chain API and are lazily evaluated only when .eval() is explicitly called. The entry point is ctx.bazel.query(), which returns a query for creating initial query expressions. Most operations operate on query objects, which represent sets of targets that can be filtered, transformed, and combined. Example
function Bazel.recover_poisoned_sandbox
def Bazel.recover_poisoned_sandbox() -> bazel.SandboxRecoveryResult
Detect and best-effort repair runner-poisoning sandbox state described by bazelbuild/bazel#23880. Inspects <output_base>/sandbox/ for entries outside Bazel’s SANDBOX_BASE_PERSISTENT_DIRS whitelist ({.DS_Store, sandbox_stash, sandbox_stash_temp, _moved_trash_dir}). Anything else present after a bazel command exited is the poisoning signature: Bazel’s own afterCommand cleanup left state behind because its spawn-runner registry didn’t include the strategy that owned that subtree (see LinuxSandboxedStrategy. create IOException path; fixed upstream by abe8d6090 in 9.0+). When poisoning is detected, every offending entry is rm -rf’d. The result distinguishes three cases:
  • "clean": nothing to remove. Either the sandbox dir didn’t exist or contained only whitelisted entries.
  • "repaired": at least one non-whitelisted entry was found and all of them were successfully removed. The runner is safe to keep serving jobs.
  • "still_poisoned": at least one entry survived the removal attempt (e.g. EPERM on the underlying filesystem). The runner will keep crashing every bazel command on the same output base — the caller should mark it unhealthy.
Reads --output_base= from ctx.bazel.startup_flags. When --output_base is not present (e.g. local dev), returns "clean" — there’s no way to know which outputabase to inspect, and the failure mode is a Workflows-runner-only concern in practice. Safe to call only AFTER the most recent bazel client invocation has fully exited — a live bazel build/test against the same outputabase would race the removal. Examples
function Bazel.test
def Bazel.test(
*targets: str,
build_events: bool | list[bazel.build.BuildEventIter | bazel.build.BuildEventSink] = ,
workspace_events: bool = False,
execution_log: bool | list[bazel.execlog.ExecLogSink] = ,
flags: list[str | (str, str)] = [],
stdout: None | std.io.Writable = ,
stderr: None | std.io.Writable = ,
stdio: None | std.io.Stdio = None,
current_dir: None | str = None,
announce_version: bool = False,
announce_command: bool = False
) -> bazel.build.Build
Build and test one or more Bazel targets. Returns a Build object. The call does not block — use .wait() to wait for the invocation to finish and retrieve its exit status. Parameters
  • execution_log: Enable Bazel execution log collection. Pass True to enable the in-memory decoded iterator (accessible via build.execution_logs()), or pass a list of sinks such as [execution_log.compact_file(path = "out.binpb.zst")] to write the log to one or more files. Sinks and the iterator can be combined: passing a list of sinks still allows calling build.execution_logs() to iterate entries in-process. “//my/pkg:test”, flags = [ “—test_output=errors”, (“—notmp_sandbox”, ”>=8”), (“—some_legacy_flag”, “<7”), ],
property Bazel.startup_flags
Bazel.startup_flags: typing.Any
Mutable list of startup flags prepended to every Bazel invocation on this context.