Skip to main content

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.

This is the per-task migration guide for aspect build and aspect test. See Migrating from legacy YAML-configured tasks for shared setup (CLI version pinning, the recommended two-step migration path, top-level workspaces:).
The legacy Rosetta build and test tasks ran bazel build / bazel test with environment-specific flags injected automatically, built-in retry logic, GitHub status checks, and lifecycle hooks. aspect build and aspect test replace them. Environment-specific flags (BES endpoint, build metadata, runner optimizations) are injected by the BazelDefaults feature. GitHub status checks are posted by the GithubStatusChecks feature. Artifact uploads are handled by the ArtifactUpload feature.
Task-level retry, timeout, and conditional execution are now handled by your CI platform rather than the task runner. Bazel’s internal retry for transient errors (e.g. BLAZE_INTERNAL_ERROR, LOCAL_ENVIRONMENTAL_ERROR) is still built into the CLI.

What changed

AreaYAML-configured tasksAspect CLI tasks
Invocationbazel build / bazel test via task runneraspect build / aspect test
Targetstargets: in .aspect/workflows/config.yaml (default //...)positional args (default ...)
Bazel flagsbazel.flags / bazel.startup_flags in .aspect/workflows/config.yaml--bazel-flag / --bazel-startup-flag
BES / remote cacheAuto-configured from platform configAuto-configured by BazelDefaults
GitHub status checksBuilt into task runnerGithubStatusChecks feature
Artifact uploadBuilt into task runnerArtifactUpload feature (opt-in per artifact kind)
Internal error retryBazel retries 3× on transient errorsBazel retries up to 10× on BLAZE_INTERNAL_ERROR / LOCAL_ENVIRONMENTAL_ERROR
Task timeouttimeout_in_minutes in .aspect/workflows/config.yamlCI platform job/step timeout
Lifecycle hooksbefore_task / after_task hooksCI platform steps
Conditional executionwhen: expressionsCI platform conditionals
Workspacesworkspaces: top-level list (one or more directories)cd <dir> in your CI config; run aspect <task> from there

Configuration migration

Many of the settings below can be applied in either of two ways:
  • CLI flag — pass the flag at invocation time (e.g. aspect build --bazel-flag=--config=remote //...). Good for overrides on individual task invocations, or experimenting with a setting before committing it.
  • .aspect/config.axl — declare it once in your repo’s AXL config so every aspect build / aspect test invocation picks it up. Good for settings that should apply to all invocations of a task type. AXL also lets you compute values programmatically (e.g. branching on CI host or environment), which is more expressive than shell logic wrapped around CLI flags.
Pick whichever fits — you only need one. Where both work, the sections below show them side-by-side under After.

Targets

Before.aspect/workflows/config.yaml:
tasks:
  build:
    targets:
      - //services/...
      - //libs/...
After — positional CLI args or config.axl:
aspect build //services/... //libs/...
The default (no arguments) is ... — expands to all rule targets in the package at and beneath your current directory.

Bazel flags

Before.aspect/workflows/config.yaml:
tasks:
  build:
    bazel:
      flags:
        - --config=remote
        - --jobs=100
      startup_flags:
        - --host_jvm_args=-Xmx4g
After — CLI flag or config.axl:
aspect build \
  --bazel-flag=--config=remote \
  --bazel-flag=--jobs=100 \
  --bazel-startup-flag=--host_jvm_args=-Xmx4g \
  //...

Test tag filters

Before.aspect/workflows/config.yaml:
tasks:
  test:
    filters:
      - integration
      - -slow
After — CLI flag or config.axl:
aspect test --bazel-flag=--test_tag_filters=integration,-slow //...

Code coverage

Before.aspect/workflows/config.yaml:
tasks:
  test:
    coverage: true
After — CLI flag or config.axl:
aspect test \
  --bazel-flag=--collect_code_coverage \
  --bazel-flag=--instrumentation_filter=^// \
  //...

Test log upload

Before.aspect/workflows/config.yaml:
tasks:
  test:
    upload_test_logs: failed
After — CLI flag or config.axl:
aspect test --artifact-upload:upload-test-logs=failed //...
Upload strategies: none (default), failed, executed, all. Test log upload is one knob of the broader Artifact upload feature — see that section for the full list of artifact kinds and authentication requirements.

GitHub status checks

The legacy YAML-configured tasks posted build and test results to a PR comment via the Aspect Workflows GitHub App (also known as Marvin) — there was no per-task GitHub status check. The new Aspect CLI posts a GitHub status check for each aspect build / aspect test invocation via the GithubStatusChecks feature. The feature is enabled by default but only posts checks when the CLI is authenticated — without ASPECT_API_TOKEN set on the runner and the Aspect Workflows GitHub App installed, nothing reaches GitHub. GithubStatusChecks:
  • Creates a check run on the commit as soon as the task starts
  • Updates it with live build progress (target counts, failures) during the build
  • Completes it with a pass/fail conclusion and a build summary including artifact download links
Set --task-key explicitly on any invocation that uses GithubStatusChecks or ArtifactUpload. Status check names and uploaded artifact names are derived from the task key, so a stable, distinct value per invocation makes results identifiable (e.g. build, test). If you omit --task-key, the CLI generates a random one per run and your status checks and artifacts will end up with unpredictable, non-reusable names.

Authentication

GithubStatusChecks needs:
  • ASPECT_API_TOKEN exposed to the runner.
  • The Aspect Workflows GitHub App (also known as Marvin) installed on the GitHub org/repository and linked to your Aspect account, so the CLI can use the App to post the check.
See Authenticating the Aspect CLI for the full setup walkthrough — installing the app, linking the installation, and generating the API token. The most common first-use scenario is a runner without ASPECT_API_TOKEN set. In that case the CLI logs one GitHub status check: authentication failed for <owner>/<repo> — <reason> line per task and the build continues normally. The reason explains what’s missing and includes a link to the setup guide, for example:
GitHub status check: authentication failed for acme/widgets — no Aspect credentials — set ASPECT_API_TOKEN (client_id:secret) in the job env. Setup guide: https://docs.aspect.build/cli/authentication
If checks still don’t appear after authentication is in place, search the build log for GitHub status check: to see what was reported. GithubStatusChecks failures are isolated from the build/test task: transport errors (DNS, TLS, connection refused), API errors (e.g. GitHub 5xx), and other failures inside the feature are caught and logged but never fail the parent aspect build / aspect test invocation.

Artifact upload

The ArtifactUpload feature uploads build artifacts to the CI platform. All upload kinds are opt-in (off by default) because uploaded artifacts are accessible to anyone with repo read access.
On public repositories, uploaded artifacts are downloadable by anyone on the internet. Treat every upload kind as public-by-default and double-check the risk column below before enabling anything.
ArtifactFlagRisk
Test logs--artifact-upload:upload-test-logs=failedMedium — test output can leak CI secrets if a test prints, asserts on, or otherwise emits values from env vars (e.g. tokens, API keys)
Bazel profile--artifact-upload:upload-profile=trueLow — labels and file paths only
Build Event Protocol--artifact-upload:upload-bep=trueLow — the CLI redacts env-var values that may hold secrets or sensitive data before upload
Compact execution log--artifact-upload:upload-exec-log=trueHigh — contains raw action env vars (including secrets); keep off on public repositories
Enable permanently in config.axl:
load("@aspect//feature/artifacts.axl", "ArtifactUpload")

def config(ctx: ConfigContext):
    ctx.features[ArtifactUpload].args.upload_test_logs = "failed"
    ctx.features[ArtifactUpload].args.upload_profile   = True
ArtifactUpload does not use the Aspect Workflows GitHub App or ASPECT_API_TOKEN. It uploads to your CI platform’s native artifact storage using the runner’s own credentials: permissions: id-token: write on GitHub Actions, the Buildkite agent token, CI_JOB_TOKEN on GitLab, the CircleCI runner token. Make sure those credentials are present in the job environment. Supported platforms: Buildkite, CircleCI, GitHub Actions, GitLab.

CI integration examples

name: CI

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  build:
    runs-on: [self-hosted, aspect-workflows, aspect-default]
    permissions:
      id-token: write   # ArtifactUpload uses the runner's OIDC token to call the GitHub Actions artifact API
    env:
      ASPECT_API_TOKEN: ${{ secrets.ASPECT_API_TOKEN }}
    steps:
      - uses: actions/checkout@v6
      - name: Build
        run: aspect build --task-key build //...

  test:
    runs-on: [self-hosted, aspect-workflows, aspect-default]
    permissions:
      id-token: write
    env:
      ASPECT_API_TOKEN: ${{ secrets.ASPECT_API_TOKEN }}
    steps:
      - uses: actions/checkout@v6
      - name: Test
        run: aspect test --task-key test --artifact-upload:upload-test-logs=failed //...