Anodyse is a CLI that turns Ansible playbooks and roles into user-facing Markdown docs.
It scans files, extracts @ annotations and TODO/FIXME comments, then renders:
- one doc page per playbook/role
- an
index.mdsummary page
- Keeps operational docs close to automation code
- Produces readable docs for consumers (not just Ansible authors)
- Works for single files, role directories, or whole trees
- Fits CI usage via clear exit codes
Requirements:
- Python 3.11+
Install locally:
python -m pip install -e .Install with dev tools:
python -m pip install -e .[dev]Verify:
anodyse --helpGenerate docs from one playbook:
anodyse samples/web-server/deploy-nginx.yml --output docs/samples --verboseGenerate docs from a directory (recursive discovery):
anodyse samples/ --output docs/samples --graph --verboseTypical output:
docs/samples/index.md- one markdown file per discovered playbook/role
Integrate Anodyse into your CI/CD pipeline to automatically generate documentation on every commit, pull request, or schedule.
This repository demonstrates the feature in action! See:
- 📖 Sample Generated Documentation - How the workflows work
- 📋 GitHub Actions Workflows - Copy these to your own repo
- 🔗 Generated Samples: Published to GitHub Pages (when available)
Choose your platform for detailed setup instructions:
- CI Integration Guide - Complete reference for all platforms
- GitHub Actions - 5-minute setup
- GitLab CI/CD - 5-minute setup
- Generic CI Patterns - Jenkins, Woodpecker, CircleCI, Travis, or custom
- Publishing Guide - Publish to GitHub Pages, GitLab Pages, S3, and more
- Platform Comparison - Choose the right platform for your needs
- Copy this workflow to
.github/workflows/anodyse-docs.yml:
name: Generate Docs
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install anodyse
- run: python -m anodyse . --output ./docs --verbose
- uses: actions/upload-artifact@v3
with:
path: ./docs
- uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/main'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs- Commit and push to
main- workflow runs automatically! - See generated docs on GitHub Pages
| Platform | Setup | Difficulty | Notes |
|---|---|---|---|
| GitHub Actions | 10 min | Beginner | Built-in to GitHub, free tier generous |
| GitLab CI/CD | 10 min | Beginner | Built-in to GitLab, 400 min/month free |
| CircleCI | 15 min | Intermediate | Cloud-based, 6,000 credits/month free |
| Jenkins | 20 min | Intermediate | Self-hosted, on-premise support |
| Woodpecker | 15 min | Intermediate | Modern Drone fork, lightweight |
| Travis CI | 10 min | Beginner | |
| Generic Script | 15 min | Intermediate | Use with any CI system or shell |
See CI Platform Support Matrix for detailed comparison.
anodyse TARGET [OPTIONS]
TARGET can be:
- a playbook file (
.yml/.yaml) - a role directory (contains
tasks/main.yml) - a directory containing multiple playbooks/roles
Options:
-o, --output PATHoutput directory (default:./docs)--graphinclude Mermaid flowchart diagrams--no-backupdo not create.bakfiles when overwriting--config PATHexplicit path to.anodyse.yml-v, --verbosedetailed processing output
Exit codes:
0success1parse/runtime error2generated with annotation warnings (for example missing@titleor@description)
File-level annotations:
# @title Human-readable title
# @description Plain-language summary
# @param name: what this parameter means
# @warning Caveat or prerequisite
# @example Example invocation or usage
# @tag category-or-labelTask-level annotations:
# @task.description: Task summary
# @task.note: Extra context
# @task.warning: Task-specific warning
# @task.tag: Task labelTODO tracking:
TODO:andFIXME:are collected from file headers and task comments- optional author form is supported (for example
TODO(ops): ...)
You can control discovery with an optional manifest:
include:
- samples/web-server/deploy-nginx.yml
- samples/database/deploy-postgresql.yml
exclude:
- samples/missing-comments/deploy-unannotated.ymlRules:
- If
includeis present, only those paths are used - Otherwise,
excluderemoves paths from discovered results - Missing declared paths produce warnings
Manifest lookup order:
--configpath (if provided).anodyse.ymlnear the target.anodyse.ymlin repo root (detected via.git)
Override built-in templates by adding files in:
./.anodyse/templates/
Supported override filenames:
playbook.md.j2role.md.j2index.md.j2
Lookup order:
- local overrides in
./.anodyse/templates/ - packaged defaults in
anodyse/templates/
Example (PowerShell):
New-Item -ItemType Directory -Path .anodyse/templates -Force | Out-Null
Copy-Item samples/anodyse-template-overrides/templates/*.j2 .anodyse/templates/
anodyse samples/web-server/deploy-nginx.yml --output docs/custom-templates --verboseRun tests:
pytestRun lint:
ruff check .Build package:
python -m pip install build
python -m build