srbouffard/guiderails

Generate readable tutorials from YAML and validate them in CI. Write once, Generate and Run.

★ 0Forks 0PythonGitHub ↗Compare

README

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.

Contributors

Copilotsrbouffard

Issues