# Phase 2 — Polish

> Production-readiness: CI/CD, git hooks, runnable examples, and publishing.

## Tasks

- [ ] **CI/CD pipeline** — GitHub Actions workflow (lint, type-check, test)
- [ ] **prek hooks config** — `.pre-commit-config.yaml` for ruff + ty
- [ ] **Runnable examples** — `examples/` directory with standalone scripts
- [ ] **PyPI publishing setup** — build + publish workflow, metadata finalization
- [ ] **Integration tests** — tests with real embeddings (marked slow, optional)

---

## CI/CD Pipeline

### GitHub Actions workflow

```
.github/
└── workflows/
    └── ci.yml
```

The CI workflow should:

1. Run on push to `main` and on pull requests
2. Test on Python 3.12+
3. Steps: install (uv sync), lint (ruff check), format check (ruff format --check), type check (ty check), test (pytest)
4. Optionally: publish to PyPI on tagged releases

---

## prek Hooks Config

prek uses the same `.pre-commit-config.yaml` format as pre-commit. Hooks to configure:

- **ruff** — lint + format check on staged files
- **ruff-format** — auto-format on staged files
- **ty** — type checking

Setup:
```bash
prek install        # install git hooks
prek run --all-files  # run all hooks manually
```

---

## Runnable Examples

```
examples/
├── basic_graph_store.py          # GraphStore + LLMGraphTransformer
├── graph_vector_rag.py           # GraphVectorStore + retrieval chain
├── graph_retriever_traversal.py  # langchain-graph-retriever + Eager strategy
└── hybrid_search.py              # combining GraphStore + GraphVectorStore
```

Each example should:
- Be self-contained (runnable with `uv run python examples/...`)
- Include clear comments explaining each step
- Use in-memory DB by default (no file cleanup needed)
- Note required env vars (e.g. `OPENAI_API_KEY`) at the top

### Example: langchain-graph-retriever

```python
from langchain_graph_retriever import GraphRetriever
from langchain_graph_retriever.strategies import Eager
from grafeo_langchain import GrafeoGraphVectorStore

store = GrafeoGraphVectorStore(embedding=embeddings, db_path="./graph.db")

retriever = GraphRetriever(
    store=store,
    edges=[("entity", "RELATES_TO")],
    strategy=Eager(k=5, start_k=2, depth=3),
)

docs = retriever.invoke("Tell me about AI research")
```

---

## PyPI Publishing

- Ensure `pyproject.toml` metadata is complete (description, URLs, classifiers)
- Add `[project.urls]` section (Homepage, Repository, Issues)
- Test build with `uv build`
- Publish workflow: build sdist + wheel, upload to PyPI on git tag

---

## Integration Tests

- Mark with `@pytest.mark.slow` or `@pytest.mark.integration`
- Require real embedding model (OpenAI or a local model)
- Skip by default, run with `pytest -m integration`
- Test end-to-end: embed -> store -> search -> verify results
