Skip to main content

Tutorials-as-Code: Execute and validate Markdown tutorials

Project description

GuideRails

Tutorials-as-Code: Execute and validate Markdown tutorials to prevent documentation drift.

GuideRails enables you to write interactive, executable tutorials in Markdown that can be:

  • ✅ Validated automatically in CI/CD pipelines
  • 🚀 Run interactively in guided mode for step-by-step execution
  • 📝 Authored with minimal, unobtrusive markup
  • 🌐 Executed from local files or web URLs

Features

  • Markdown-first: Write tutorials in plain Markdown with minimal annotations
  • Interactive mode: Step-by-step guided execution with user prompts
  • CI mode: Automated validation for continuous integration
  • Flexible validation: Support for exit codes, output matching, regex, and exact comparisons
  • File generation: Create files directly from code blocks with .gr-file
  • Output capture: Store command output and exit codes in variables
  • Variable substitution: Use ${VAR} syntax for continuity across steps
  • Web support: Load tutorials from URLs with meta tag discovery
  • Developer-friendly: Simple attribute syntax for marking executable steps
  • Safe by default: Sandboxed file operations within working directory

Note: As of version 0.2.0, the CLI tool has been renamed from guiderun to guiderails for consistency with the project name. Please update your scripts and workflows accordingly. See CHANGELOG.md for details.

Installation

pip install guiderails

Or install from source:

git clone https://github.com/srbouffard/guiderails.git
cd guiderails
pip install -e .

Quick Start

1. Write a Tutorial

Create a Markdown file with GuideRails annotations:

# My First Tutorial

## Step 1: Setup {.gr-step #step1}

Let's create a test directory:

\```bash {.gr-run data-mode=exit data-exp=0}
mkdir -p /tmp/test
\```

## Step 2: Verify {.gr-step #step2}

Check that it was created:

\```bash {.gr-run data-mode=contains data-exp="/tmp/test"}
ls -d /tmp/test
\```

2. Run Interactively

guiderails exec --guided tutorial.md

3. Validate in CI

guiderails exec --ci tutorial.md

Authoring Convention

Marking Steps

Mark tutorial steps by adding {.gr-step} to headings:

## Setup Environment {.gr-step #setup}

Optional: Add an ID with #step-id for reference.

Marking Executable Code

Mark code blocks for execution with {.gr-run}:

\```bash {.gr-run data-mode=exit data-exp=0}
echo "Hello, World!"
\```

Validation Modes

GuideRails supports four validation modes:

1. Exit Code (default)

\```bash {.gr-run data-mode=exit data-exp=0}
test -f myfile.txt
\```

2. Contains

\```bash {.gr-run data-mode=contains data-exp="success"}
./my-script.sh
\```

3. Regex

\```bash {.gr-run data-mode=regex data-exp="Error: [0-9]+"}
./check-status.sh
\```

4. Exact Match

\```bash {.gr-run data-mode=exact data-exp="Hello, World!"}
echo "Hello, World!"
\```

File-Generating Blocks

Create files directly from your tutorial using .gr-file blocks:

\```bash {.gr-file data-path="script.sh" data-mode=write data-exec=true}
#!/bin/bash
echo "Hello from GuideRails!"
\```

Attributes:

  • data-path: Target file path (relative to working directory)
  • data-mode: write (default, overwrite) or append
  • data-exec: true to make file executable (chmod +x)
  • data-template: none (default) or shell (enables ${VAR} substitution)
  • data-once: true to skip if file already exists

Example with variable substitution:

\```python {.gr-file data-path="config.py" data-template=shell}
VERSION = "${APP_VERSION}"
PORT = ${PORT}
\```

Output and Exit Code Capture

Capture command output and exit codes for use in later steps:

\```bash {.gr-run data-out-var=GREETING data-code-var=EXIT_STATUS}
echo "Hello, World!"
exit 0
\```

Capture Options:

  • data-out-var=VARNAME: Store combined stdout/stderr in a variable
  • data-out-file=path: Write stdout to a file
  • data-code-var=VARNAME: Store exit code in a variable

Variable Substitution

Use captured variables in subsequent blocks with ${VAR} syntax:

\```bash {.gr-run data-out-var=NAME}
echo -n "Alice"
\```

\```bash {.gr-run data-mode=contains data-exp="Hello, Alice"}
echo "Hello, ${NAME}"
\```

Variables are automatically substituted when:

  • Running .gr-run code blocks (command is substituted before execution)
  • Writing .gr-file blocks with data-template=shell

Safety: File paths are sandboxed to the working directory by default. Absolute paths and .. traversal are rejected unless explicitly allowed with CLI flags.

Additional Options

  • Timeout: data-timeout=60 (seconds, default: 30)
  • Working Directory: data-workdir=/tmp
  • Continue on Error: data-continue-on-error=true

Example:

\```bash {.gr-run data-mode=exit data-exp=0 data-timeout=60 data-workdir=/tmp}
long-running-command
\```

CLI Usage

Commands

guiderails exec

Execute a tutorial:

guiderails exec [OPTIONS] TUTORIAL

Basic Options:

  • --guided: Run in interactive mode (shows each step, prompts for execution)
  • --ci: Run in CI mode (non-interactive, fails fast, defaults to quiet output)
  • --working-dir, -w PATH: Set base working directory for execution

Verbosity Options:

  • --verbosity LEVEL: Set verbosity level (quiet, normal, verbose, debug)
  • --quiet, -q: Quiet mode (minimal output, alias for --verbosity=quiet)
  • --verbose, -v: Increase verbosity (-v for verbose, -vv or -vvv for debug)
  • --debug: Debug mode (maximum verbosity, alias for --verbosity=debug)

Output Toggle Options:

  • --show-commands / --no-show-commands: Show/hide commands being executed
  • --show-substituted / --no-show-substituted: Show/hide variable substitution hints
  • --show-expected / --no-show-expected: Show/hide expected validation values
  • --show-captured / --no-show-captured: Show/hide captured variable information
  • --timestamps / --no-timestamps: Show/hide execution timestamps
  • --step-banners / --no-step-banners: Show/hide step banners and boxes
  • --previews / --no-previews: Show/hide command previews and extra details

Output Format:

  • --output FORMAT: Output format (text or jsonl)

Verbosity Level Behaviors:

  • quiet: Shows only step titles, commands (if --show-commands), command output, and PASS/FAIL status. Minimal decoration.
  • normal (default): Adds step banners, content boxes, and basic execution results.
  • verbose: Adds command previews, substitution details, timing information, and working directory.
  • debug: Adds internal diagnostics, parser events, and variable table state.

Tutorial Sources:

  • Local file: ./tutorial.md
  • Direct URL: https://example.com/tutorial.md
  • HTML page with meta tag: https://example.com/tutorial.html

Examples

Run locally with interaction:

guiderails exec --guided examples/getting-started.md

Validate in CI (defaults to quiet output):

guiderails exec --ci examples/getting-started.md

Run with verbose output:

guiderails exec --ci --verbose examples/getting-started.md

Run in quiet mode with no command display:

guiderails exec --ci --quiet --no-show-commands examples/getting-started.md

Run from URL:

guiderails exec --guided https://example.com/tutorial.md

From HTML with meta tag:

guiderails exec --guided https://example.com/tutorial.html

The HTML page should include:

<meta name="guiderails:source" content="https://example.com/raw/tutorial.md">

Configuration

GuideRails supports configuration through multiple sources with the following precedence:

1. Command-line flags (highest priority)
2. Environment variables
3. Configuration file (guiderails.yml)
4. Built-in defaults (lowest priority)

Environment Variables

# Verbosity level
export GUIDERAILS_VERBOSITY=quiet|normal|verbose|debug

# Output toggles
export GUIDERAILS_SHOW_COMMANDS=true|false
export GUIDERAILS_SHOW_SUBSTITUTED=true|false
export GUIDERAILS_SHOW_EXPECTED=true|false
export GUIDERAILS_SHOW_CAPTURED=true|false
export GUIDERAILS_TIMESTAMPS=true|false
export GUIDERAILS_STEP_BANNERS=true|false
export GUIDERAILS_PREVIEWS=true|false

Configuration File

Create a guiderails.yml file in your project root:

# Verbosity level (quiet, normal, verbose, debug)
verbosity: normal

# Output toggles
show_commands: true
show_substituted: false
show_expected: true
show_captured: true
show_timestamps: false
show_step_banners: true
show_previews: false

GuideRails will search for guiderails.yml in the current directory and parent directories.

CI Integration

GitHub Actions

Create .github/workflows/validate-tutorials.yml:

name: Validate Tutorials

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  validate:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    
    - name: Install GuideRails
      run: pip install guiderails
    
    - name: Validate tutorials
      run: |
        guiderails exec --ci docs/tutorial.md

Examples

See the examples directory for sample tutorials:

Development

Setup

# Clone the repository
git clone https://github.com/srbouffard/guiderails.git
cd guiderails

# Install in development mode
pip install -e ".[dev]"

Running Tests

pytest tests/ -v

Code Formatting

black src/ tests/
ruff check src/

Roadmap

  • Support for reStructuredText (reST) tutorials
  • Environment variable support
  • Parallel execution of independent steps
  • Step dependencies and conditional execution
  • Plugin system for custom validators
  • Web UI for tutorial execution and monitoring

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details.

Acknowledgments

Inspired by the need for validated, executable documentation that stays in sync with code.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

guiderails-0.1.0.tar.gz (37.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

guiderails-0.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file guiderails-0.1.0.tar.gz.

File metadata

  • Download URL: guiderails-0.1.0.tar.gz
  • Upload date:
  • Size: 37.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for guiderails-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d40637ffaf48d56e9e1bfaf8660c84bf8e5d1e57e6bae3fc3d7cee34c9bc6a04
MD5 6ad6b7eff0d74b1f84e82aabcfc91e46
BLAKE2b-256 ac9e3a9f3421924baab8c3d6202bfb0ebfba778d36d7d8affe4cb45fc171bb61

See more details on using hashes here.

Provenance

The following attestation bundles were made for guiderails-0.1.0.tar.gz:

Publisher: release.yml on srbouffard/guiderails

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file guiderails-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: guiderails-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for guiderails-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 62151ebba591c6266ff5d7ece985e878b05f2b00c627fde0ed42b9fdac509ba8
MD5 58089c0f7f5a428b92e0f0bad9eeaf46
BLAKE2b-256 e00390717722d3ba5401d9e846f87802cc9ff219277bf7ab241b24a280cbaa10

See more details on using hashes here.

Provenance

The following attestation bundles were made for guiderails-0.1.0-py3-none-any.whl:

Publisher: release.yml on srbouffard/guiderails

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page