Documentation Index
Fetch the complete documentation index at: https://docs.aspect.build/llms.txt
Use this file to discover all available pages before exploring further.
aspect build and aspect test are the core CI tasks. They wrap bazel build and bazel test with automatic environment configuration, live build progress in your CI platform, artifact upload, and reproducible local invocations.
The same command you run in CI works identically on a developer’s machine — no wrappers, no CI-only flag soup. If a build breaks, running aspect build --task-key build //... locally reproduces it exactly.
What they do
aspect build builds Bazel targets. Under the hood it:
- Streams all Build Event Protocol (BEP) events so features can observe individual target outcomes, timing, and outputs
- Injects remote cache / BES flags via the
BazelDefaultsfeature when running on an Aspect Workflows CI runner (or any runner with the relevant env vars) - Retries automatically on
BLAZE_INTERNAL_ERRORandLOCAL_ENVIRONMENTAL_ERROR— transient failures that don’t reflect your code
aspect test is the same but runs bazel test. It adds:
- Code coverage support with LCOV output and optional external tool integration
- Test log upload (via
ArtifactUpload) so failing test output is one click away in CI
Automatic environment configuration
On Aspect Workflows runners,BazelDefaults automatically injects the right BES endpoint, remote cache/execution flags, and runner-specific optimizations. You don’t declare them in CI YAML or commit them to .bazelrc — the task reads the runner environment and does the right thing.
On standard runners, BazelDefaults is a no-op: the same invocation runs against your local output base with no remote connections.
This is the key insight: the same aspect build //... command is fully portable across every CI system and every developer machine.
Configuration
Configure in.aspect/config.axl (applies to every invocation) or via CLI flags (per-invocation overrides).
Targets
Default target pattern is... (all targets in the workspace). Override with positional args:
config.axl:
Additional Bazel flags
Pass extra Bazel flags without editing.bazelrc:
config.axl with conditional logic:
Test filters and coverage
$(bazel info output_path)/_coverage/_coverage_report.dat. The {report} and {lcov} placeholders in --coverage-tool-arg are substituted with the actual report path for compatibility with different tools (genhtml, codecov, etc.).
GitHub Status Checks
TheGithubStatusChecks feature posts a check run to the commit the moment aspect build starts:
- Creates the check run immediately (CI platform and developers can see the build is in progress)
- Streams live progress: target counts, current failures
- Completes with pass/fail and a build summary with artifact download links
ASPECT_API_TOKEN in the job environment and the Aspect Workflows GitHub App installed. Without those, builds and tests work normally — the check is silently skipped with a single log line explaining what’s missing.
Status check names derive from --task-key. Set a stable, distinct key on each invocation:
Artifact upload
ArtifactUpload uploads build outputs to your CI platform’s native storage. All kinds are opt-in (nothing is uploaded by default) because artifacts are accessible to anyone with repo access.
.aspect/config.axl
| Artifact | Flag | When to use |
|---|---|---|
| Test logs | upload_test_logs (none/failed/executed/all) | Debug flaky tests; start with failed |
| Bazel profile | upload_profile | Performance analysis with bazel analyze-profile |
| Build Event Protocol | upload_bep | BES-based tooling; env-var values are redacted before upload |
| Compact execution log | upload_exec_log | Deep action investigation; contains raw env vars — keep off on public repos |
ArtifactUpload uses the runner’s native credentials (permissions: id-token: write on GitHub Actions, agent token on Buildkite, CI_JOB_TOKEN on GitLab). It does not require ASPECT_API_TOKEN.
How it works under the hood
Both tasks use the same BES event streaming infrastructure:- BES tap — a local Build Event Service listener captures every BEP event in a streaming loop, processing up to 10,000 events per tick with a minimum 500ms heartbeat between ticks.
- Feature lifecycle — at
task_started, features subscribe to the event stream.GithubStatusCheckscreates the check run;ArtifactUploadsets up upload queues;BazelDefaultsinjects flags. - Retry budget — if Bazel exits with
BLAZE_INTERNAL_ERRORorLOCAL_ENVIRONMENTAL_ERROR, the task retries automatically. Default: up to 3 additional attempts. Configurable with--bazel-retry-attempts. - Graceful teardown — on cancellation, the task calls
bazel cancelbefore exiting so orphaned Bazel servers don’t accumulate on CI runners.

