feat: fall back to system Python when pre-built binaries unavailable

When pre-built Python binaries are not available for the current
architecture (e.g., riscv64), try using system Python as a fallback
instead of failing with an error.

This enables setup-python to work on architectures that don't yet
have pre-built binaries in actions/python-versions, such as riscv64
self-hosted runners. The fallback only activates when:
1. No cached version is found
2. No manifest entry exists for the architecture
3. System python3 exists and satisfies the requested version spec

A warning is emitted so users know the fallback was used.

Fixes #1288

Signed-off-by: Bruno Verachten <gounthar@gmail.com>
This commit is contained in:
Bruno Verachten 2026-03-18 15:48:13 +01:00
parent 28f2168f4d
commit 156786c425
No known key found for this signature in database
GPG key ID: E7EAD7209D3ECCD3
2 changed files with 52 additions and 0 deletions

24
dist/setup/index.js vendored
View file

@ -82997,6 +82997,30 @@ async function useCpythonVersion(version, architecture, updateEnvironment, check
installDir = tc.find('Python', semanticVersionSpec, architecture);
}
}
if (!installDir) {
// Try system Python as fallback (e.g., on architectures without pre-built binaries)
try {
const { exitCode, stdout } = await exec.getExecOutput('python3', [
'-c',
'import sys; print(sys.prefix)'
]);
if (exitCode === 0) {
const systemPrefix = stdout.trim();
const systemVersion = await exec.getExecOutput('python3', [
'-c',
'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")'
]);
if (systemVersion.exitCode === 0 &&
semver.satisfies(systemVersion.stdout.trim(), semanticVersionSpec)) {
installDir = systemPrefix;
core.warning(`Pre-built Python not available for architecture '${architecture}'. Using system Python ${systemVersion.stdout.trim()} at ${systemPrefix}.`);
}
}
}
catch {
// System Python not available, fall through to error
}
}
if (!installDir) {
const osInfo = await (0, utils_1.getOSInfo)();
const msg = [