From e300d88f7b8dd8e186875c6fa5dae7749de15bda Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 28 Oct 2026 14:17:45 -0700 Subject: [PATCH 1/3] Check Python versions in PR and push matrices Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0f98b77b-049b-4c68-953f-648bbde06698 --- build/test_update_python_versions.py | 58 ++++++++++++++++++++++------ build/update_python_versions.py | 16 +++++--- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/build/test_update_python_versions.py b/build/test_update_python_versions.py index fd1e53a..882950b 100644 --- a/build/test_update_python_versions.py +++ b/build/test_update_python_versions.py @@ -41,11 +41,13 @@ def test_latest_release_candidate_rejects_malformed_release_date(release_date): update_python_versions.latest_release_candidate(releases, NOW) -def test_configured_versions(tmp_path): +@pytest.mark.parametrize( + "versions", + ["['3.10', '3.11', '3.12']", "['3.10.9', '3.11-dev', '3.12.0rc1']"], +) +def test_configured_versions(tmp_path, versions): workflow = tmp_path / "pr-check.yml" - workflow.write_text( - "matrix:\n python: ['3.10', '3.11', '3.12']\n", encoding="utf-8" - ) + workflow.write_text(f"matrix:\n python: {versions}\n", encoding="utf-8") assert update_python_versions.configured_versions(workflow) == { "3.10", @@ -63,17 +65,51 @@ def test_configured_versions_requires_one_matrix(tmp_path): @pytest.mark.parametrize( - "matrix, expected", + "pr_version, push_version, expected", [ - ("python: ['3.14']\n", "3.15"), - ("python: ['3.14', '3.15']\n", None), + ("3.14", "3.14", "3.15"), + ("3.15", "3.14", "3.15"), + ("3.14", "3.15", "3.15"), + ("3.15", "3.15", None), + ("3.15.1", "3.15.0-rc.2", None), + ("3.150", "3.15", "3.15"), ], ) -def test_unconfigured_version(tmp_path, matrix, expected): - workflow = tmp_path / "pr-check.yml" - workflow.write_text(matrix, encoding="utf-8") +def test_unconfigured_version(tmp_path, pr_version, push_version, expected): + workflows = [tmp_path / name for name in ("pr-check.yml", "push-check.yml")] + for workflow, version in zip(workflows, (pr_version, push_version)): + workflow.write_text(f"python: ['{version}']\n", encoding="utf-8") releases = [release("Python 3.15.0rc1", "2026-08-01T00:00:00Z")] assert ( - update_python_versions.unconfigured_version(releases, workflow, NOW) == expected + update_python_versions.unconfigured_version(releases, workflows, NOW) + == expected ) + + +@pytest.mark.parametrize( + "push_version, expected", [("3.14", "3.15\n"), ("3.15-dev", "")] +) +def test_main_checks_both_matrices( + tmp_path, monkeypatch, capsys, push_version, expected +): + workflow_dir = tmp_path / ".github" / "workflows" + workflow_dir.mkdir(parents=True) + (workflow_dir / "pr-check.yml").write_text("python: ['3.15.1']\n", encoding="utf-8") + (workflow_dir / "push-check.yml").write_text( + f"python: ['{push_version}']\n", encoding="utf-8" + ) + monkeypatch.setattr( + update_python_versions, + "__file__", + str(tmp_path / "build" / "update_python_versions.py"), + ) + monkeypatch.setattr( + update_python_versions, + "fetch_releases", + lambda: [release("Python 3.15.0rc1", "2020-08-01T00:00:00Z")], + ) + + update_python_versions.main() + + assert capsys.readouterr().out == expected diff --git a/build/update_python_versions.py b/build/update_python_versions.py index 6f7622a..54fd665 100644 --- a/build/update_python_versions.py +++ b/build/update_python_versions.py @@ -69,21 +69,25 @@ def configured_versions(workflow): matches = VERSION_MATRIX.findall(workflow.read_text(encoding="utf-8")) if len(matches) != 1: raise RuntimeError(f"Expected one Python version matrix in {workflow}") - versions = set(re.findall(r"['\"](3\.\d+)['\"]", matches[0])) + versions = set(re.findall(r"['\"](\d+\.\d+)[^'\"]*['\"]", matches[0])) if not versions: raise RuntimeError(f"No Python versions found in {workflow}") return versions -def unconfigured_version(releases, workflow, now=None): - """Return the newest RC series when it is missing from the test matrix.""" +def unconfigured_version(releases, workflows, now=None): + """Return the newest RC series when it is missing from either test matrix.""" latest = latest_release_candidate(releases, now) - return latest if latest not in configured_versions(workflow) else None + for workflow in workflows: + if latest not in configured_versions(workflow): + return latest + return None def main(): - workflow = pathlib.Path(__file__).parent.parent / ".github/workflows/pr-check.yml" - version = unconfigured_version(fetch_releases(), workflow) + workflow_dir = pathlib.Path(__file__).parent.parent / ".github/workflows" + workflows = [workflow_dir / name for name in ("pr-check.yml", "push-check.yml")] + version = unconfigured_version(fetch_releases(), workflows) if version: print(version) From 8ac1285660811bc7a56ecfa33a0e7fa85ffd2efd Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 28 Oct 2026 14:23:24 -0700 Subject: [PATCH 2/3] Label Python version update issues Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0f98b77b-049b-4c68-953f-648bbde06698 --- .github/workflows/check-python-versions.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-python-versions.yml b/.github/workflows/check-python-versions.yml index 9b56838..a8aaa3b 100644 --- a/.github/workflows/check-python-versions.yml +++ b/.github/workflows/check-python-versions.yml @@ -46,5 +46,6 @@ jobs: gh issue create \ --title "$title" \ --label debt \ + --label python-version \ --body "Python $VERSION has a published release candidate according to the [Python.org downloads API](https://www.python.org/api/v2/downloads/release/?is_published=true&pre_release=true&version=3). Update the supported Python versions in this repository." fi From 06585b0004fdabb953a662411e85948cf0490e7c Mon Sep 17 00:00:00 2001 From: Eduardo Villalpando Mello Date: Wed, 28 Oct 2026 14:32:15 -0700 Subject: [PATCH 3/3] Clarify Python version update issue instructions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0f98b77b-049b-4c68-953f-648bbde06698 --- .github/workflows/check-python-versions.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-python-versions.yml b/.github/workflows/check-python-versions.yml index a8aaa3b..52fc5a1 100644 --- a/.github/workflows/check-python-versions.yml +++ b/.github/workflows/check-python-versions.yml @@ -47,5 +47,14 @@ jobs: --title "$title" \ --label debt \ --label python-version \ - --body "Python $VERSION has a published release candidate according to the [Python.org downloads API](https://www.python.org/api/v2/downloads/release/?is_published=true&pre_release=true&version=3). Update the supported Python versions in this repository." + --body "Python $VERSION has a published release candidate according to the [Python.org downloads API](https://www.python.org/api/v2/downloads/release/?is_published=true&pre_release=true&version=3), but is missing from at least one CI test matrix. + + ### Requested changes + - [ ] Ensure the \`python\` matrix in \`.github/workflows/pr-check.yml\` includes Python $VERSION. + - [ ] Ensure the \`python\` matrix in \`.github/workflows/push-check.yml\` includes Python $VERSION. + - [ ] Run the tests on Python $VERSION and resolve any compatibility failures. + + Compare matrix entries by major.minor; patch and prerelease/dev variants of $VERSION already count as coverage. Add the version only where missing and preserve existing entries. + + Keep minimum-supported-version and build-runtime Python pins unchanged; adding CI coverage does not require raising the minimum supported Python version." fi