A Buildkite plugin that prepares an
Aspect Workflows runner so that raw
bazel <verb> calls — not just aspect <task> — route through the runner's
caching infrastructure.
This is the Buildkite counterpart of the
aspect-build/setup-aspect
GitHub Action, ported down to just the work that an Aspect Workflows runner
needs.
On an Aspect Workflows runner, aspect <task> already wires itself into the
runner's remote cache, repository cache, and local NVMe disk cache on its own. But
many pipelines mix aspect build with a separate bare bazel build step, and
without this plugin those bare bazel invocations would miss all of that.
The plugin runs in the pre-command hook — after the repository checkout
(so the rc generator can read the workspace's .bazelversion) and before the
step's command (so the rc is in place before any bazel call). It does three
things:
- Logs the runner's metadata (version, cloud, region, instance, …) for traceability.
- Waits for the runner's cache warming to complete.
aspect <task>performs this wait itself; a vanillabazelcall would otherwise race the still-running bootstrap warming — competing for CPU/disk and missing the warmed caches. - Generates a Bazel rc so vanilla
bazelpicks up the Workflows-tuned configuration. The preferred path isaspect ci bazelrc, which writes~/.bazelrc. On older runners that still shiprosetta, it falls back torosetta bazelrcwriting/etc/bazel.bazelrc. If neither is available, the plugin warns (vanillabazelcalls won't be configured) but does not fail the build — warming is done andaspect <task>steps are unaffected.
It does not install aspect, bazel, or Bazelisk, and does not wire up any
ephemeral-runner caching or auth — Buildkite runners are expected to be Aspect
Workflows runners, which already ship those. On a non-Workflows runner the plugin
no-ops gracefully (logs a skip message and exits 0), so it is safe to leave in
a pipeline that occasionally runs elsewhere.
Add the plugin to any step that runs bazel directly:
steps:
- command: bazel test //...
plugins:
- aspect-build/setup-aspect#19a9eb187ad1f1c65c1b6d64a7fc03589041c8ae: ~ # v2026.25.0aspect <task> steps don't need the plugin (they self-configure), but it's
harmless to apply it pipeline-wide.
Pin to a full-length commit SHA, not a branch or tag — tags are mutable and can be repointed at malicious code, so SHA-pinning is the recommended way to consume third-party plugins. Annotate with the version in a trailing comment for readability and let Renovate keep the SHA fresh:
plugins:
- aspect-build/setup-aspect#19a9eb187ad1f1c65c1b6d64a7fc03589041c8ae: ~ # v2026.25.0Find the latest SHA on the Releases page.
- An Aspect Workflows Buildkite runner (sets
ASPECT_WORKFLOWS_RUNNER). On any other agent the plugin no-ops. bashon the agent.aspect,bazel, androsettaare provided by the Workflows runner image.
None. The plugin's behavior is driven entirely by the runner's
ASPECT_WORKFLOWS_RUNNER_* environment variables.
If aspect ci bazelrc is unavailable (the runner's Aspect CLI is older than
v2026.26.44, the minimum supported version of the aspect ci commands) the
plugin falls back to the legacy rosetta bazelrc. If neither is available, the plugin cannot configure
vanilla bazel calls: it emits a warning — but it does not fail the build. If
you see this, upgrade the Aspect CLI on the runner image to v2026.26.44 or
newer: https://github.com/aspect-build/aspect-cli/releases.
rosetta is the legacy generator that a future major Aspect Workflows release
will remove; once it is gone, aspect ci bazelrc is the only path.
See DEVELOPMENT.md. In short:
docker-compose run --rm tests # BATS suite via buildkite/plugin-testerCI (.buildkite/pipeline.yml) runs the tests, the plugin linter, and shellcheck.
Apache-2.0. See LICENSE.