Skip to content

dev-ugurkontel/docsmoke

docsmoke

CI PyPI Downloads Release Last commit Python License: Apache 2.0 Checked with mypy Ruff

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 docsmoke execute 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 label
  • cwd=<path>: working directory relative to the project root
  • timeout=<seconds>: positive per-snippet timeout
  • expect-contains=<text>: required stdout or stderr substring
  • expect-regex=<pattern>: required regex match against stdout or stderr
  • env.NAME=<value>: environment variable override
  • shell=<binary>: shell override for shell snippets
  • skip[=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.0 for fully reproducible workflow inputs.

- uses: dev-ugurkontel/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/dev-ugurkontel/docsmoke:latest scan README.md docs examples

Use :latest for convenience, :1 for the moving stable major line, or :1.0.0 for a fully pinned container.

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

Development

make all

License

Apache 2.0 licensed. See LICENSE.

Packages

 
 
 

Contributors