From 25b2d0457c43d8e9cd5f524d0aa3c19f0bb30cdd Mon Sep 17 00:00:00 2001 From: bohdansolovie Date: Sat, 4 Jul 2026 16:54:24 +0200 Subject: [PATCH] fix(enrichment): treat .python-version as a Python runtime pin for EOL checks The EOL analyzer and its scheduler gate recognized Node pin files but not pyenv/asdf's `.python-version`, so PRs that pin Python that way silently skipped EOL analysis. Parse `.python-version` as product `python` and admit it through the runtime-pin gate. Co-authored-by: Cursor --- review-enrichment/src/analyzers/eol-check.ts | 4 ++++ review-enrichment/src/scheduler.ts | 3 ++- review-enrichment/test/eol-check.test.ts | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/review-enrichment/src/analyzers/eol-check.ts b/review-enrichment/src/analyzers/eol-check.ts index 1c6877623..b76c74983 100644 --- a/review-enrichment/src/analyzers/eol-check.ts +++ b/review-enrichment/src/analyzers/eol-check.ts @@ -92,6 +92,10 @@ export function extractVersionPins( // `.node-version` (nodenv/asdf) carries the same leading-version pin as `.nvmrc`. const version = leadingVersion(line); if (version) pins.push({ file: file.path, product: "nodejs", version }); + } else if (base === ".python-version") { + // pyenv/asdf pin file — same leading-version format, product is Python. + const version = leadingVersion(line); + if (version) pins.push({ file: file.path, product: "python", version }); } else if (base === "go.mod") { const match = /^go\s+(\d+\.\d+)/.exec(line); if (match) diff --git a/review-enrichment/src/scheduler.ts b/review-enrichment/src/scheduler.ts index 94c7637a6..b24768d99 100644 --- a/review-enrichment/src/scheduler.ts +++ b/review-enrichment/src/scheduler.ts @@ -404,11 +404,12 @@ function isRuntimePinPath(path: string): boolean { // Share the eol analyzer's own Dockerfile predicate so the gate can't skip a file the analyzer would // parse. The prior bespoke `/^Dockerfile(?:\..*)?$/` missed `*.dockerfile` (e.g. web.dockerfile), silently // dropping eol analysis for it even though isDockerfile() handles it. - // `.node-version` is the nodenv/asdf pin file; the eol analyzer parses it like `.nvmrc`. + // `.node-version` / `.python-version` are nodenv/pyenv (and asdf) pin files the eol analyzer parses. return ( isDockerfile(path) || basename === ".nvmrc" || basename === ".node-version" || + basename === ".python-version" || basename === "go.mod" ); } diff --git a/review-enrichment/test/eol-check.test.ts b/review-enrichment/test/eol-check.test.ts index e827b5ebb..e2c342366 100644 --- a/review-enrichment/test/eol-check.test.ts +++ b/review-enrichment/test/eol-check.test.ts @@ -51,6 +51,13 @@ test("extractVersionPins reads .node-version pins like .nvmrc", () => { ]); }); +test("extractVersionPins reads .python-version pins as Python", () => { + // pyenv/asdf use `.python-version` with the same leading-version format. + assert.deepEqual(extractVersionPins([added(".python-version", "3.11.0")]), [ + { file: ".python-version", product: "python", version: "3.11.0" }, + ]); +}); + test("extractVersionPins ignores removed/context lines and files with no patch", () => { const patch = ["@@ -1 +1,2 @@", "-FROM python:3.7", " FROM python:3.9"].join( "\n",