mirror of
https://github.com/astral-sh/setup-uv.git
synced 2026-10-25 00:37:44 +00:00
Add python-arch support (#1079)
Windows ARM64 jobs may need x64 Python independently of their Python version pin. Add `python-arch` to export `UV_PYTHON_ARCH` for subsequent steps and include the selected architecture in the uv and managed-Python cache keys. The input takes precedence over an inherited environment value, and unsupported uv versions fail before environment creation. Requires a uv release with `UV_PYTHON_ARCH` support.
This commit is contained in:
1 parent
c84232ca4f
commit
b06acff4b6
15 files changed
+431
-15
No files matched your search
@@ -0,0 +1,75 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import * as core from "@actions/core";
|
||||
import * as log from "./logging";
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
const PROBE_ARCH = "setup-uv-probe";
|
||||
|
||||
export async function setupPythonArch(
|
||||
uvPath: string,
|
||||
pythonArch: string,
|
||||
exportPythonArch: boolean,
|
||||
): Promise<void> {
|
||||
if (pythonArch === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Older uv releases ignore unknown environment variables. An invalid architecture
|
||||
// confirms that uv recognizes UV_PYTHON_ARCH without finding or downloading Python.
|
||||
const probe = await queryPythonArch(uvPath, PROBE_ARCH);
|
||||
if (probe.exitCode === 0) {
|
||||
throw new Error(
|
||||
"The installed version of uv does not support UV_PYTHON_ARCH. Select a newer uv version or use an architecture-qualified python-version.",
|
||||
);
|
||||
}
|
||||
if (
|
||||
!probe.stderr.includes(
|
||||
`environment variable \`UV_PYTHON_ARCH\` with invalid value \`${PROBE_ARCH}\``,
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`Failed to check uv's support for UV_PYTHON_ARCH: ${probe.stderr.trim() || `uv exited with code ${probe.exitCode}`}`,
|
||||
);
|
||||
}
|
||||
|
||||
const selected = await queryPythonArch(uvPath, pythonArch);
|
||||
if (selected.exitCode !== 0) {
|
||||
throw new Error(
|
||||
`Failed to set Python architecture to ${pythonArch}: ${selected.stderr.trim() || `uv exited with code ${selected.exitCode}`}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (exportPythonArch) {
|
||||
core.exportVariable("UV_PYTHON_ARCH", pythonArch);
|
||||
log.info(`Set UV_PYTHON_ARCH to ${pythonArch}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function queryPythonArch(
|
||||
uvPath: string,
|
||||
pythonArch: string,
|
||||
): Promise<{ exitCode: number; stderr: string }> {
|
||||
try {
|
||||
const { stderr } = await execFileAsync(
|
||||
uvPath,
|
||||
["--no-config", "cache", "dir"],
|
||||
{
|
||||
encoding: "utf8",
|
||||
env: { ...process.env, NO_COLOR: "1", UV_PYTHON_ARCH: pythonArch },
|
||||
},
|
||||
);
|
||||
return { exitCode: 0, stderr };
|
||||
} catch (error) {
|
||||
if (
|
||||
error instanceof Error &&
|
||||
"code" in error &&
|
||||
typeof error.code === "number" &&
|
||||
"stderr" in error &&
|
||||
typeof error.stderr === "string"
|
||||
) {
|
||||
return { exitCode: error.code, stderr: error.stderr };
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user