Skip to main content
aspect setup workspace-data prints this build’s commit, branch, pull request and CI metadata as Bazel workspace status: KEY value lines on stdout.
An aspect <task> already sends this metadata with every invocation it streams. A vanilla bazel call sends none, so it arrives in the Build Results UI with no commit, no branch and no pull request. This command supplies them. Bazel runs the command at the start of every invocation, so the values are always the current build’s, and the flag is identical for every job, which makes it safe in a shared ~/.bazelrc.

Set it up

On a CI runner, put it in the machine rc that aspect setup bazelrc already writes, or in ~/.bazelrc directly:
A bare command name resolves on PATH, so no wrapper script or absolute path is needed, and arguments are accepted. Locally it is worth the same line in your own ~/.bazelrc if you stream developer builds, though the attribution matters most where builds are anonymous: CI.

If you already have a workspace status script

Bazel takes one --workspace_status_command, so a repository that already has a script doesn’t replace it; it calls this from inside. The output is KEY value lines on stdout, so appending them is the whole integration:
tools/workspace_status.sh
Your .bazelrc keeps naming your script:
When you compose them:
  • Keep your keys and Aspect’s distinct. Aspect emits the keys listed below; if your script already sets one of those names, rename yours rather than relying on which line Bazel keeps.

What it emits

The keys are the ones aspect <task> already sends as --build_metadata, so the two routes reach the same fields. The UI merges both, with --build_metadata winning where they disagree. What is available depends on the CI host and the checkout, and empty values are dropped:
The keys are written unprefixed, so they land in volatile-status.txt rather than stable-status.txt. A STABLE_ key invalidates every stamped action whenever it changes, the wrong trade for data that changes every commit.

Where it prints nothing

In a bare directory with no git, no .aspect/ and no MODULE.bazel, the shape a sibling workspace often has, it prints nothing and exits 0. Task narrative goes to stderr, so stdout carries only the data and Bazel’s parse stays clean. It exits non-zero when aspect isn’t on PATH or the workspace’s .aspect/config.axl fails to evaluate. Where developers may not have the CLI installed, call it from your own status script and guard the call.
It costs roughly 350ms per invocation, on the critical path of every bazel call that uses it. That’s negligible on a CI build and noticeable in a script calling bazel in a loop. Almost all of it is CLI startup rather than the git call.

What it doesn’t do

Workspace status carries attribution, not wiring. A vanilla bazel still needs --remote_cache and --bes_backend from somewhere; that’s aspect setup bazelrc’s job.