Skip to content

feat(ci): validate embedded Mergify config examples against the schema#12142

Merged
mergify[bot] merged 1 commit into
mainfrom
devs/jd/jd/validate-config-examples/validate-embedded-mergify-config-examples-against--ec4826a9
Jul 20, 2026
Merged

feat(ci): validate embedded Mergify config examples against the schema#12142
mergify[bot] merged 1 commit into
mainfrom
devs/jd/jd/validate-config-examples/validate-embedded-mergify-config-examples-against--ec4826a9

Conversation

@jd

@jd jd commented Jul 17, 2026

Copy link
Copy Markdown
Member

Docs config snippets are the most-copied content on the site, but nothing
stopped them from drifting out of sync with the real Mergify config schema.
A wrong example erodes trust instantly. This adds CI that extracts every
Mergify config example from the MDX and validates it, so a broken snippet
fails CI instead of silently misleading users.

This started as a spike ("not sure it's possible"). It is possible, cleanly.
The three feasibility risks resolved as follows:

  1. Schema source. The repo already vendors the exact schema at
    public/mergify-configuration-schema.json (draft 2020-12), and it is kept
    fresh by the automated "chore: sync Mergify JSON Schema files" commits. We
    validate against that in-repo copy — offline, no auth, no network. The
    mergify config validate CLI was evaluated and rejected for CI: it fetches
    the schema over the network from docs.mergify.com (the served copy even lags
    the just-synced repo file), which is both flaky and circular — validating the
    docs against a schema served by the docs. It does the same structural
    JSON-Schema check we do, so we lose nothing. It remains the right tool for
    deep, single-config semantic validation locally.

  2. Extraction / partial-vs-complete. A block is validated only when it has an
    unindented top-level Mergify key (queue_rules, pull_request_rules,
    scopes, merge_protections_settings, ...). Fragments, ... placeholders,
    GitHub Actions YAML, and # partial-marked blocks are skipped automatically.
    For a complete-looking block that must not be validated (deprecated syntax in
    a migration guide), a reader-invisible MDX comment
    {/* validate-config-examples: skip — why */} before the fence excludes it.

  3. CI shape. A new config-examples job in the existing GitHub Actions
    workflow runs pnpm check:config-examples, mirroring the other jobs.

Running the validator over the current docs surfaced 111 complete config
examples; 2 were genuinely broken and are fixed here:

  • comment.mdx: message: @{{author}} ... is invalid YAML (leading @), now
    quoted.

  • backport.mdx: bot_account: {{ author }} is invalid YAML (flow mapping),
    now quoted.
    The 2 deprecated partition_rules examples in the partitions→scopes migration
    guide are marked skipped.

  • Validation is structural only. Mergify's custom string formats
    (duration, template, ...) are intentionally not enforced — a generic
    JSON-Schema duration validator reads it as ISO-8601 and would wrongly reject
    valid values like checks_timeout: 5 min.

  • Consolidated on a single Node implementation (scripts/validate-config-examples.mjs,
    repo-native, with unit + integration tests) and retired the earlier standalone
    Python extractor; the validate-config-examples skill now drives the same script.

  • pnpm check:config-examples — green (111 checked, 2 skipped, 0 invalid)

  • pnpm test — 73 passing, incl. a negative test proving the validator rejects
    an unknown key (not a no-op)

  • pnpm check — clean (astro check + eslint + biome)

  • actionlint — clean on the updated workflow

Copilot AI review requested due to automatic review settings July 17, 2026 14:47
@mergify
mergify Bot had a problem deploying to Mergify Merge Protections July 17, 2026 14:47 Failure
@mergify

mergify Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 All 6 merge protections satisfied — ready to merge.

Show 6 satisfied protections

🟢 🤖 Continuous Integration

  • all of:
    • check-success = build
    • check-success = lint
    • check-success = test
    • any of:
      • check-success = test-broken-links
      • label = ignore-broken-links
    • any of:
      • check-success=Cloudflare Pages
      • -head-repo-full-name~=^Mergifyio/

🟢 👀 Review Requirements

  • any of:
    • #approved-reviews-by >= 2
    • author = dependabot[bot]
    • author = mergify-ci-bot

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:

🟢 🔎 Reviews

  • #changes-requested-reviews-by = 0
  • #review-requested = 0
  • #review-threads-unresolved = 0

🟢 📕 PR description

  • body ~= (?ms:.{48,})

🟢 🚦 Auto-queue

When all merge protections are satisfied, this pull request will be queued automatically.

@mergify
mergify Bot requested a review from a team July 17, 2026 14:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a repo-native CI check to prevent .mergify.yml examples embedded in docs from drifting out of sync with the vendored JSON Schema, so invalid snippets fail PR validation instead of silently shipping.

Changes:

  • Introduces scripts/validate-config-examples.mjs (Ajv + js-yaml) plus Vitest coverage to extract/classify YAML fences in MDX and structurally validate complete Mergify configs against public/mergify-configuration-schema.json.
  • Adds pnpm check:config-examples and a dedicated GitHub Actions job to run it in CI.
  • Fixes/marks up a few docs snippets so they either validate (quote needed templates) or are explicitly skipped (deprecated partition_rules migration examples).

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/content/docs/workflow/actions/comment.mdx Quotes a template-containing string so the YAML example parses and validates.
src/content/docs/workflow/actions/backport.mdx Quotes a template-containing value so the YAML example parses and validates.
src/content/docs/merge-queue/migrate-partitions-to-scopes.mdx Adds skip directives for intentionally-deprecated partition_rules examples.
scripts/validate-config-examples.mjs New validator/extractor CLI for MDX YAML fences, using Ajv 2020 + js-yaml.
scripts/validate-config-examples.test.mjs Unit + integration tests covering classification, schema validation, skip directive behavior, and a docs-wide validation pass.
package.json Adds check:config-examples script entry.
pnpm-lock.yaml Locks the new Ajv dev dependency.
.github/workflows/ci.yaml Adds a config-examples CI job to run the new check.
.claude/skills/validate-config-examples/SKILL.md Updates the skill docs to describe the new Node-based workflow (needs a small fence fix per review comment).
.claude/skills/validate-config-examples/scripts/extract_yaml.py Removes the superseded Python extractor.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/ci.yaml Outdated
Comment thread .claude/skills/validate-config-examples/SKILL.md Outdated
Docs config snippets are the most-copied content on the site, but nothing
stopped them from drifting out of sync with the real Mergify config schema.
A wrong example erodes trust instantly. This adds CI that extracts every
Mergify config example from the MDX and validates it, so a broken snippet
fails CI instead of silently misleading users.

This started as a spike ("not sure it's possible"). It is possible, cleanly.
The three feasibility risks resolved as follows:

1. Schema source. The repo already vendors the exact schema at
   `public/mergify-configuration-schema.json` (draft 2020-12), and it is kept
   fresh by the automated "chore: sync Mergify JSON Schema files" commits. We
   validate against that in-repo copy — offline, no auth, no network. The
   `mergify config validate` CLI was evaluated and rejected for CI: it fetches
   the schema over the network from docs.mergify.com (the served copy even lags
   the just-synced repo file), which is both flaky and circular — validating the
   docs against a schema served by the docs. It does the same structural
   JSON-Schema check we do, so we lose nothing. It remains the right tool for
   deep, single-config semantic validation locally.

2. Extraction / partial-vs-complete. A block is validated only when it has an
   unindented top-level Mergify key (`queue_rules`, `pull_request_rules`,
   `scopes`, `merge_protections_settings`, ...). Fragments, `...` placeholders,
   GitHub Actions YAML, and `# partial`-marked blocks are skipped automatically.
   For a complete-looking block that must not be validated (deprecated syntax in
   a migration guide), a reader-invisible MDX comment
   `{/* validate-config-examples: skip — why */}` before the fence excludes it.

3. CI shape. A new `config-examples` job in the existing GitHub Actions
   workflow runs `pnpm check:config-examples`, mirroring the other jobs.

Running the validator over the current docs surfaced 111 complete config
examples; 2 were genuinely broken and are fixed here:
- `comment.mdx`: `message: @{{author}} ...` is invalid YAML (leading `@`), now
  quoted.
- `backport.mdx`: `bot_account: {{ author }}` is invalid YAML (flow mapping),
  now quoted.
The 2 deprecated `partition_rules` examples in the partitions→scopes migration
guide are marked skipped.

- Validation is structural only. Mergify's custom string formats
  (`duration`, `template`, ...) are intentionally not enforced — a generic
  JSON-Schema `duration` validator reads it as ISO-8601 and would wrongly reject
  valid values like `checks_timeout: 5 min`.
- Consolidated on a single Node implementation (`scripts/validate-config-examples.mjs`,
  repo-native, with unit + integration tests) and retired the earlier standalone
  Python extractor; the `validate-config-examples` skill now drives the same script.

- `pnpm check:config-examples` — green (111 checked, 2 skipped, 0 invalid)
- `pnpm test` — 73 passing, incl. a negative test proving the validator rejects
  an unknown key (not a no-op)
- `pnpm check` — clean (astro check + eslint + biome)
- actionlint — clean on the updated workflow

Change-Id: Iec4826a97e941255bcfcf0133a654edaf1f07585
@jd
jd force-pushed the devs/jd/jd/validate-config-examples/validate-embedded-mergify-config-examples-against--ec4826a9 branch from d41044e to 50d4f0c Compare July 17, 2026 15:59
@jd

jd commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

Revision history

# Type Changes Reason Date
1 initial d41044e 2026-07-17 15:59 UTC
2 content d41044e → 50d4f0c (raw) 2026-07-17 15:59 UTC

@mergify
mergify Bot deployed to Mergify Merge Protections July 17, 2026 15:59 Active
@jd
jd marked this pull request as ready for review July 17, 2026 16:07
@mergify
mergify Bot requested a review from a team July 18, 2026 05:41
@mergify

mergify Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Merge Queue Status

This pull request spent 2 minutes 30 seconds in the queue, including 2 minutes 14 seconds running CI.

Required conditions to merge

@mergify mergify Bot added the queued label Jul 20, 2026
@mergify
mergify Bot merged commit 38fa9e9 into main Jul 20, 2026
9 of 15 checks passed
@mergify
mergify Bot deleted the devs/jd/jd/validate-config-examples/validate-embedded-mergify-config-examples-against--ec4826a9 branch July 20, 2026 07:49
@mergify mergify Bot removed the queued label Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants