For the complete documentation index, see llms.txt. This page is also available as Markdown.

Buildkite

Run Lunar on Buildkite — trace builds with a Buildkite agent command hook and deliver build status to Lunar Hub with a Notification Service webhook.

Lunar instruments Buildkite with two pieces:

  1. A Buildkite agent command hook (command is Buildkite's agent-hook type) that wraps each command with Lunar tracing, so collectors run and their data is attributed to your components.

  2. A Buildkite Notification Service webhook to Lunar Hub, so Lunar Hub knows a build ran and CI-dependent policies wait for it instead of finalizing early.

Lunar listens to two webhooks that drive different things: your source-control (SCM) webhook carries source events (push / pull request) and owns component identity, while the Buildkite webhook reports that a build ran so CI-dependent policies wait for it. Buildkite is the CI layer; your SCM is the source host — Buildkite tracing works against the source host your components are already registered with.

Setup

Step 1 — Agent command hook (tracing)

On your Buildkite agent, add a command hook (in the agent's hooks/ directory) that exports the Lunar configuration and runs lunar ci-tracer run to trace the build's command:

# hooks/command
set -e

export LUNAR_CI_TYPE=buildkite
export LUNAR_RUN_CMD="bash -c \"$BUILDKITE_COMMAND\""
export LUNAR_HUB_HOST=hub.example.com
export LUNAR_HUB_TOKEN="$LUNAR_HUB_TOKEN"

lunar ci-tracer run

The lunar CLI installs the CI tracer on first use and caches it, so no separate agent binary needs to be installed on the runner. Source-control credentials (used for changed-file inference) are fetched from Lunar Hub, so no GitHub token is needed on the runner.

The Hub host and ports resolve in order: explicit LUNAR_HUB_* env vars, then the hub: block of a lunar-config.yml the runner can read, then a default of 443 for both gRPC and HTTP. Set LUNAR_HUB_GRPC_PORT / LUNAR_HUB_HTTP_PORT only for a Hub on non-default ports that isn't declared in a manifest. See the Configuration Reference for the full set of LUNAR_* variables.

Step 2 — Notification Service webhook (build status)

Without the webhook, Lunar Hub never learns a Buildkite build happened, so CI-dependent policies would finalize before the build's data lands. In Buildkite, go to Organization Settings → Notification Services → Add → Webhook (the service is org-level, not per-pipeline) and configure it so Lunar Hub records each build:

  • URL: https://<your-hub-host>/webhooks/buildkite

  • Token: set a shared token and configure Lunar Hub with HUB_BUILDKITE_WEBHOOK_TOKEN to the same value. Lunar Hub verifies the X-Buildkite-Token header on every request; an unset token rejects all requests.

  • Events: build.scheduled, build.running, build.finished.

Lunar Hub creates a workflow-run record per build, associates it with the build's commit (and pull request, for PR builds), and re-evaluates CI-dependent policies when a build finishes.

Component attribution

Lunar reads the standard BUILDKITE_* environment to attribute collected data to components. In a monorepo, set one of the following in your pipeline so a build maps to the right subdirectory component (see Components):

  • LUNAR_COMPONENT — name the component(s) explicitly (comma-separated).

  • ciPipelines on the component — matches the Buildkite pipeline name.

  • LUNAR_COMPONENT_INFER=true — infer from changed paths (PR builds) or the working directory.

Scope and limitations

  • Command-level collection is supported (ci-before/after-command hooks). Job- and step-level scopes are not yet collected by Lunar.

  • Changed-path component inference resolves for pull-request builds; push builds fall back to working-directory inference (Buildkite provides no prior-commit SHA to diff against).

  • One CI provider per repo — the first Buildkite build marks the repo as Buildkite-driven, and any other CI provider's doneness probe then skips it. Running two CI providers against the same repo isn't supported.

Last updated