Skip to content

Add docmeta to CI (GitHub Actions)

This page wires docmeta into GitHub Actions so that every push and pull request validates your document metadata, fails the job when a file is non-conformant, and reports each failure as an inline annotation on the pull request diff.

You do not need to install docmeta into your repository. The recipes here run it with npx, which fetches the published docmeta package on demand. The only requirement on the runner is Node.js 24 or newer.

docmeta is built to behave well in CI. Two properties carry the whole integration:

  • Exit codes drive the gate. docmeta exits 0 when every file is valid, 1 when one or more files fail validation, and 2 on an operational or usage error (for example, no inputs and no config). GitHub Actions treats any non-zero exit from a step as a failed step, so the metadata gate is enforced for free — there is no separate “if failures, then fail” wiring to maintain.
  • --format github produces inline annotations. Instead of pretty console output, the github format emits one GitHub Actions workflow command per error (::error file=...,line=...,col=...::...). GitHub turns each line into an annotation pinned to the offending file and line in the pull request, so reviewers see exactly what failed without opening the job log.

For the full contract, see Exit codes & PR annotations.

Use this when metadata validation is its own job. This is the canonical recipe from examples/docmeta.yml.

  1. Create the workflow file. Add .github/workflows/docmeta.yml:

    .github/workflows/docmeta.yml
    # Validate document metadata on every push and pull request.
    name: Validate metadata
    on:
    push:
    pull_request:
    jobs:
    docmeta:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
    with:
    node-version: 24
    # Validate all Markdown. `--format github` turns failures into inline
    # PR annotations; the nonzero exit code fails the job.
    - name: Validate frontmatter
    run: npx -y docmeta validate "**/*.md" --format github
  2. Adapt the targets. Replace "**/*.md" with the paths, directories, or globs you want to check — for example "docs/**/*.md". Quote globs so the shell passes them to docmeta intact rather than expanding them itself.

  3. Commit and push. On the next push or pull request, the docmeta job runs. A clean run passes; any validation failure fails the job and annotates the diff.

If your repository has a docmeta.config.yaml at its root, its paths: key is the fallback when you pass no positional targets. That lets the workflow step drop the glob entirely:

.github/workflows/docmeta.yml
- name: Validate frontmatter
# Targets come from paths: in docmeta.config.yaml at the repo root.
run: npx -y docmeta validate --format github

Keeping the target list in docmeta.config.yaml means the same command works locally and in CI, and you change what gets validated in one place. See Create your docmeta.config.yaml for the config keys.

You do not need a dedicated workflow. If you already run a docs or lint job, add docmeta as one more step. It needs a checkout and a Node.js 24+ toolchain — if the job already has those, the validation step is a single line.

.github/workflows/docs.yml
jobs:
# ... your existing jobs ...
metadata:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- name: Validate frontmatter
run: npx -y docmeta validate "docs/**/*.md" --format github

To confirm the gate fires, open a pull request that introduces a metadata error — for example, a Markdown file missing a required type field — and check that:

  • The docmeta job is red.
  • The failing file shows an inline annotation on the changed line.
  • A passing change leaves the job green.

If you want to see the same output locally before pushing, run the command from your shell. Locally, --format github prints the raw ::error lines; drop the flag to get the readable pretty report:

Terminal window
npx -y docmeta validate "docs/**/*.md"