5 views
Strict pyright on a giant monorepo is correct—and useless if every PR waits an hour. The unfair advantage is affected-package analysis: typecheck only dirty projects plus dependents, keep a warm cache, and reserve full-fleet runs for main/nightly.
⚡ TL;DR: Partition withpyrightconfig.json/ polyrepo packages; compute changed paths → package set → dependents; runpyright -pper package with CI cache onpyrightartifacts; full check onmain. Pair with TypeScript Project References and AST-Guided Edits.
Incremental pyright in CI: production guidance
A single root invocation:- Re-walks the entire import graph on every PR
- Contends for CPU with tests and lint in the same job
- Encourages teams to flip
typeCheckingModetobasic“temporarily” - Hides which package introduced the break when the log is 40k lines
Package graph, not file list
bash
# ✅ Example: git-diff → packages (illustrative)
git diff --name-only origin/main...HEAD \
| awk -F/ '/^packages\//{print $2}' \
| sort -u > /tmp/changed_pkgs.txt
python
# ✅ Expand dependents from a simple adjacency file
# packages/deps.json: {"payments": ["ledger", "api"], "api": []}
import json
from pathlib import Path
deps = json.loads(Path("packages/deps.json").read_text())
# reverse edges: who imports me?
rev: dict[str, set[str]] = {k: set() for k in deps}
for pkg, uses in deps.items():
for u in uses:
rev.setdefault(u, set()).add(pkg)
def closure(changed: set[str]) -> set[str]:
out = set(changed)
stack = list(changed)
while stack:
p = stack.pop()
for d in rev.get(p, ()):
if d not in out:
out.add(d)
stack.append(d)
return out
yaml
Generate # ✅ CI job sketch
# - restore cache key: pyright-${{ hashFiles('**/pyrightconfig.json', 'uv.lock') }}
# - for pkg in $(cat affected); do pyright -p packages/$pkg; done
# - on main: pyright -p . # full
deps.json from your packaging tool (Pants, Bazel, uv workspaces, poetry plugins) so humans do not hand-edit edges forever. Treat drift as a CI failure.
Config that keeps strictness
json
Per-package configs should extend a shared base rather than fork rules:
{
"include": ["src"],
"exclude": ["**/tests/fixtures", "**/generated"],
"typeCheckingMode": "strict",
"venvPath": ".",
"venv": ".venv",
"reportMissingImports": true,
"pythonVersion": "3.12"
}
json
{
"extends": "../../pyright.base.json",
"include": ["src"],
"executionEnvironments": [{ "root": "src" }]
}
| Mode | When |
|---|---|
| Affected + dependents | PR / push branches |
| Full workspace | main, nightly, release |
| Changed files only | ❌ misses cross-package breakages |
pyright $(git diff --name-only) on raw files without dependents — you green PRs that break importers.
Caching that actually hits
- Cache key:
pyright-${{ runner.os }}-${{ hashFiles('**/pyrightconfig*.json', 'uv.lock', '**/py.typed') }} - Store the pyright binary / nodeenv separately from package type artifacts
- Prefer
uv sync --frozenbefore pyright so stub packages are identical across runners - Shard by package on large PRs (
matrix.package) but merge results into one check run
Agent-friendly build graph
Coding agents thrash CI when they cannot see package boundaries. Check in a machine-readable graph (same idea as TypeScript Project References) and teach agents to edit within one package + run that package’s pyright locally before opening a PR. Pair with AST-Guided Edits so refactors do not sprayAny across the monorepo.
Escape hatches that do not rot
Allow# pyright: ignore only with a tracking issue ID in the same line. Ban repo-wide typeCheckingMode: off. If a generated client is untyped, put it under exclude and wrap it with a typed facade package.
Nightly full gate as the contract
PR incremental checks are a filter, not the source of truth. Nightly (and every merge tomain) must still run the full strict workspace. If nightly fails while PRs were green, you have a graph bug—usually a missing reverse edge—or an unchecked generated path. Page the owning platform team; do not silently downgrade strictness overnight.
Measuring the win
Track PR wall-clock for the typecheck job before/after incremental rollout. Healthy targets: median PR typecheck under 5–8 minutes on a 1M-LOC monorepo, with nightly full under whatever budget finance already accepted. Publish a weekly dashboard of “PRs that would have missed a dependent break under file-only mode” by replaying diffs — that proves why dependents stay mandatory.Closing checklist
✅ Dos – ✅ Maintain an explicit package dependency graph – ✅ Typecheck dependents of changed packages – ✅ Cache pyright / nodeenv between CI runs – ✅ Keepmain full-strict as the source of truth
– ✅ Fail CI on config drift (pyrightconfig owned)
– ✅ Shard by package on large affected sets
– ✅ Require issue IDs on inline ignores
❌ Don’ts
– ❌ Don’t lower typeCheckingMode to save wall time
– ❌ Don’t skip dependents to “go faster”
– ❌ Don’t commit generated files into the typecheck set without need
– ❌ Don’t run one giant process with no cache on every PR
– ❌ Don’t let agents open PRs without a local package-scoped pyright run
Related reading
Last updated on September 11, 2026 Related: Cursor Agent Mode: Multi-File Refactors That Survive CI Gates; Cursor Background Agents: CI Gates That Catch Hallucinated AWS Changes; WebSockets vs Server-Sent Events vs Long Polling: Real-Time Communication Explained.Watch: 100 Days of AI on YouTube
Short videos from CheatCoders, one AI engineering topic per day.
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- Claude Code vs Cursor vs GitHub Copilot: Choose by Workflow, and Set Up One Repo That Works With All Three
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- Python String Methods: Every str Method With Real Production Examples
- Css Animation Performance: Performance-Optimized Motion for Modern UIs
Newly added
- AWS Systems Manager Parameter Store: Hierarchical Runtime Config for Coding Agents
- Amazon Cognito Identity Pools: Federate Coding-Agent Tool Callers Without Long-Lived Keys
- Amazon Athena for Coding Agents: Query Tool Audit Logs and Eval Traces on S3 Without a Warehouse
- AWS Batch for Coding Agents: Parallel Overnight PR Reviews and Long-Running Jobs Without Lambda Timeouts
- Amazon Bedrock Prompt Management: Version and A/B Test Coding-Agent System Prompts
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
