mirror of
https://github.com/hwchase17/langchain.git
synced 2026-04-04 19:35:08 +00:00
ci: skip excluded files when applying package labels in pr-labeler (#36114)
A PR that only touches `uv.lock` currently gets the label of its' dir because the file rule matches on the file prefix. This is misleading — lockfile-only changes aren't meaningful package changes. The `excludedFiles` list already existed in config (for size calculations), but file rules didn't consult it. ## Changes - Add `skipExcludedFiles` option to file rules in `pr-labeler-config.json`, enabled for the four package rules (`deepagents`, `cli`, `acp`, `evals`) so lockfile-only PRs don't trigger package labels - `matchFileLabels` in `pr-labeler.js` now filters out files whose basename appears in the top-level `excludedFiles` list (currently just `uv.lock`) before testing rules that opt in via `skipExcluded` - Non-package rules (`github_actions`, `dependencies`) are unaffected — they don't set the flag
This commit is contained in:
44
.github/scripts/pr-labeler-config.json
vendored
44
.github/scripts/pr-labeler-config.json
vendored
@@ -53,28 +53,28 @@
|
||||
"infra": "infra"
|
||||
},
|
||||
"fileRules": [
|
||||
{ "label": "core", "prefix": "libs/core/" },
|
||||
{ "label": "langchain-classic", "prefix": "libs/langchain/" },
|
||||
{ "label": "langchain", "prefix": "libs/langchain_v1/" },
|
||||
{ "label": "standard-tests", "prefix": "libs/standard-tests/" },
|
||||
{ "label": "model-profiles", "prefix": "libs/model-profiles/" },
|
||||
{ "label": "text-splitters", "prefix": "libs/text-splitters/" },
|
||||
{ "label": "integration", "prefix": "libs/partners/" },
|
||||
{ "label": "anthropic", "prefix": "libs/partners/anthropic/" },
|
||||
{ "label": "chroma", "prefix": "libs/partners/chroma/" },
|
||||
{ "label": "deepseek", "prefix": "libs/partners/deepseek/" },
|
||||
{ "label": "exa", "prefix": "libs/partners/exa/" },
|
||||
{ "label": "fireworks", "prefix": "libs/partners/fireworks/" },
|
||||
{ "label": "groq", "prefix": "libs/partners/groq/" },
|
||||
{ "label": "huggingface", "prefix": "libs/partners/huggingface/" },
|
||||
{ "label": "mistralai", "prefix": "libs/partners/mistralai/" },
|
||||
{ "label": "nomic", "prefix": "libs/partners/nomic/" },
|
||||
{ "label": "ollama", "prefix": "libs/partners/ollama/" },
|
||||
{ "label": "openai", "prefix": "libs/partners/openai/" },
|
||||
{ "label": "openrouter", "prefix": "libs/partners/openrouter/" },
|
||||
{ "label": "perplexity", "prefix": "libs/partners/perplexity/" },
|
||||
{ "label": "qdrant", "prefix": "libs/partners/qdrant/" },
|
||||
{ "label": "xai", "prefix": "libs/partners/xai/" },
|
||||
{ "label": "core", "prefix": "libs/core/", "skipExcludedFiles": true },
|
||||
{ "label": "langchain-classic", "prefix": "libs/langchain/", "skipExcludedFiles": true },
|
||||
{ "label": "langchain", "prefix": "libs/langchain_v1/", "skipExcludedFiles": true },
|
||||
{ "label": "standard-tests", "prefix": "libs/standard-tests/", "skipExcludedFiles": true },
|
||||
{ "label": "model-profiles", "prefix": "libs/model-profiles/", "skipExcludedFiles": true },
|
||||
{ "label": "text-splitters", "prefix": "libs/text-splitters/", "skipExcludedFiles": true },
|
||||
{ "label": "integration", "prefix": "libs/partners/", "skipExcludedFiles": true },
|
||||
{ "label": "anthropic", "prefix": "libs/partners/anthropic/", "skipExcludedFiles": true },
|
||||
{ "label": "chroma", "prefix": "libs/partners/chroma/", "skipExcludedFiles": true },
|
||||
{ "label": "deepseek", "prefix": "libs/partners/deepseek/", "skipExcludedFiles": true },
|
||||
{ "label": "exa", "prefix": "libs/partners/exa/", "skipExcludedFiles": true },
|
||||
{ "label": "fireworks", "prefix": "libs/partners/fireworks/", "skipExcludedFiles": true },
|
||||
{ "label": "groq", "prefix": "libs/partners/groq/", "skipExcludedFiles": true },
|
||||
{ "label": "huggingface", "prefix": "libs/partners/huggingface/", "skipExcludedFiles": true },
|
||||
{ "label": "mistralai", "prefix": "libs/partners/mistralai/", "skipExcludedFiles": true },
|
||||
{ "label": "nomic", "prefix": "libs/partners/nomic/", "skipExcludedFiles": true },
|
||||
{ "label": "ollama", "prefix": "libs/partners/ollama/", "skipExcludedFiles": true },
|
||||
{ "label": "openai", "prefix": "libs/partners/openai/", "skipExcludedFiles": true },
|
||||
{ "label": "openrouter", "prefix": "libs/partners/openrouter/", "skipExcludedFiles": true },
|
||||
{ "label": "perplexity", "prefix": "libs/partners/perplexity/", "skipExcludedFiles": true },
|
||||
{ "label": "qdrant", "prefix": "libs/partners/qdrant/", "skipExcludedFiles": true },
|
||||
{ "label": "xai", "prefix": "libs/partners/xai/", "skipExcludedFiles": true },
|
||||
{ "label": "github_actions", "prefix": ".github/workflows/" },
|
||||
{ "label": "github_actions", "prefix": ".github/actions/" },
|
||||
{ "label": "dependencies", "suffix": "pyproject.toml" },
|
||||
|
||||
11
.github/scripts/pr-labeler.js
vendored
11
.github/scripts/pr-labeler.js
vendored
@@ -109,15 +109,22 @@ function init(github, owner, repo, config, core) {
|
||||
`(expected one of: prefix, suffix, exact, pattern)`
|
||||
);
|
||||
}
|
||||
return { label: rule.label, test };
|
||||
return { label: rule.label, test, skipExcluded: !!rule.skipExcludedFiles };
|
||||
});
|
||||
}
|
||||
|
||||
function matchFileLabels(files, fileRules) {
|
||||
const rules = fileRules || buildFileRules();
|
||||
const excluded = new Set(excludedFiles);
|
||||
const labels = new Set();
|
||||
for (const rule of rules) {
|
||||
if (files.some(f => rule.test(f.filename ?? ''))) {
|
||||
// skipExcluded: ignore files whose basename is in the top-level
|
||||
// "excludedFiles" list (e.g. uv.lock) so lockfile-only changes
|
||||
// don't trigger package labels.
|
||||
const candidates = rule.skipExcluded
|
||||
? files.filter(f => !excluded.has((f.filename ?? '').split('/').pop()))
|
||||
: files;
|
||||
if (candidates.some(f => rule.test(f.filename ?? ''))) {
|
||||
labels.add(rule.label);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user