Skip to main content

Advanced

Configure automerge

Safe, opinionated automerge setup for docs PRs — GitHub's auto-merge plus a minimum CI gate that catches bad MDX without blocking typo fixes. Reduce review friction on the 80% of changes that don't need human eyes.

Most docs PRs are low-risk: typo fixes, broken-link updates, minor additions. Requiring human review on every one creates friction — a writer opens a PR at 4pm, the reviewer isn't online until the next morning, the typo stays live for 18 hours. GitHub's auto-merge feature lets you flip this: the PR merges automatically once required CI checks pass, without waiting for an approving human.

This guide covers the safe defaults for docs-repo auto-merge.

When auto-merge makes sense

Typo + broken-link fixes

Low-risk by definition. CI catches MDX parse errors. Reviewer adds no value vs 18h delay.

Generated content updates

Auto-generated files (schema-reference, integration pages, llms.txt). CI catches schema drift. Human review is rubber-stamping.

Dependabot bumps

Small dependency updates. CI catches regressions. Patch + minor version bumps auto-merge; major bumps go through review.

Low-churn reference docs

A contributor fixes a value in a table. The table was auto-gen'd from code. No structural change. Safe auto-merge candidate.

When NOT to auto-merge

New pages

Structural change. Every new page should get a human look — voice, IA placement, cross-links all need judgement.

Rewrites of existing pages

Major revisions change the meaning. Need a second pair of eyes to verify accuracy.

Legal / security / billing content

Wrong wording here is expensive. Always human review.

Config schema changes

public/schema.json changes affect every tenant. Review carefully.

The safe baseline setup

Three layers:

  1. GitHub's native auto-merge — opt-in per PR. Requires all checks + reviews (if configured).

  2. Required CI checks — catch mechanical failures before merge.

  3. CODEOWNERS — high-sensitivity paths still require human review even with auto-merge.

Step 1: enable auto-merge on the repo

GitHub repo settings → General → scroll to "Pull Requests" → check "Allow auto-merge".

Now PRs can opt in individually by clicking "Enable auto-merge" on the PR page.

Step 2: required CI checks

In .github/workflows/docs-ci.yml (or equivalent), run checks that catch the classes of errors that shouldn't reach main:

name: Docs CI

on:
  pull_request:
    paths:
      - "docs/**"
      - "nookdocs.config.json"
      - "public/schema.json"
      - "src/components/docs/**"

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci

      # Parse every MDX file — catches syntax errors before deploy
      - name: MDX parse check
        run: |
          node --input-type=module -e "
            import { mdxParse } from 'safe-mdx/parse';
            import { readFileSync, readdirSync, statSync } from 'fs';
            import { join } from 'path';
            function walk(dir) {
              const out = [];
              for (const f of readdirSync(dir)) {
                const p = join(dir, f);
                if (statSync(p).isDirectory()) out.push(...walk(p));
                else if (p.endsWith('.mdx')) out.push(p);
              }
              return out;
            }
            let errors = 0;
            for (const f of walk('docs')) {
              try { mdxParse(readFileSync(f, 'utf-8')); }
              catch(e) { errors++; console.log(\`❌ \${f}:\${e.line}: \${e.message}\`); }
            }
            if (errors) process.exit(1);
            console.log('All MDX files parsed cleanly.');
          "

      # Cross-layer drift (types + validator + renderer + docs + UI)
      - name: Sync check
        run: npm run check:sync

      # TypeScript
      - name: Type check
        run: npx tsc --noEmit

      # JSON validity
      - name: Config JSON valid
        run: node -e "JSON.parse(require('fs').readFileSync('nookdocs.config.json','utf-8'))"

      # Broken links (internal + external)
      - name: Link check
        run: npx lychee --include-file-extensions=mdx docs/ || true
        # `|| true` keeps link-rot from blocking merges; flag it in the PR comment instead

Then in repo settings → Branches → main → Require status checks to pass, check "MDX parse check" + "Sync check" + "Type check" + "Config JSON valid".

Step 3: CODEOWNERS for sensitive paths

.github/CODEOWNERS forces explicit review for paths you care about:

# Default: any docs change pings the docs team (shows in PR sidebar)
/docs/                       @yourorg/docs-team

# Legal / compliance — always require legal review
/docs/legal/                 @yourorg/legal-team
/docs/privacy/               @yourorg/legal-team
/docs/terms/                 @yourorg/legal-team

# Security — security team review
/docs/security/              @yourorg/security-team

# Schema changes — engineering review
/public/schema.json          @yourorg/engineering-team
/src/types/                  @yourorg/engineering-team

# Billing / pricing — product + finance review
/docs/pricing*               @yourorg/finance-team
/docs/billing/               @yourorg/finance-team

Pair with branch protection's "Require review from Code Owners" — now legal-team must review any /docs/legal/ change, even if auto-merge is enabled.

Step 4: enable auto-merge per PR

On each PR you'd like to auto-merge:

  1. Open the PR.

  2. Scroll to the merge panel at the bottom.

  3. Click Enable auto-merge.

  4. Pick merge strategy (squash-and-merge is the usual choice for docs).

Once required checks pass AND required reviews are satisfied, the PR merges automatically.

Auto-merge patterns

Pattern 1: auto-merge on approval

Writer opens PR. Reviewer approves. Auto-merge fires when CI completes. No "hit the button" friction.

Workflow:

  1. Writer opens PR.

  2. Writer clicks "Enable auto-merge" (or uses a PR template checkbox).

  3. Reviewer approves.

  4. CI completes.

  5. PR merges automatically.

Saves the 1-3 minute "pinging reviewer to click merge" step.

Pattern 2: auto-merge Dependabot PRs

Most Dependabot PRs are trivial (patch + minor bumps). Auto-merge these after CI passes:

name: Dependabot auto-merge

on:
  pull_request_target:
    types: [opened, synchronize]

jobs:
  automerge:
    if: github.actor == 'dependabot[bot]'
    runs-on: ubuntu-latest
    steps:
      - name: Dependabot metadata
        id: metadata
        uses: dependabot/fetch-metadata@v2

      # Auto-merge only patch + minor version bumps
      - name: Auto-merge
        if: |
          steps.metadata.outputs.update-type == 'version-update:semver-patch' ||
          steps.metadata.outputs.update-type == 'version-update:semver-minor'
        run: gh pr merge --auto --squash "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Major version bumps still require human review.

Pattern 3: auto-generated content updates

Daily job regenerates integration pages / schema-reference / etc. Opens PR. Auto-merges if CI passes.

name: Regenerate generated content

on:
  schedule:
    - cron: "0 5 * * *"  # daily 5am UTC
  workflow_dispatch:

jobs:
  regen:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
      - run: npm ci

      - name: Regenerate
        run: |
          npm run build:schema-reference
          npm run build:integration-pages

      - name: Open PR (auto-merge enabled)
        uses: peter-evans/create-pull-request@v6
        with:
          commit-message: "chore(generated): refresh auto-generated docs"
          branch: auto/regen-generated-pages
          title: "chore(generated): daily refresh"
          body: |
            Automated refresh of schema-reference + integration pages.
            Auto-merges on CI pass.
          labels: auto-merge

Pairs with a workflow that enables auto-merge on PRs with the auto-merge label.

Safety net — what to do when automerge goes wrong

Inevitably, some bad content ships because auto-merge merged a PR that should have been flagged. Recovery playbook:

Identify the bad commit

git log --oneline main | head -20 on the failing branch.

Revert

git revert <commit-sha> creates a new commit that undoes the bad one. Push to main — auto-deploys within 30 seconds.

Diagnose the gap

What check should have caught this? If parse check missed it, the check is insufficient. If the reviewer wasn't required, CODEOWNERS needs expanding.

Tighten the gate

Update CI / CODEOWNERS to catch this class of error next time. Commit the change.

Reset trust

If automerge caused real damage (legal / security / billing exposure), pause auto-merge for 1-2 weeks. Force human review on everything while the gap gets fixed.

Common automerge mistakes

Related

Was this page helpful?

Last updated August 7, 2026