From dc13eb4f93986767ede38c4885302466dae431e3 Mon Sep 17 00:00:00 2001 From: Alexander Lanin Date: Tue, 29 Sep 2026 23:24:49 +0200 Subject: [PATCH 1/5] fix: resolve known-good versions to verified commits --- .../collector/reference_integration.py | 8 ++++- tests/test_repo_overview.py | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/generate_repo_overview/collector/reference_integration.py b/src/generate_repo_overview/collector/reference_integration.py index 5be5b86..6e00ef8 100644 --- a/src/generate_repo_overview/collector/reference_integration.py +++ b/src/generate_repo_overview/collector/reference_integration.py @@ -217,9 +217,15 @@ def resolve_reference_integration_pin( for version_ref in version_refs: try: commit = get_commit(version_ref) + # The collector uses PyGithub's lazy mode. An incomplete + # Commit can expose the requested ref as ``sha`` before + # GitHub has confirmed that the ref exists. + complete = getattr(commit, "complete", None) + if callable(complete): + complete() + resolved_sha = getattr(commit, "sha", None) except Exception: continue - resolved_sha = getattr(commit, "sha", None) if isinstance(resolved_sha, str) and resolved_sha: pin_ref = resolved_sha break diff --git a/tests/test_repo_overview.py b/tests/test_repo_overview.py index eda87b5..cda455f 100644 --- a/tests/test_repo_overview.py +++ b/tests/test_repo_overview.py @@ -1154,6 +1154,39 @@ def test_known_good_pin_parser_ignores_malformed_json() -> None: ) +def test_resolve_known_good_version_verifies_lazy_commit_before_accepting_sha() -> None: + commit_sha = "0123456789abcdef0123456789abcdef01234567" + commit_refs: list[str] = [] + + class LazyCommit: + def __init__(self, ref: str) -> None: + self.sha = ref + + def complete(self) -> None: + if self.sha == "8.3.0": + raise LookupError("No Git ref named 8.3.0") + self.sha = commit_sha + + class Repository: + def get_commit(self, ref: str) -> LazyCommit: + commit_refs.append(ref) + return LazyCommit(ref) + + pin = reference_integration.KnownGoodPin( + module="score_docs_as_code", + group="Core", + branch="main", + version="8.3.0", + commit_hash=None, + ) + + assert ( + reference_integration.resolve_reference_integration_pin(Repository(), pin) + == commit_sha + ) + assert commit_refs == ["8.3.0", "v8.3.0"] + + def test_latest_release_details_keep_divergence_from_single_comparison( monkeypatch: pytest.MonkeyPatch, ) -> None: From c19282e89db9aafe90418f6ab416602b124d809a Mon Sep 17 00:00:00 2001 From: Alexander Lanin Date: Wed, 30 Sep 2026 10:01:04 +0200 Subject: [PATCH 2/5] refactor: require lazy commit verification --- src/generate_repo_overview/collector/reference_integration.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/generate_repo_overview/collector/reference_integration.py b/src/generate_repo_overview/collector/reference_integration.py index 6e00ef8..b6549cd 100644 --- a/src/generate_repo_overview/collector/reference_integration.py +++ b/src/generate_repo_overview/collector/reference_integration.py @@ -220,9 +220,7 @@ def resolve_reference_integration_pin( # The collector uses PyGithub's lazy mode. An incomplete # Commit can expose the requested ref as ``sha`` before # GitHub has confirmed that the ref exists. - complete = getattr(commit, "complete", None) - if callable(complete): - complete() + commit.complete() resolved_sha = getattr(commit, "sha", None) except Exception: continue From a847d92c1e1d6e6c8c799cc5173d266901e32e39 Mon Sep 17 00:00:00 2001 From: Alexander Lanin Date: Wed, 30 Sep 2026 10:07:32 +0200 Subject: [PATCH 3/5] test: clarify lazy version pin fallback case --- tests/test_repo_overview.py | 45 ++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/tests/test_repo_overview.py b/tests/test_repo_overview.py index cda455f..d9475f5 100644 --- a/tests/test_repo_overview.py +++ b/tests/test_repo_overview.py @@ -1154,37 +1154,50 @@ def test_known_good_pin_parser_ignores_malformed_json() -> None: ) -def test_resolve_known_good_version_verifies_lazy_commit_before_accepting_sha() -> None: - commit_sha = "0123456789abcdef0123456789abcdef01234567" - commit_refs: list[str] = [] +def test_version_pin_retries_v_prefixed_tag_after_plain_version_is_rejected() -> None: + """Resolve a module version through a real tag before comparing Git commits. + + ``known_good.json`` stores ``8.3.0``, while this repository's Git tag is + ``v8.3.0``. PyGithub's lazy commit initially echoes either requested ref as + ``sha``; completion must reject the plain version and return the tag's real + commit SHA before the resolver accepts it. + """ + module_version = "8.3.0" + github_tag = "v8.3.0" + verified_commit_sha = "0123456789abcdef0123456789abcdef01234567" + attempted_refs: list[str] = [] class LazyCommit: - def __init__(self, ref: str) -> None: - self.sha = ref + """Mirror PyGithub: before completion, sha still echoes the requested ref.""" + + def __init__(self, requested_ref: str) -> None: + self.sha = requested_ref def complete(self) -> None: - if self.sha == "8.3.0": - raise LookupError("No Git ref named 8.3.0") - self.sha = commit_sha + if self.sha != github_tag: + raise LookupError(f"No Git ref named {self.sha}") + self.sha = verified_commit_sha class Repository: - def get_commit(self, ref: str) -> LazyCommit: - commit_refs.append(ref) - return LazyCommit(ref) + def get_commit(self, requested_ref: str) -> LazyCommit: + attempted_refs.append(requested_ref) + return LazyCommit(requested_ref) - pin = reference_integration.KnownGoodPin( + version_pin = reference_integration.KnownGoodPin( module="score_docs_as_code", group="Core", branch="main", - version="8.3.0", + version=module_version, commit_hash=None, ) assert ( - reference_integration.resolve_reference_integration_pin(Repository(), pin) - == commit_sha + reference_integration.resolve_reference_integration_pin( + Repository(), version_pin + ) + == verified_commit_sha ) - assert commit_refs == ["8.3.0", "v8.3.0"] + assert attempted_refs == [module_version, github_tag] def test_latest_release_details_keep_divergence_from_single_comparison( From bed96d92c18490fa2250ecdc561453d44e698ef3 Mon Sep 17 00:00:00 2001 From: Alexander Lanin Date: Wed, 30 Sep 2026 10:11:41 +0200 Subject: [PATCH 4/5] fix: type verified lazy commit interface --- .../collector/reference_integration.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/generate_repo_overview/collector/reference_integration.py b/src/generate_repo_overview/collector/reference_integration.py index b6549cd..f6423a4 100644 --- a/src/generate_repo_overview/collector/reference_integration.py +++ b/src/generate_repo_overview/collector/reference_integration.py @@ -4,7 +4,7 @@ import re from dataclasses import dataclass from pathlib import Path -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING, Protocol, cast from urllib.parse import urlsplit from repo_cache import default_cache_directory @@ -42,6 +42,14 @@ class GitRefComparison: left_ahead_by: int +class _CompletableCommit(Protocol): + """Minimal PyGithub commit interface needed to validate a lazy ref.""" + + sha: str + + def complete(self) -> object: ... + + def fetch_reference_integration_repository_names( *, reference_integration_repository: object | None, @@ -216,12 +224,12 @@ def resolve_reference_integration_pin( version_refs.append(f"v{pin.version}") for version_ref in version_refs: try: - commit = get_commit(version_ref) + commit = cast(_CompletableCommit, get_commit(version_ref)) # The collector uses PyGithub's lazy mode. An incomplete # Commit can expose the requested ref as ``sha`` before # GitHub has confirmed that the ref exists. commit.complete() - resolved_sha = getattr(commit, "sha", None) + resolved_sha = commit.sha except Exception: continue if isinstance(resolved_sha, str) and resolved_sha: From f20a5aa64a761cca3e460081fed994f816fde84c Mon Sep 17 00:00:00 2001 From: Alexander Lanin Date: Wed, 30 Sep 2026 10:14:00 +0200 Subject: [PATCH 5/5] style: quote protocol type in cast --- src/generate_repo_overview/collector/reference_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generate_repo_overview/collector/reference_integration.py b/src/generate_repo_overview/collector/reference_integration.py index f6423a4..9a3e45b 100644 --- a/src/generate_repo_overview/collector/reference_integration.py +++ b/src/generate_repo_overview/collector/reference_integration.py @@ -224,7 +224,7 @@ def resolve_reference_integration_pin( version_refs.append(f"v{pin.version}") for version_ref in version_refs: try: - commit = cast(_CompletableCommit, get_commit(version_ref)) + commit = cast("_CompletableCommit", get_commit(version_ref)) # The collector uses PyGithub's lazy mode. An incomplete # Commit can expose the requested ref as ``sha`` before # GitHub has confirmed that the ref exists.