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.10

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.10
File Size Uploaded
reci-0.0.10.tar.gz 94.7 kB Details

Built distribution (wheel)

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

Total release size: 160.7 kB

Release files / reci-0.0.10.tar.gz

Download URL reci-0.0.10.tar.gz
Size 94.7 kB
Tags Source
SHA-256 checksum
How to use checksums
24b0925c857a9f2a1f0125dc59a8209046707eb7475ce8e256a7e640269179b7
BLAKE2b-256 checksum
How to use checksums
b20545fee84a52085f5c2adb990d53e88350d42c660f62537fe2925b8eb0dba8
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.10-py3-none-any.whl

Download URL reci-0.0.10-py3-none-any.whl
Size 66.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
56ff1e3d13a61e11fb3256f65fd3f2cf4faeeda351887ab28a5036d38fe1dbcf
BLAKE2b-256 checksum
How to use checksums
a0705f665242302d454319b4cd160d64749ace256f2ca25824ecd308a80cd067
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

This release

0.0.10 This release

2 release files

0.0.9

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