Auto-detect installed Python versions at runtime

When no --python-versions is specified at
runtime, auto-detect which Python versions are actually installed in the
container instead of defaulting to all versions from python_versions.json.

This resolves the issue where:
1. Building with --python-versions=3.12 installs only Python 3.12
2. Running without --python-versions would try to test all versions from JSON
3. Tests would fail for non-installed versions (3.8, 3.9, 3.10, 3.11, 3.13)

Now the runtime logic:
1. Uses `pyenv versions --bare` to detect installed versions
2. Maps full versions (3.12.9) to short versions (3.12)
3. Uses detected versions as default for testing
4. Falls back to JSON versions if detection fails

Example behavior:
- Build: --python-versions=3.12 (installs only 3.12.9)
- Runtime: auto-detects 3.12, tests only that version
- Explicit: --python-versions=3.11,3.12 still works as before
This commit is contained in:
Håkon Hægland committed 2025-09-23 11:46:27 +02:00
1 parent 412773785e
commit 85344a3998
1 file changed
+26 -1
@@ -304,7 +304,32 @@ def main():
print(f"Error: Invalid JSON in {version_map_file}: {e}")
sys.exit(1)
default_versions = ",".join(version_map.keys())
# Auto-detect actually installed Python versions instead of using all from JSON
# This allows runtime to use only the versions that were installed during build
try:
result = subprocess.run(["pyenv", "versions", "--bare"],
capture_output=True, text=True, check=True)
installed_versions = []
for line in result.stdout.strip().split('\n'):
if line.strip():
# Extract short version (e.g., "3.12.9" -> "3.12")
full_version = line.strip()
short_version = '.'.join(full_version.split('.')[:2])
if short_version in version_map:
installed_versions.append(short_version)
if installed_versions:
default_versions = ",".join(sorted(set(installed_versions)))
print(f"Auto-detected installed Python versions: {default_versions}")
else:
# Fallback to JSON versions if detection fails
default_versions = ",".join(version_map.keys())
print(f"Could not detect installed versions, using all from JSON: {default_versions}")
except Exception as e:
# Fallback to JSON versions if detection fails
default_versions = ",".join(version_map.keys())
print(f"Could not detect installed versions ({e}), using all from JSON: {default_versions}")
python_versions_env = os.environ.get("PYTHON_VERSIONS", default_versions)
print(f"Running tests.. Requested Python versions: {python_versions_env}")