Skip to main content

CI/CD Integration

Zenzic is automation-ready out of the box. The --format json flag and --save option expose machine-readable output that any CI/CD system can consume to drive dynamic badges, quality gates, and regression detection.


JSON Output

Every check command supports --format json:

# Aggregated report for all checks
zenzic check all --format json

# Individual checks
zenzic check links --format json
zenzic check references --format json

# Scoring and regression
zenzic score --format json
zenzic diff --format json

zenzic check all --format json

{
"links": ["guides/setup.md:12 — Link target 'install.md' not found"],
"orphans": ["old-page.md"],
"snippets": [{"file": "api/ref.md", "line": 5, "message": "Snippet target not found"}],
"placeholders": [{"file": "index.md", "line": 1, "issue": "TODO", "detail": "Fix this"}],
"unused_assets": ["images/old-logo.png"],
"references": [],
"nav_contract": []
}

zenzic score --format json

{
"project": "zenzic",
"score": 100,
"threshold": 0,
"status": "success",
"timestamp": "2026-03-24T12:00:00+00:00",
"categories": [
{"name": "links", "weight": 0.35, "issues": 0, "category_score": 1.0, "contribution": 0.35},
{"name": "orphans", "weight": 0.20, "issues": 0, "category_score": 1.0, "contribution": 0.20},
{"name": "snippets", "weight": 0.20, "issues": 0, "category_score": 1.0, "contribution": 0.20},
{"name": "placeholders", "weight": 0.15, "issues": 0, "category_score": 1.0, "contribution": 0.15},
{"name": "assets", "weight": 0.10, "issues": 0, "category_score": 1.0, "contribution": 0.10}
]
}

Each individual check command returns a uniform findings structure:

{
"findings": [
{"rel_path": "guides/setup.md", "line_no": 42, "code": "BROKEN_LINK", "severity": "error", "message": "Link target 'install.md' not found"}
],
"summary": {
"errors": 1, "warnings": 0, "info": 0,
"security_incidents": 0, "security_breaches": 0,
"elapsed_seconds": 0.042
}
}

Exit codes are preserved in JSON mode: exit 0 when only warnings are found, exit 1 on errors (or warnings under --strict), exit 2 on Shield breaches, exit 3 on Blood Sentinel — the same contract as terminal output.


GitHub Actions: Zenzic Shield Gate

The simplest integration — fails the build on any documentation error.

No Python setup required. uvx fetches and runs Zenzic in a throwaway environment on every run. Ideal for documentation-only repositories or teams that do not otherwise need a Python environment in their CI:

# .github/workflows/docs.yml
name: Documentation Quality

on:
push:
branches: [main]
paths: ['docs/**', 'mkdocs.yml']

jobs:
zenzic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Lint documentation
run: uvx --pre zenzic check all --strict

- name: Check references and run Shield
run: uvx --pre zenzic check references

GitHub Actions: Dynamic Score Badge

This workflow reads the .zenzic-score.json snapshot and pushes the live score to a Shields.io endpoint via a GitHub Gist, keeping your badge current on every push.

# .github/workflows/zenzic-badge.yml
name: Zenzic Score Badge

on:
push:
branches: [main]

jobs:
score:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: 🛡️ Run Zenzic Score
id: zenzic_step
run: |
uvx --pre zenzic score --save # threshold read from fail_under in zenzic.toml
SCORE=$(jq '.score' .zenzic-score.json)
echo "SCORE=$SCORE" >> "$GITHUB_OUTPUT"

- name: 🔄 Update Gist for Badge
uses: Schneegans/dynamic-badges-[email protected]
with:
auth: ${{ secrets.GIST_SECRET }}
gistID: ${{ secrets.ZENZIC_GIST_ID }}
filename: zenzic-score.json
label: "🛡️ zenzic score"
message: "${{ steps.zenzic_step.outputs.SCORE }}/100"
valColorRange: ${{ steps.zenzic_step.outputs.SCORE }}
maxColorRange: 100
minColorRange: 0

Setup steps:

  1. Create a GitHub Gist (public or secret).
  2. Create a Personal Access Token with gist scope and store it as GIST_SECRET in your repo secrets.
  3. Store your Gist's ID (the long hex in the URL) as ZENZIC_GIST_ID in your repo secrets.
  4. Add the dynamic badge URL to your README.md:
[![Zenzic Score](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/<user>/<gist-id>/raw/zenzic-score.json)](https://github.com/PythonWoods/zenzic)

Note: valColorRange / maxColorRange / minColorRange produce a smooth green→yellow→red gradient based on the score value. jq is pre-installed on all GitHub-hosted runners.


Regression Detection

zenzic diff compares the current score against the saved .zenzic-score.json baseline:

- name: Detect score regression
run: |
uvx --pre zenzic score --save # update snapshot
uvx --pre zenzic diff --threshold 5 # fail if score drops > 5 points

Combine with branch protection rules to block merges that degrade documentation quality.


Exit Codes Reference

CodeMeaningBadge action
0All checks passedKeep badge green
1One or more checks failedSet badge to failing / ef4444
2Zenzic Shield: credential detectedRotate credential immediately
3Blood Sentinel: path traversal detectedRemove offending link immediately

For the full badge copy-paste reference, see Official Badges.