Skip to content
Back to skills

Ci

ASecurity

Guide for testing conventions and CI pipelines — unit tests, integration smoke tests, pytest markers, and GitHub Actions workflows. Use when the user asks about testing, CI, running tests, or adding tests for a recipe.

  • 5 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 1, 2026
testingpythonbashtestinggitapi

Works with

  • api

Security analysis

A100/100

Scanned September 1, 2026

npx -y skills add uiuc-kang-lab/rlvr_generalization_bounds --skill ci --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ci?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ci
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/uiuc-kang-lab-rlvr-generalization-bounds/badge)](https://www.skillsdirectory.com/skills/uiuc-kang-lab-rlvr-generalization-bounds)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ci
description: Guide for testing conventions and CI pipelines — unit tests, integration smoke tests, pytest markers, and GitHub Actions workflows. Use when the user asks about testing, CI, running tests, or adding tests for a recipe.
---

# Testing & CI

The repo has two layers of testing and two CI workflows.

## Reference

Read these for details:
- `tests/helpers.py` — `run_recipe()` helper for smoke tests
- `tests/conftest.py` — Pytest configuration and API key handling
- `tests/recipes/` — Existing recipe smoke tests
- `.github/workflows/pytest.yaml` — Unit test CI (every PR)
- `.github/workflows/smoke-test-recipes.yaml` — Smoke test CI (daily)
- `CONTRIBUTING.md` — Development setup and test commands
- `pyproject.toml` — Pytest configuration (testpaths, markers, file patterns)

## Test structure

```
tinker-cookbook/
├── tinker_cookbook/
│   ├── renderers/parsing_test.py     # Unit tests: *_test.py next to source
│   ├── recipes/math_rl/math_env_test.py
│   └── ...
└── tests/
    ├── conftest.py                   # Skips integration tests without API key
    ├── helpers.py                    # run_recipe() helper
    └── recipes/
        ├── test_recipe_chat_sl.py    # Integration tests: test_recipe_*.py
        ├── test_recipe_dpo.py
        └── ...
```

## Unit tests (`*_test.py`)

Colocated with source code. Run without API key.

```bash
uv run pytest tinker_cookbook/
```

**Conventions:**
- File naming: `<module>_test.py` next to the code it tests
- No network calls, no `TINKER_API_KEY` required
- Fast (< 1s per test)
- Use standard pytest features (fixtures, parametrize, marks)
- Test picklability for components used in distributed rollout

**Example:** `tinker_cookbook/renderers/parsing_test.py`

## Integration / smoke tests (`test_recipe_*.py`)

Live in `tests/recipes/`. Require `TINKER_API_KEY`. Verify recipes can run.

```bash
# Run all integration tests
uv run pytest tests/ -v -x -s

# Run a specific recipe test
uv run pytest tests/recipes/test_recipe_chat_sl.py -v -x -s
```

**Conventions:**
- File naming: `tests/recipes/test_recipe_<name>.py`
- Mark with `@pytest.mark.integration`
- Use `run_recipe()` from `tests/helpers.py`
- `run_recipe()` passes `max_steps=2` by default — recipe runs 2 training steps and exits
- Always pass `behavior_if_log_dir_exists=delete` to avoid CI conflicts
- Override batch sizes to small values for fast execution

**Template:**

```python
import pytest
from tests.helpers import run_recipe

@pytest.mark.integration
def test_my_recipe():
    run_recipe(
        "tinker_cookbook.recipes.my_recipe.train",
        [
            "behavior_if_log_dir_exists=delete",
            "groups_per_batch=4",
        ],
    )
```

### How `run_recipe()` works
1. Launches `uv run python -m <module> <args> max_steps=2` as a subprocess
2. Streams stdout in real time for CI debuggability
3. Waits for clean exit (exit code 0) within timeout (default: 1800s)
4. Fails if process exits non-zero or times out

## Pytest markers

Defined in `pyproject.toml`:
- `@pytest.mark.integration` — Requires API key, skipped locally without `TINKER_API_KEY`
- `@pytest.mark.slow` — Long-running tests

`tests/conftest.py` auto-skips integration tests when `TINKER_API_KEY` is not set (fails on CI if missing).

## CI workflows

### `pytest.yaml` — Unit tests (every PR/push to main)
```
Trigger: push to main, pull requests
Runs: uv run pytest tinker_cookbook/
Requires: HF_TOKEN (for tokenizer access)
```

### `smoke-test-recipes.yaml` — Integration tests (daily + manual)
```
Trigger: daily at 6am UTC, manual dispatch
Runs: Each test_recipe_*.py in parallel (matrix strategy)
Requires: TINKER_API_KEY, HF_TOKEN
Timeout: 20 min per recipe
Concurrency: 1 (avoid API contention)
```

Adding `tests/recipes/test_recipe_<name>.py` is all that's needed — CI auto-discovers it.

## Running pre-commit checks

```bash
uv run ruff check tinker_cookbook/
uv run ruff format tinker_cookbook/
uv run pyright tinker_cookbook/
pre-commit run --all-files
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.