Skip to main content

reci

Compile declarative CI recipes into fully-wired GitHub Actions workflows with typed data-flow validation.

To install: pip install reci

Why reci

Writing GitHub Actions workflows by hand means wading through hundreds of lines of boilerplate: forwarding step outputs to job outputs, threading needs.X.outputs.Y expressions across jobs, and copy-pasting config values that belong in one place. When something changes you touch a dozen lines across three jobs — and one typo silently breaks your pipeline.

reci lets you write a short recipe that says what your CI does (which actions, in what order, with what config), and the compiler handles how — auto-wiring cross-job outputs, injecting config from pyproject.toml, and validating data-flow before you push.

reci ships with CLI and Python APIs (see below), but the best way to use it is through AI agent skills — structured instructions that let coding assistants operate reci on your behalf. Instead of memorizing CLI flags and YAML syntax, just say what you want:

  • "Set up CI for this project"
  • "Migrate my existing workflow to reci"
  • "What CI actions make sense here?"

Available skills

Skill What it does
ci-setup Examines your project, proposes a CI plan, writes a recipe, compiles to a workflow
ci-migrate Converts an existing GitHub Actions workflow into a reci recipe
ci-advisor Interactive discussion about what CI pipeline makes sense for your project
reci-dev Guide for contributors — architecture, adding rules, adding adapters

Using the skills

The skills live in reci/data/skills/, so they ship inside pip install reci and any agent host can install them from the repo with the GitHub CLI (gh 2.90+):

gh skill install i2mint/reci ci-setup
gh skill install i2mint/reci ci-migrate
gh skill install i2mint/reci ci-advisor

Claude Code — symlink or copy the skills into your project or your personal skills directory (from a checkout, or from the installed package's reci/data/skills/):

# Make available to all your projects
ln -s /path/to/reci/reci/data/skills/ci-setup ~/.claude/skills/ci-setup
ln -s /path/to/reci/reci/data/skills/ci-migrate ~/.claude/skills/ci-migrate
ln -s /path/to/reci/reci/data/skills/ci-advisor ~/.claude/skills/ci-advisor

# Or just for one project
ln -s /path/to/reci/reci/data/skills/ci-setup my-project/.claude/skills/ci-setup

Then invoke with /ci-setup, /ci-migrate, or /ci-advisor in Claude Code. See the Claude Code skills docs for details.

Other agents — the skills are plain Markdown files following the open Agent Skills standard. For Cursor, Copilot, Windsurf, and other tools, see the standard's integration guide.

Quick start

from reci import (
    parse_recipe_string,
    compile_recipe,
    dump_workflow,
    ActionSpec,
    InputSpec,
    OutputSpec,
)

recipe = parse_recipe_string("""
name: CI
on: [push, pull_request]

jobs:
  test:
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '${{ config.python_version }}'
      - id: run_tests
        run: pytest
""")

# Action specs can be fetched from GitHub or provided manually
specs = {
    "actions/checkout@v4": ActionSpec(ref="actions/checkout@v4"),
    "actions/setup-python@v5": ActionSpec(
        ref="actions/setup-python@v5",
        inputs={"python_version": InputSpec(name="python_version", default="3.x")},
    ),
}

config = {"python_version": "3.12"}
workflow = compile_recipe(recipe, specs, config=config)
print(dump_workflow(workflow))

The compiler:

  • Injects a setup job that exports config values as job outputs
  • Rewrites ${{ config.* }} to ${{ needs.setup.outputs.* }}
  • Auto-wires needs: edges from data-flow dependencies
  • Generates the cross-job output forwarding ceremony (step output -> job output -> needs consumption)

CLI

# Inspect an action's input/output contract
reci inspect actions/setup-python@v5

# Compile a recipe to workflow YAML
reci compile recipe.yml --output .github/workflows/ci.yml

# Validate a recipe + config
reci validate --recipe recipe.yml --format cli

# Scaffold a config skeleton from a recipe
reci scaffold recipe.yml

Five-level input resolution

For each action input, the compiler resolves its value using this precedence:

  1. Explicit with: in the recipe — used verbatim
  2. Upstream output match — ${{ steps.<id>.outputs.<name> }}
  3. Config value (scoped action__key, then shared key) — ${{ needs.setup.outputs.<key> }}
  4. Default from action.yml — omitted (GitHub uses the default)
  5. Required + no source — validation error

Validation

ESLint-style severity (error/warning/info) with ruff-style rule prefixes:

Rule Category What it catches
DAG001 Structure Cycle detected
DAG002 Structure Duplicate output name in a job
FLOW001 Data flow Required input has no source
FLOW002 Data flow Ambiguous wiring (multiple upstream matches)
FLOW006 Data flow Matrix job output consumed downstream (non-deterministic)
CONF001 Config Required config key missing
PURE001 Purity run: step breaks typed contract
ACT002 Action Referenced action not found

Config adapters

Read CI config from your project file of choice:

Adapter Section Library
pyproject [tool.ci] tomlkit (round-trip)
wads [tool.wads.ci] tomlkit
package-json "ci" key json
yaml .ci.yml ruamel.yaml

The recipe format

A recipe looks like a GitHub Actions workflow with reci extensions:

  • ${{ config.* }} — references to config values (resolved from pyproject.toml etc.)
  • bind: — input renaming (bind: {tag_name: version} wires upstream output version to input tag_name)
  • outputs: on run: steps — manual output annotation for untyped steps
name: Python CI
on: [push, pull_request]

jobs:
  test:
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '${{ config.python_version }}'
      - run: pytest

  publish:
    needs: [test]
    steps:
      - uses: actions/checkout@v4
      - id: bump
        uses: i2mint/isee/actions/bump-version-number@master
      - uses: i2mint/wads/actions/git-tag@master
        bind:
          tag_name: version  # wire bump's "version" output to git-tag's "tag_name" input

Metadata

Release files for reci 0.0.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for reci 0.0.9
File Size Uploaded
reci-0.0.9.tar.gz 93.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for reci 0.0.9
File Interpreter ABI Platform
reci-0.0.9-py3-none-any.whl Python 3 none any Details

Total release size: 158.6 kB

Release files / reci-0.0.9.tar.gz

Download URL reci-0.0.9.tar.gz
Size 93.7 kB
Tags Source
SHA-256 checksum
How to use checksums
56e0eb76a34620e6bd888b6775eca92a91850715c56e8ab8bcc7e52193377b0a
BLAKE2b-256 checksum
How to use checksums
e10bb8927deea31ea7ce87258f9a1d54f758b8dbc83b68672b1086560e4132e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / reci-0.0.9-py3-none-any.whl

Download URL reci-0.0.9-py3-none-any.whl
Size 64.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
488eb318b458c9d56dc67e8ccb70e0acd8b345cea2f20800b512614e9ff10c12
BLAKE2b-256 checksum
How to use checksums
7cd0754ea255d5e92237794250e7ec62131d58c0b5537deefcb6b959f33dd8ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.0.33

2 release files

0.0.32

2 release files

0.0.31

2 release files

0.0.30

2 release files

0.0.29

2 release files

0.0.28

2 release files

0.0.27

2 release files

0.0.26

2 release files

0.0.25

2 release files

0.0.24

2 release files

0.0.23

2 release files

0.0.22

2 release files

0.0.21

2 release files

0.0.20

2 release files

0.0.19

2 release files

0.0.18

2 release files

0.0.17

2 release files

0.0.16

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

This release

0.0.9 This release

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page