> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Buildkite pipelines

> Configure a Buildkite pipeline to run on Aspect Workflows CI runners: target a runner group, keep your existing bazel steps, and optionally adopt Aspect CLI tasks.

export const gatedAccess = (user, group) => {
  const loggedIn = !!(user && user.loggedIn);
  const groups = user && user.tenantMetadata && user.tenantMetadata.docsGroups || [];
  if (loggedIn && (!group || groups.indexOf(group) >= 0)) {
    return "entitled";
  }
  return loggedIn ? "signed-in" : "anonymous";
};

export const GatedLink = ({access, href, group, children}) => {
  const note = group ? "Aspect Enterprise customers" : "free Aspect account";
  const muted = {
    fontSize: "0.85em",
    opacity: 0.7,
    whiteSpace: "nowrap"
  };
  if (access === "entitled") {
    return <a href={href}>{children}</a>;
  }
  if (access !== "signed-in") {
    return <span>
        <a href={"/login?redirect=" + encodeURIComponent(href)}>{children}</a>
        <span style={muted}> (sign in: {note})</span>
      </span>;
  }
  return <span>
      {children}
      <span style={muted}> ({note})</span>
    </span>;
};

Your Buildkite pipeline runs on Aspect Workflows CI runners by targeting a runner group with `agents: queue:`. Your existing `bazel` steps keep working unchanged: the [setup step](/docs/aspect-workflows/enterprise/connect/ci-setup#the-setup-step) wires the runner's remote cache, build event service and NVMe-backed output base into every invocation.

<Note>
  Registering the runners with Buildkite is covered in <GatedLink access={gatedAccess(user, "workflows-subscriber")} href="/docs/aspect-workflows/enterprise/self-hosted/runner-registration/buildkite" group="workflows-subscriber">runner registration</GatedLink>.
</Note>

## Configure a pipeline

1. Create a [new pipeline](https://buildkite.com/docs/pipelines/create-your-own#create-a-pipeline) for your Workflows build, or choose an existing one and configure it.
   * If you use GitHub, follow [these steps](https://buildkite.com/docs/integrations/github#set-up-a-new-pipeline-for-a-github-repository) to integrate your repository with Buildkite.
2. Choose a queue for the pipeline upload step:
   * If you have access to Buildkite hosted agents, create an agent queue with a small agent (2 vCPU and 4 GB RAM is enough) to run it.
   * Otherwise, target an Aspect Workflows runner group such as `aspect-default`.
3. In the Buildkite interface, access **Steps > Convert to YAML Steps** and paste the upload step. This one targets a hosted agent queue named `bk-small`:

```yaml theme={null}
steps:
  - label: ":aspect: Upload .buildkite/pipeline.yaml"
    agents:
      queue: bk-small
    command: buildkite-agent pipeline upload .buildkite/pipeline.yaml
```

This uploads the Buildkite pipeline defined in `.buildkite/pipeline.yaml` in your repository.

4. Define your Buildkite pipeline. Point each step's `command` at your existing `bazel` invocation and target your Workflows runner queue.

Each step uses the [`aspect-build/setup-aspect`](https://github.com/aspect-build/setup-aspect-buildkite-plugin) Buildkite plugin. [The setup step](/docs/aspect-workflows/enterprise/connect/ci-setup#the-setup-step) covers what it does and the inputs it takes.

```yaml title=.buildkite/pipeline.yaml theme={null}
steps:
  - key: build
    label: ":bazel: Build"
    command: bazel build //...
    agents:
      queue: aspect-default
    plugins:
      - aspect-build/setup-aspect#8de9aed254d0699baf201f66e2076fc8c09f42b9: ~ # v2026.38.2

  - key: test
    label: ":bazel: Test"
    command: bazel test //...
    agents:
      queue: aspect-default
    plugins:
      - aspect-build/setup-aspect#8de9aed254d0699baf201f66e2076fc8c09f42b9: ~ # v2026.38.2
```

<Tip>
  See [Aspect Bazel Examples](https://buildkite.com/aspect-build/bazel-examples) for a complete working example of a Buildkite pipeline.
</Tip>

## Non-Bazel jobs

Jobs that don't call Bazel need no setup step. Target the runner group and run your commands:

```yaml title=.buildkite/pipeline.yaml theme={null}
steps:
  - label: "Custom job"
    command: npm install && npm test
    agents:
      queue: aspect-default
```

## Aspect CLI tasks (optional)

Swap a `bazel` command for the matching `aspect <task>` from the open-source [Aspect CLI](/docs/cli/overview) to add status checks, inline PR comments with one-click suggested fixes, retries on transient Bazel errors and [selective delivery](/docs/aspect-workflows/platform/features/selective-delivery).

Using the Aspect CLI's platform integrations requires an `ASPECT_API_TOKEN`. Store it as a [Buildkite secret](https://buildkite.com/docs/pipelines/security/secrets/buildkite-secrets) and name it in the `secrets:` of each step that calls `aspect <task>`, so the setup plugin can exchange it for a session before the step runs.

```yaml title=.buildkite/pipeline.yaml theme={null}
steps:
  - key: build
    label: ":bazel: Build"
    command: aspect build --task:name build -- //...
    secrets: [ASPECT_API_TOKEN]
    agents:
      queue: aspect-default
    plugins:
      - aspect-build/setup-aspect#8de9aed254d0699baf201f66e2076fc8c09f42b9: ~ # v2026.38.2

  - key: test
    label: ":bazel: Test"
    command: aspect test --task:name test -- //...
    secrets: [ASPECT_API_TOKEN]
    agents:
      queue: aspect-default
    plugins:
      - aspect-build/setup-aspect#8de9aed254d0699baf201f66e2076fc8c09f42b9: ~ # v2026.38.2

  - key: format
    label: ":hammer_and_wrench: Format"
    command: aspect format --task:name format
    secrets: [ASPECT_API_TOKEN]
    agents:
      queue: aspect-default
    plugins:
      - aspect-build/setup-aspect#8de9aed254d0699baf201f66e2076fc8c09f42b9: ~ # v2026.38.2

  - key: lint
    label: ":lint-roller: Lint"
    command: aspect lint --task:name lint -- //...
    secrets: [ASPECT_API_TOKEN]
    agents:
      queue: aspect-default
    plugins:
      - aspect-build/setup-aspect#8de9aed254d0699baf201f66e2076fc8c09f42b9: ~ # v2026.38.2

  - key: delivery
    label: ":package: Delivery"
    depends_on: [test]
    if: build.branch == pipeline.default_branch
    command: aspect delivery --task:name delivery --query='attr(tags, deliverable, //...)'
    secrets: [ASPECT_API_TOKEN]
    agents:
      queue: aspect-default
    plugins:
      - aspect-build/setup-aspect#8de9aed254d0699baf201f66e2076fc8c09f42b9: ~ # v2026.38.2
```

The `delivery` step runs only on the default branch. `--query` selects the targets to deliver; without it or positional targets, `aspect delivery` delivers nothing. You can set the query once in `.aspect/config.axl` instead (`ctx.tasks["delivery"].args.query`). See [`aspect delivery`](/docs/cli/tasks/delivery).

See [Running tasks in CI](/docs/cli/tasks-ci) for the full task reference and examples for all CI providers.
