CI Setup

This guide shows how to run Butterflow in continuous integration with token-aware scheduling and rate-limit protection.

Basic GitHub Actions workflow

name: butterflow
on: [push, pull_request]
jobs:
  evals:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v3
      - run: uv pip install -e ".[dev]"
      - run: uv run butterflow detect
      - run: uv run butterflow plan examples/ --show-cache-clusters
      - run: uv run butterflow run examples/ --dry-run

Token-aware scheduling

The token-aware scheduler reorders flows to maximize cache hits across shared prompt prefixes. Enable it in CI:

butterflow run examples/ --scheduler token-aware

Or set it in pyproject.toml:

[tool.butterflow.scheduler]
default = "token-aware"

The scheduler automatically falls back to deterministic when no rate limits are configured.

Rate limits configuration

Add rate-limit buckets in pyproject.toml:

[tool.butterflow.rate_limits.default]
requests_per_minute = 60
tokens_per_minute = 100000
concurrency_cap = 4

The scheduler uses these buckets to compute wait times between batches.

Caching between CI runs

Cache adapter detection results:

- uses: actions/cache@v4
  with:
    path: .butterflow
    key: butterflow-${{ runner.os }}-${{ hashFiles('pyproject.toml') }}

Dry-run gates

Use --dry-run in PR checks to validate specs without spending tokens:

butterflow run specs/ --dry-run --subset happy

Promote to full execution on main:

butterflow run specs/ --subset happy,golden