A Buildkite plugin for integrating with Mergify CI Insights — upload JUnit test reports, detect pull request scopes, and upload scopes to Mergify Merge Queue.
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}"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}"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-refsUpload 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}"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| Property | Required | Default | Description |
|---|---|---|---|
action |
yes | — | junit-process, scopes, scopes-git-refs, or scopes-upload |
token |
for API calls | — | Mergify CI authentication token |
report_path |
for junit-process | — | Glob path to JUnit XML files |
scopes |
no | — | Comma-separated list of scopes. If not set, scopes-upload reads from mergify-ci.scopes meta-data |
mergify_api_url |
no | https://api.mergify.com |
Mergify API endpoint |
job_name |
no | Step label | Override job name (useful for matrix builds) |
mergify_config_path |
no | — | Path to .mergify.yml configuration file |
mergify_cli_version |
no | pinned default | Version of mergify-cli to install. Leave unset to use the plugin's pinned default (kept current by Renovate, see hooks/environment), pin an exact release (e.g. 2026.6.16.1, must be >= 2026.6.15.1), or use latest to always install the newest released version. |
The plugin stores the following values via buildkite-agent meta-data:
| Key | Set by | Description |
|---|---|---|
mergify-ci.base |
scopes, scopes-git-refs |
Merge-queue-aware base SHA |
mergify-ci.head |
scopes, scopes-git-refs |
Merge-queue-aware head SHA |
mergify-ci.source |
scopes, scopes-git-refs |
Reference source (e.g. buildkite_pull_request, merge_queue) |
mergify-ci.scopes |
scopes |
JSON mapping of scope names to "true"/"false" |
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).
mergify-cli is installed as a prebuilt binary (no Python required), downloaded
and checksum-verified by the upstream install.sh.
Supported platforms: Linux (x86_64, aarch64) and macOS (x86_64, aarch64).
curl(to download the installer and the binary)tar(to extract the binary)sha256sumorshasum(to verify the binary checksum)jq(for JSON processing inscopes-upload)
bats tests/Apache 2.0 — see LICENSE.