function Bazel.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. PassTrueto enable the in-memory decoded iterator (accessible viabuild.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 callingbuild.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
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 viawait(timeout_ms=...)andforce().
function Bazel.health_check
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
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
Parse
.bazelrc files rooted at root and return a BazelRC object.
Parameters
-
root: - Bazel workspace root directory. Defaults toenv.bazel_root_dir— the deepestMODULE.bazel/WORKSPACEancestor ofcwd. Pass an explicitrootonly to read a bazelrc outside the surrounding workspace; passing the Aspect root here in a sub-workspace layout would read the outer.bazelrcand leak the parent project’s flags. -
startup_flags: - Startup flags (e.g.["--bazelrc=/path/to/extra.bazelrc"]). -
flags: - Command-line flags to inject as syntheticalwaysoptions (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
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
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.
--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
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. PassTrueto enable the in-memory decoded iterator (accessible viabuild.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 callingbuild.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
Mutable list of startup flags prepended to every Bazel invocation on this context.

