Implementation:Langchain ai Langchain Check Diff CI Detection
Overview
Concrete CI diff-analysis tool that maps changed files to affected packages and generates test matrices, provided by the check_diff.py script in the LangChain monorepo.
Description
The check_diff.py script is the core engine of LangChain's incremental CI system. It receives a list of changed files as command-line arguments, analyzes which packages are affected, builds a dependency graph, and outputs JSON test matrix configurations for GitHub Actions.
Key functions:
all_package_dirs(): Discovers all package directories by globbing forpyproject.tomlfiles underlibs/.dependents_graph(): Builds a mapping of package names to their dependent packages by parsingpyproject.tomldependencies andextended_testing_deps.txtfiles.add_dependents(): Given a set of changed directories, adds all packages that depend on them (except core dependents, which are handled separately)._get_configs_for_single_dir(): Generates test configurations for a single directory with appropriate Python versions._get_pydantic_test_configs(): Generates Pydantic version compatibility test configurations._get_configs_for_multi_dirs(): Orchestrates test matrix generation across all affected directories for a given job type.
File-to-package mapping rules:
- Files under
libs/partners/<name>/map tolibs/partners/<name>. - Files under
libs/core,libs/langchain, etc. map to the corresponding LANGCHAIN_DIRS entry and trigger extended testing on all downstream packages. - Files under
.github/workflows,.github/scriptstrigger extended tests on all core packages. - Files under
libs/standard-teststrigger tests on standard-tests itself plus select partner packages (openai, anthropic, mistralai, fireworks, groq).
Ignored partners: The IGNORED_PARTNERS list (currently ["huggingface"]) excludes unstable packages from dependent testing while still testing them when directly modified.
Output format: Each job type produces a JSON array of configuration objects:
[
{"working-directory": "libs/partners/deepseek", "python-version": "3.10"},
{"working-directory": "libs/partners/deepseek", "python-version": "3.14"}
]
Usage
This script is invoked by the check_diffs GitHub Actions workflow. It is not typically run manually, but can be used for debugging CI behavior.
Code Reference
Source Location: .github/scripts/check_diff.py, Lines 1-333
Entry point signature:
if __name__ == "__main__":
files = sys.argv[1:]
# ... maps files to dirs_to_run categories
# ... builds dependents graph
# ... generates per-job configs
for key, value in map_job_to_configs.items():
json_output = json.dumps(value)
print(f"{key}={json_output}")
Key constants:
LANGCHAIN_DIRS = [
"libs/core",
"libs/text-splitters",
"libs/langchain",
"libs/langchain_v1",
"libs/model-profiles",
]
IGNORE_CORE_DEPENDENTS = False
IGNORED_PARTNERS = [
"huggingface",
]
Import:
# Not imported as a library; invoked as a script
python .github/scripts/check_diff.py <file1> <file2> ...
I/O Contract
| Input | Type | Description |
|---|---|---|
sys.argv[1:] |
list[str] |
Changed file paths relative to repo root |
libs/**/pyproject.toml |
TOML files | Package dependency declarations (read at runtime) |
libs/core/uv.lock |
TOML file | Core lock file for Pydantic version detection |
| Output | Type | Description |
|---|---|---|
lint=<json> |
stdout line | JSON array of lint job configurations |
test=<json> |
stdout line | JSON array of unit test job configurations |
extended-tests=<json> |
stdout line | JSON array of extended test configurations |
compile-integration-tests=<json> |
stdout line | JSON array of integration test compile configurations |
dependencies=<json> |
stdout line | JSON array of dependency check configurations |
test-pydantic=<json> |
stdout line | JSON array of Pydantic compatibility test configurations |
codspeed=<json> |
stdout line | JSON array of performance benchmark configurations |
Usage Examples
Manual invocation for debugging:
# Simulate a change to the deepseek partner package
cd /path/to/langchain
python .github/scripts/check_diff.py libs/partners/deepseek/langchain_deepseek/chat_models.py
Expected output:
lint=[{"working-directory": "libs/partners/deepseek", "python-version": "3.10"}, {"working-directory": "libs/partners/deepseek", "python-version": "3.14"}]
test=[{"working-directory": "libs/partners/deepseek", "python-version": "3.10"}, {"working-directory": "libs/partners/deepseek", "python-version": "3.14"}]
extended-tests=[]
compile-integration-tests=[{"working-directory": "libs/partners/deepseek", "python-version": "3.10"}, {"working-directory": "libs/partners/deepseek", "python-version": "3.14"}]
dependencies=[{"working-directory": "libs/partners/deepseek", "python-version": "3.10"}, {"working-directory": "libs/partners/deepseek", "python-version": "3.14"}]
test-pydantic=[...]
codspeed=[{"working-directory": "libs/partners/deepseek", "python-version": "3.13"}]
Simulating a core change (triggers dependents):
python .github/scripts/check_diff.py libs/core/langchain_core/language_models/chat_models.py
# Output includes libs/core plus dependent packages in test/lint matrices