1. Resources
  2. /
  3. Plugins
  4. /
  5. mergify-ci-buildkite-plugin

Mergify CI Buildkite Plugin

A Buildkite plugin for integrating with Mergify CI Insights — upload JUnit test reports, detect pull request scopes, and upload scopes to Mergify Merge Queue.

Actions

junit-process

Process JUnit XML test reports and upload them to Mergify CI Insights. Detects silent test failures automatically using the step’s exit code.

steps:
  - label: "Run tests"
    command: pytest --junitxml=reports/junit.xml
    plugins:
      - mergifyio/mergify-ci#v2:
          action: junit-process
          report_path: "reports/*.xml"
          token: "${MERGIFY_TOKEN}"

scopes

Detect which code scopes are affected by a pull request and upload them to the Mergify API. A Buildkite annotation is created to display the detected scopes directly on the build page.

steps:
  - label: "Detect scopes"
    plugins:
      - mergifyio/mergify-ci#v2:
          action: scopes
          token: "${MERGIFY_TOKEN}"

scopes-git-refs

Return the merge-queue-aware base and head SHAs. Results are stored as Buildkite meta-data (mergify-ci.base, mergify-ci.head) for use by subsequent steps.

steps:
  - label: "Get git refs"
    key: git-refs
    plugins:
      - mergifyio/mergify-ci#v2:
          action: scopes-git-refs

scopes-upload

Upload scopes to the Mergify API. Requires a prior scopes-git-refs step for base/head refs. Scopes can be provided as a comma-separated list in plugin config, or read automatically from the mergify-ci.scopes meta-data set by a prior scopes step (both JSON and CSV formats are supported).

# Option 1: explicit scopes via plugin config
steps:
  - label: "Get git refs"
    key: git-refs
    plugins:
      - mergifyio/mergify-ci#v2:
          action: scopes-git-refs

  - label: "Upload scopes"
    depends_on: git-refs
    plugins:
      - mergifyio/mergify-ci#v2:
          action: scopes-upload
          token: "${MERGIFY_TOKEN}"
          scopes: "backend,frontend"
# Option 2: scopes from meta-data (set by a prior step)
steps:
  - label: "Generate scopes"
    key: generate-scopes
    command: |
      buildkite-agent meta-data set "mergify-ci.scopes" "backend,frontend"

  - label: "Upload scopes"
    depends_on: generate-scopes
    plugins:
      - mergifyio/mergify-ci#v2:
          action: scopes-upload
          token: "${MERGIFY_TOKEN}"

Using scopes to conditionally run steps

Detect scopes first, then use the meta-data to skip steps unaffected by the change:

steps:
  - label: "Detect scopes"
    key: scopes
    plugins:
      - mergifyio/mergify-ci#v2:
          action: scopes
          token: "${MERGIFY_TOKEN}"

  - label: "Backend tests"
    depends_on: scopes
    command: pytest tests/backend/
    if: build.env("BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG") != null || build.pull_request.id != null
    plugins:
      - mergifyio/mergify-ci#v2:
          action: junit-process
          report_path: "reports/*.xml"
          token: "${MERGIFY_TOKEN}"
    # Use a dynamic pipeline or script to check scopes:
    # SCOPES=$(buildkite-agent meta-data get "mergify-ci.scopes")
    # echo "$SCOPES" | jq -e '.backend == "true"'

  - label: "Frontend tests"
    depends_on: scopes
    command: npm test
    plugins:
      - mergifyio/mergify-ci#v2:
          action: junit-process
          report_path: "reports/*.xml"
          token: "${MERGIFY_TOKEN}"
    # SCOPES=$(buildkite-agent meta-data get "mergify-ci.scopes")
    # echo "$SCOPES" | jq -e '.frontend == "true"'

For full conditional control, use a dynamic pipeline that reads the scopes meta-data and only uploads the relevant steps:

#!/bin/bash
# .buildkite/dynamic-pipeline.sh
SCOPES=$(buildkite-agent meta-data get "mergify-ci.scopes")

if echo "$SCOPES" | jq -e '.backend == "true"' > /dev/null 2>&1; then
  cat <<'YAML'
  - label: "Backend tests"
    command: pytest tests/backend/
    plugins:
      - mergifyio/mergify-ci#v2:
          action: junit-process
          report_path: "reports/*.xml"
          token: "${MERGIFY_TOKEN}"
YAML
fi

if echo "$SCOPES" | jq -e '.frontend == "true"' > /dev/null 2>&1; then
  cat <<'YAML'
  - label: "Frontend tests"
    command: npm test
    plugins:
      - mergifyio/mergify-ci#v2:
          action: junit-process
          report_path: "reports/*.xml"
          token: "${MERGIFY_TOKEN}"
YAML
fi
# pipeline.yml
steps:
  - label: "Detect scopes"
    key: scopes
    plugins:
      - mergifyio/mergify-ci#v2:
          action: scopes
          token: "${MERGIFY_TOKEN}"

  - label: "Upload pipeline"
    depends_on: scopes
    command: .buildkite/dynamic-pipeline.sh | buildkite-agent pipeline upload

Configuration

PropertyRequiredDefaultDescription
actionyesjunit-process, scopes, scopes-git-refs, or scopes-upload
tokenfor API callsMergify CI authentication token
report_pathfor junit-processGlob path to JUnit XML files
scopesnoComma-separated list of scopes. If not set, scopes-upload reads from mergify-ci.scopes meta-data
mergify_api_urlnohttps://api.mergify.comMergify API endpoint
job_namenoStep labelOverride job name (useful for matrix builds)
mergify_config_pathnoPath to .mergify.yml configuration file
python_versionno3.13Python version for mergify-cli. Uses uv to download it if needed. Set to system to use the agent’s system Python.

Meta-data

The plugin stores the following values via buildkite-agent meta-data:

KeySet byDescription
mergify-ci.basescopes, scopes-git-refsMerge-queue-aware base SHA
mergify-ci.headscopes, scopes-git-refsMerge-queue-aware head SHA
mergify-ci.sourcescopes, scopes-git-refsReference source (e.g. buildkite_pull_request, merge_queue)
mergify-ci.scopesscopesJSON mapping of scope names to “true”/“false”

Annotations

The mergify-cli writes Buildkite annotations (context: mergify-ci-scopes) showing the detected scopes as a table. Annotations are written at both build scope (visible on the build page) and job scope (visible on the job card).

Requirements

  • Python 3.x on the Buildkite agent
  • curl (for installing uv)
  • jq (for JSON processing in scopes-upload)

Development

Running tests

bats tests/

License

Apache 2.0 — see LICENSE.

The plugins listed on this webpage are provided for informational purposes only. They have not undergone any formal security review or assessment. While we strive to provide useful resources, we cannot guarantee the safety, reliability, or integrity of these plugins. Users are strongly advised to conduct their own security evaluations before downloading, installing, or using any plugin. By using these plugins, you acknowledge and accept any risks associated with their use. We disclaim any liability for any harm or damages arising from the use of the plugins listed.

Start turning complexity into an advantage

Create an account to get started for free.

Buildkite Pipelines

Platform

  1. Pipelines
  2. Public pipelines
  3. Test Engine
  4. Package Registries
  5. Mobile Delivery Cloud
  6. Pricing

Hosting options

  1. Self-hosted agents
  2. Mac hosted agents
  3. Linux hosted agents

Resources

  1. Docs
  2. Blog
  3. Changelog
  4. Example pipelines
  5. Plugins
  6. Webinars
  7. Case studies
  8. Events
  9. Migration Services
  10. CI/CD perspectives

Company

  1. About
  2. Careers
  3. Press
  4. Security
  5. Brand assets
  6. Contact

Solutions

  1. Replace Jenkins
  2. Workflows for MLOps
  3. Testing at scale
  4. Monorepo mojo
  5. Bazel orchestration

Legal

  1. Terms of Service
  2. Acceptable Use Policy
  3. Privacy Policy
  4. Subprocessors
  5. Service Level Agreement
  6. Supplier Code of Conduct
  7. Modern Slavery Statement

Support

  1. System status
  2. Forum
© Buildkite Pty Ltd 2026