Scopes with Bazel
Configure merge queue scopes using Bazel's dependency graph for precise batching.
If you’re using monorepo tools like Bazel that have built-in dependency graph analysis, you can use their affected project detection instead of file patterns. This approach is often more accurate because these tools understand your project’s dependency relationships.
Configuring Manual Scopes
Section titled Configuring Manual ScopesTo use the manual scopes mechanism, configure Mergify to expect scopes from your CI system:
scopes: source: manual:
queue_rules: - name: default batch_size: 5Detecting Scopes with Bazel
Section titled Detecting Scopes with BazelUse bazel query to determine affected projects and upload them to Mergify.
GitHub Actions
Section titled GitHub Actionsname: Detect Scopeson: pull_request:
jobs: detect-scopes: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v5 with: # The queue-aware base commit must exist locally for `git diff`. fetch-depth: 0
- name: Get git refs id: refs uses: Mergifyio/gha-mergify-ci@v25 with: action: scopes-git-refs
- name: Get scopes id: scopes env: HEAD: ${{ steps.refs.outputs.head }} BASE: ${{ steps.refs.outputs.base }} run: | changed=$(git diff --name-only --diff-filter=ACMR "$BASE" "$HEAD" | tr '\n' ' ') if [ -z "$changed" ]; then echo "scopes=" >> "$GITHUB_OUTPUT" exit 0 fi
set +e packages=$(bazel query --keep_going --noshow_progress --output=package \ "buildfiles(set($changed))" 2>query.err) rc=$? set -e # --keep_going exits 3 when it skipped files outside any Bazel package # (README.md, .github/**). Anything else is a real failure and must not # be swallowed into an empty scope list. if [ "$rc" -ne 0 ] && [ "$rc" -ne 3 ]; then cat query.err >&2 exit "$rc" fi
scopes=$(printf '%s\n' "$packages" | sed '/^$/d' | sort -u | paste -sd, -) echo "Detected scopes: ${scopes:-<none>}" echo "scopes=$scopes" >> "$GITHUB_OUTPUT"
- name: Scopes upload uses: Mergifyio/gha-mergify-ci@v25 with: action: scopes-upload token: ${{ secrets.MERGIFY_TOKEN }} scopes: ${{ steps.scopes.outputs.scopes }}Buildkite
Section titled BuildkiteUsing the
mergifyio/mergify-ci
Buildkite plugin, a first step resolves the merge-queue-aware base and head
SHAs and exposes them as meta-data, while a second step computes the affected
projects with bazel query and uploads them to Mergify:
steps: - label: ":mag: Get git refs" key: git-refs plugins: - mergifyio/mergify-ci#v7: action: scopes-git-refs
- label: ":mag: Detect and upload scopes" depends_on: git-refs command: | BASE=$(buildkite-agent meta-data get "mergify-ci.base") HEAD=$(buildkite-agent meta-data get "mergify-ci.head") CHANGED=$(git diff --name-only --diff-filter=ACMR "$BASE" "$HEAD" | tr '\n' ' ') SCOPES="" if [ -n "$CHANGED" ]; then set +e PACKAGES=$(bazel query --keep_going --noshow_progress --output=package \ "buildfiles(set($CHANGED))" 2>query.err) RC=$? set -e # --keep_going exits 3 when it skipped files outside any Bazel package. # Anything else is a real failure, not an empty scope list. if [ "$RC" -ne 0 ] && [ "$RC" -ne 3 ]; then cat query.err >&2 exit "$RC" fi SCOPES=$(printf '%s\n' "$PACKAGES" | sed '/^$/d' | sort -u | paste -sd, -) fi buildkite-agent meta-data set "mergify-ci.scopes" "$SCOPES" plugins: - mergifyio/mergify-ci#v7: action: scopes-upload token: "${MERGIFY_TOKEN}"Any CI (Mergify CLI)
Section titled Any CI (Mergify CLI)
Install the Mergify CLI in your pipeline and export
MERGIFY_TOKEN. Use
mergify ci git-refs to get the
merge-queue-aware base and head SHAs and
mergify ci scopes-send to upload the
detected scopes:
REFS=$(mergify ci git-refs --format json)BASE=$(printf '%s' "$REFS" | jq -r '.base')HEAD=$(printf '%s' "$REFS" | jq -r '.head')
CHANGED=$(git diff --name-only --diff-filter=ACMR "$BASE" "$HEAD" | tr '\n' ' ')
if [ -z "$CHANGED" ]; thenecho '{"scopes": []}' > scopes.jsonelse# Capture the exit code rather than piping straight into jq: a failed query# piped into jq still writes a well-formed, empty scopes.json and returns 0.if PACKAGES=$(bazel query --keep_going --noshow_progress --output=package \ "buildfiles(set($CHANGED))" 2>query.err); then RC=0else RC=$?fi
# --keep_going exits 3 when it skipped files outside any Bazel package# (README.md, .github/**). Anything else is a real failure.if [ "$RC" -ne 0 ] && [ "$RC" -ne 3 ]; then cat query.err >&2 exit "$RC"fi
printf '%s\n' "$PACKAGES" | sort -u \ | jq -R -s '{scopes: split("\n") | map(select(length > 0))}' > scopes.jsonfi
mergify ci scopes-send --scopes-json scopes.jsonWas this page helpful?
Thanks for your feedback!