docsmoke
Executable documentation smoke tests for Markdown.
docsmoke runs the shell and Python examples you mark in README.md,
docs/, and onboarding guides, then fails CI when those examples stop
matching reality. It is intentionally small: opt-in fenced blocks,
inline expectations, deterministic timeouts, and reports that fit pull
requests.
Why Maintainers Use It
- Docs fail like code — quickstarts, install commands, and CLI examples run in CI instead of quietly rotting.
- Markdown-native — authors keep examples in ordinary fenced blocks.
- Opt-in by default — only snippets marked for
docsmokeexecute unless you explicitly choose--all-supported. - Assert behavior — expectations, regexes, timeouts, working directories, environment overrides, skips, and shell overrides live next to the example.
- CI-native — console, JSON, and Markdown reports work in local terminals, GitHub Actions, and release gates.
- Supply-chain aware — releases publish to PyPI, GitHub Releases, GHCR, and the reusable GitHub Action with SBOMs and Sigstore bundles.
Use It When
- your README contains copy-paste commands that users rely on
- your docs include shell or Python examples that should keep working
- you want a narrow documentation gate in CI
- you want to verify examples without adopting a full documentation platform
Reach for Other Tools When
- you need prose style linting or grammar checks
- you need full notebook execution
- you need browser-based end-to-end tests
- you want to run arbitrary untrusted snippets without sandboxing
Quick Start
pipx install docsmoke
docsmoke --help
Detailed installation: docs/INSTALL.md.
Mark Runnable Snippets
Put docsmoke after the language in the fenced block's info string.
The first word, bash, still controls Markdown syntax highlighting; the
second word, docsmoke, is the opt-in marker that tells the scanner to
execute the block.
```bash docsmoke
# docsmoke: name=hello; expect-contains=hello
printf 'hello\n'
```
Run a scan:
# docsmoke: name=scan-examples
docsmoke scan examples --quiet
List what would run:
# docsmoke: expect-contains=example-snippet
docsmoke list-snippets examples --json
Directive Syntax
Directives live in the first lines of a runnable fenced block:
```bash docsmoke
# docsmoke: name=install-check
# docsmoke: cwd=examples
# docsmoke: expect-contains=hello
printf 'hello\n'
```
Supported directives:
name=<value>: human-friendly snippet labelcwd=<path>: working directory relative to the project roottimeout=<seconds>: positive per-snippet timeoutexpect-contains=<text>: required stdout or stderr substringexpect-regex=<pattern>: required regex match against stdout or stderrenv.NAME=<value>: environment variable overrideshell=<binary>: shell override for shell snippetsskip[=true|false]: skip the snippet without removing it
GitHub Action
Use the moving @v1 tag to receive compatible 1.x fixes automatically, or
pin an exact release such as @v1.0.5 for fully reproducible workflow inputs.
- uses: fillbyte/docsmoke@v1
with:
paths: README.md docs examples
Distribution Options
- PyPI — best for
pipx, virtualenvs, and Python-based tooling. - GHCR — best when CI prefers a pinned container image.
- GitHub Action — best when docs validation already lives in Actions.
docker run --rm -v "$PWD:/work" -w /work \
ghcr.io/fillbyte/docsmoke:latest scan README.md docs examples
Use :latest for convenience, :1 for the moving stable major line, or
:1.0.5 for a fully pinned container.
Published images include native linux/amd64 and linux/arm64 manifests, so
the same tags run on x86-64 Linux and Apple Silicon container hosts.
Sample Output
docsmoke
passed examples/README.md:5 bash 0.004s ok
Summary: total=1 passed=1 failed=0 skipped=0 errors=0
Project Site
Documentation
- docs/INSTALL.md: installation options
- docs/USAGE.md: CLI usage and workflows
- docs/CONFIG.md: configuration file reference
- docs/ARCHITECTURE.md: internal architecture
- docs/RECIPES.md: CI, Docker, and migration recipes
- docs/REPORT_SCHEMA.md: JSON report contract
- docs/RELEASE.md: release and tag-management process
- docs/REPOSITORY.md: repository settings checklist
- CONTRIBUTING.md: contribution workflow
- SECURITY.md: private vulnerability disclosure
- SUPPORT.md: usage help and issue routing
Development
make all
License
Apache 2.0 licensed. See LICENSE.
Release files for docsmoke 1.0.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| docsmoke-1.0.5.tar.gz | 45.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| docsmoke-1.0.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 70.7 kB
Release files / docsmoke-1.0.5.tar.gz
| Download URL | docsmoke-1.0.5.tar.gz |
|---|---|
| Size | 45.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
78028adbd2e935a66ca64f5d8430aa939cfc1f71e0d999a2e8b4929bf6a3bdef
|
|
BLAKE2b-256 checksum How to use checksums |
a2520c1f81db502a8b2ba5e9ed1ad2bc734126a5695242337ed42aa9ffe15c58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency logRelease files / docsmoke-1.0.5-py3-none-any.whl
| Download URL | docsmoke-1.0.5-py3-none-any.whl |
|---|---|
| Size | 25.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
846e5bcc2dcefb7f901aa5e40265142ef5b48b612aa7bbebf9a5c116413a62c7
|
|
BLAKE2b-256 checksum How to use checksums |
2258445c0e3ada5ecc78eba6e43ea97bf7aa9bb4726b46ecd83d47bb0e0d3465
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency log