Skip to content

GitHub Action

The Structured MADR Validator is a composite GitHub Action that validates your Architectural Decision Records against the Structured MADR specification. It checks both YAML frontmatter (via JSON Schema) and body structure (required sections, ordering).

.github/workflows/validate-adrs.yml
name: Validate ADRs
on:
push:
paths:
- 'docs/decisions/**'
pull_request:
paths:
- 'docs/decisions/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate Structured MADR
uses: zircote/structured-madr@v1
with:
path: docs/decisions

All inputs are optional. The action uses sensible defaults that work for most projects.

InputTypeDefaultDescription
pathstringdocs/decisionsPath to the directory containing ADR files, relative to repository root
patternstring**/*.mdGlob pattern for matching ADR files within the path
schemastring(built-in)Path to a custom JSON Schema. Omit to use the built-in Structured MADR schema
strictstringfalseEnable strict mode: fail the check on warnings in addition to errors
fail-on-errorstringtrueWhether to fail the workflow step when validation errors are found

The action sets these outputs for use in subsequent workflow steps.

OutputTypeDescription
validstring"true" if all ADRs passed validation, "false" otherwise
totalstringTotal number of ADR files checked
passedstringNumber of files that passed validation
failedstringNumber of files that failed validation
warningsstringNumber of warnings generated

Fail the workflow on any warnings, not just errors:

- uses: zircote/structured-madr@v1
with:
strict: 'true'

If your ADRs live in a non-default location:

- uses: zircote/structured-madr@v1
with:
path: architecture/decisions

Validate against your own extended schema:

- uses: zircote/structured-madr@v1
with:
schema: .github/schemas/custom-madr.schema.json

Report validation results without failing the workflow:

- uses: zircote/structured-madr@v1
id: adr-check
with:
fail-on-error: 'false'
- name: Report results
run: |
echo "Valid: ${{ steps.adr-check.outputs.valid }}"
echo "Passed: ${{ steps.adr-check.outputs.passed }}/${{ steps.adr-check.outputs.total }}"
- uses: zircote/structured-madr@v1
id: validate
with:
fail-on-error: 'false'
- name: Comment on PR
if: steps.validate.outputs.valid == 'false'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `ADR validation failed: ${context.steps.validate.outputs.failed} of ${context.steps.validate.outputs.total} files have errors.`
})

The action performs two categories of validation:

  1. Frontmatter validation — Checks YAML frontmatter against the JSON Schema, verifying required fields, types, formats, and constraints.
  2. Body structure validation — Checks that the markdown body contains required sections in the correct order, including Status, Context, Decision Drivers, Considered Options, Decision, Consequences, and Audit.

Validation errors appear as GitHub annotations on the pull request, pointing to specific lines in the file.

You can run the same validation locally:

Terminal window
git clone https://github.com/zircote/structured-madr.git
cd structured-madr
npm install
INPUT_PATH=/path/to/your/docs/decisions npm run validate