From 84fcb4a6dc0009b9140fb6dc042bf8b2dc008314 Mon Sep 17 00:00:00 2001 From: Bruce Ashfield Date: Sat, 30 May 2026 04:22:21 +0000 Subject: oe-go-mod-fetcher: fix stale clone cache in pseudo-version expansion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolve_pseudo_version_commit() expands a 12-character pseudo-version short hash to its full 40-character form by cloning the upstream repo into a cache directory and running 'git log --since=...'. The cache is reused on subsequent invocations and refreshed via 'git fetch --all'. The initial clone used 'git clone --bare', which does NOT install a remote.origin.fetch refspec. As a result, the later 'git fetch --all' exits 0 but actually fetches nothing — the cache stays frozen at the state of the very first clone, no matter how much time passes. For any pseudo-version whose timestamp is newer than the first time the cache was populated, the 'git log --since=' search returns no commits, expansion silently returns None, and the 12-char hash propagates verbatim into the generated SRC_URI .inc files. bitbake then refuses to parse the recipe with an unhelpful "Unable to resolve '<12 chars>' in upstream git repository in git ls-remote output for " error, because its git fetcher requires a full 40-char SHA. Hit on a nerdctl v2.2.1 -> v2.3.1-tip bump: the repo's self-reference module 'github.com/containerd/nerdctl/v2' at pseudo-version v2.0.0-20260528082953-89ecd85071c4 (timestamped 2026-05-28) failed to expand because the cached clone of github.com/containerd/nerdctl was created on 2026-03-19 and never advanced. Two changes: - clone with --mirror instead of --bare. --mirror sets up the +refs/*:refs/* refspec, so 'git fetch --all' actually pulls new refs on every subsequent run. - print a non-VERBOSE warning when expansion leaves any 12-char hash unresolved, listing the affected modules and pointing at the cache directory. The previous failure message was gated behind VERBOSE_MODE, so an exhausted cache produced a silent fall-through and the next visible error was bitbake's confusing parse failure. Signed-off-by: Bruce Ashfield --- scripts/oe-go-mod-fetcher.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/oe-go-mod-fetcher.py b/scripts/oe-go-mod-fetcher.py index 74459204..c17582b8 100755 --- a/scripts/oe-go-mod-fetcher.py +++ b/scripts/oe-go-mod-fetcher.py @@ -2754,13 +2754,19 @@ def resolve_pseudo_version_commit(vcs_url: str, timestamp_str: str, short_commit # Fetch failed, try to use existing clone anyway pass else: - # Clone repository (bare clone for efficiency) + # Clone repository as a mirror so `git fetch --all` can later + # refresh refs. A plain `git clone --bare` does NOT install a + # remote.origin.fetch refspec, so subsequent `git fetch --all` + # exits 0 but updates nothing — the cache stays frozen at the + # initial clone, and pseudo-version expansion silently fails + # for any commit newer than the first clone time. --mirror + # sets up the refspec `+refs/*:refs/*` so fetches stay current. if clone_dir.exists(): shutil.rmtree(clone_dir) clone_dir.mkdir(parents=True, exist_ok=True) subprocess.run( - ['git', 'clone', '--bare', '--quiet', try_url, str(clone_dir)], + ['git', 'clone', '--mirror', '--quiet', try_url, str(clone_dir)], capture_output=True, check=True, timeout=300, # 5 minute timeout @@ -4419,6 +4425,22 @@ def load_discovered_modules(discovered_modules_path: Path) -> Optional[List[Dict print(f" Expanded {expanded} short hashes, {failed} failed ") + # A 12-char vcs_hash left in any module will trip bitbake's git + # fetcher (sha1_re requires 40 chars) and trigger a confusing + # "Unable to resolve" parse error. Surface this even outside + # VERBOSE_MODE so the user catches it before the build fails. + if failed: + still_short = [m for m in short_hash_modules + if len(m.get('vcs_hash', '')) != 40] + if still_short: + print(f"\n⚠️ {len(still_short)} module(s) still have 12-char hashes after expansion:") + for m in still_short[:10]: + print(f" - {m['module_path']}@{m.get('version', '')} ({m['vcs_hash']})") + if len(still_short) > 10: + print(f" ... and {len(still_short) - 10} more") + print(f" These will cause bitbake parse errors. Common cause: a stale") + print(f" clone_cache_dir entry. Try: rm -rf {CLONE_CACHE_DIR}") + # Filter out modules with empty vcs_hash - these are typically pre-Go 1.18 # modules lacking Origin metadata (e.g. pre-release pseudo-versions) that # cannot be fetched from git. They are usually transitive dependencies that -- cgit v1.2.3-54-g00ecf