Add value of UV_PYTHON_INSTALL_DIR to path (#628)

Closes: #610
This commit is contained in:
Kevin Stillhammer
2025-10-11 18:42:06 +02:00
committed by GitHub
parent bd1f875aba
commit d18bcc753a
7 changed files with 112 additions and 49 deletions

View File

@@ -852,7 +852,7 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Verify Python install dir is not populated - name: Verify Python install dir is not populated
run: | run: |
if [ -d ~/.local/share/uv/python ]; then if [ -d /home/runner/work/_temp/uv-python-dir ]; then
echo "Python install dir should not exist" echo "Python install dir should not exist"
exit 1 exit 1
fi fi
@@ -866,7 +866,7 @@ jobs:
working-directory: __tests__/fixtures/uv-project working-directory: __tests__/fixtures/uv-project
- name: Verify Python install dir exists - name: Verify Python install dir exists
run: | run: |
if [ ! -d ~/.local/share/uv/python ]; then if [ ! -d /home/runner/work/_temp/uv-python-dir ]; then
echo "Python install dir should exist" echo "Python install dir should exist"
exit 1 exit 1
fi fi
@@ -879,7 +879,7 @@ jobs:
persist-credentials: false persist-credentials: false
- name: Verify Python install dir does not exist - name: Verify Python install dir does not exist
run: | run: |
if [ -d ~/.local/share/uv/python ]; then if [ -d /home/runner/work/_temp/uv-python-dir ]; then
echo "Python install dir should not exist" echo "Python install dir should not exist"
exit 1 exit 1
fi fi
@@ -892,7 +892,7 @@ jobs:
cache-suffix: ${{ github.run_id }}-${{ github.run_attempt }}-test-cache-python-installs cache-suffix: ${{ github.run_id }}-${{ github.run_attempt }}-test-cache-python-installs
- name: Verify Python install dir exists - name: Verify Python install dir exists
run: | run: |
if [ ! -d ~/.local/share/uv/python ]; then if [ ! -d /home/runner/work/_temp/uv-python-dir ]; then
echo "Python install dir should exist" echo "Python install dir should exist"
exit 1 exit 1
fi fi
@@ -906,6 +906,34 @@ jobs:
- run: uv sync --managed-python - run: uv sync --managed-python
working-directory: __tests__/fixtures/uv-project working-directory: __tests__/fixtures/uv-project
test-python-install-dir:
strategy:
matrix:
inputs:
- os: ubuntu-latest
expected-python-dir: "/home/runner/work/_temp/uv-python-dir"
- os: windows-latest
expected-python-dir: "D:\\a\\_temp\\uv-python-dir"
- os: selfhosted-ubuntu-arm64
expected-python-dir: "/home/ubuntu/.local/share/uv/python"
runs-on: ${{ matrix.inputs.os }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install latest version
id: setup-uv
uses: ./
- name: Check Python dir is expected dir
run: |
if [ "$UV_PYTHON_INSTALL_DIR" != "${{ matrix.inputs.expected-python-dir }}" ]; then
echo "Wrong UV_PYTHON_INSTALL_DIR: UV_PYTHON_INSTALL_DIR"
exit 1
fi
shell: bash
- name: Install python works
run: uv python install
all-tests-passed: all-tests-passed:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: needs:
@@ -950,6 +978,7 @@ jobs:
- test-cache-dir-from-file - test-cache-dir-from-file
- test-cache-python-installs - test-cache-python-installs
- test-restore-python-installs - test-restore-python-installs
- test-python-install-dir
if: always() if: always()
steps: steps:
- name: All tests passed - name: All tests passed

37
dist/save-cache/index.js generated vendored
View File

@@ -90595,7 +90595,7 @@ async function restoreCache() {
core.info(`Trying to restore uv cache from GitHub Actions cache with key: ${cacheKey}`); core.info(`Trying to restore uv cache from GitHub Actions cache with key: ${cacheKey}`);
const cachePaths = [inputs_1.cacheLocalPath]; const cachePaths = [inputs_1.cacheLocalPath];
if (inputs_1.cachePython) { if (inputs_1.cachePython) {
cachePaths.push(await (0, inputs_1.getUvPythonDir)()); cachePaths.push(inputs_1.pythonDir);
} }
try { try {
matchedKey = await cache.restoreCache(cachePaths, cacheKey); matchedKey = await cache.restoreCache(cachePaths, cacheKey);
@@ -90851,12 +90851,11 @@ async function saveCache() {
} }
const cachePaths = [actualCachePath]; const cachePaths = [actualCachePath];
if (inputs_1.cachePython) { if (inputs_1.cachePython) {
const pythonDir = await (0, inputs_1.getUvPythonDir)(); core.info(`Including Python cache path: ${inputs_1.pythonDir}`);
core.info(`Including Python cache path: ${pythonDir}`); if (!fs.existsSync(inputs_1.pythonDir) && !inputs_1.ignoreNothingToCache) {
if (!fs.existsSync(pythonDir) && !inputs_1.ignoreNothingToCache) { throw new Error(`Python cache path ${inputs_1.pythonDir} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`);
throw new Error(`Python cache path ${pythonDir} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`);
} }
cachePaths.push(pythonDir); cachePaths.push(inputs_1.pythonDir);
} }
core.info(`Final cache paths: ${cachePaths.join(", ")}`); core.info(`Final cache paths: ${cachePaths.join(", ")}`);
try { try {
@@ -91011,11 +91010,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0; exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.pythonDir = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0;
exports.getUvPythonDir = getUvPythonDir; exports.getUvPythonDir = getUvPythonDir;
const node_path_1 = __importDefault(__nccwpck_require__(6760)); const node_path_1 = __importDefault(__nccwpck_require__(6760));
const core = __importStar(__nccwpck_require__(7484)); const core = __importStar(__nccwpck_require__(7484));
const exec = __importStar(__nccwpck_require__(5236));
const config_file_1 = __nccwpck_require__(5465); const config_file_1 = __nccwpck_require__(5465);
exports.workingDirectory = core.getInput("working-directory"); exports.workingDirectory = core.getInput("working-directory");
exports.version = core.getInput("version"); exports.version = core.getInput("version");
@@ -91035,6 +91033,7 @@ exports.ignoreNothingToCache = core.getInput("ignore-nothing-to-cache") === "tru
exports.ignoreEmptyWorkdir = core.getInput("ignore-empty-workdir") === "true"; exports.ignoreEmptyWorkdir = core.getInput("ignore-empty-workdir") === "true";
exports.toolBinDir = getToolBinDir(); exports.toolBinDir = getToolBinDir();
exports.toolDir = getToolDir(); exports.toolDir = getToolDir();
exports.pythonDir = getUvPythonDir();
exports.githubToken = core.getInput("github-token"); exports.githubToken = core.getInput("github-token");
exports.manifestFile = getManifestFile(); exports.manifestFile = getManifestFile();
exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true"; exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true";
@@ -91124,19 +91123,23 @@ function getCacheDirFromConfig() {
} }
return undefined; return undefined;
} }
async function getUvPythonDir() { function getUvPythonDir() {
if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) { if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) {
core.info(`Using UV_PYTHON_INSTALL_DIR from environment: ${process.env.UV_PYTHON_INSTALL_DIR}`); core.info(`UV_PYTHON_INSTALL_DIR is already set to ${process.env.UV_PYTHON_INSTALL_DIR}`);
return process.env.UV_PYTHON_INSTALL_DIR; return process.env.UV_PYTHON_INSTALL_DIR;
} }
core.info("Determining uv python dir using `uv python dir`..."); if (process.env.RUNNER_ENVIRONMENT !== "github-hosted") {
const result = await exec.getExecOutput("uv", ["python", "dir"]); if (process.platform === "win32") {
if (result.exitCode !== 0) { return `${process.env.APPDATA}${node_path_1.default.sep}uv${node_path_1.default.sep}python`;
throw new Error(`Failed to get uv python dir: ${result.stderr || result.stdout}`); }
else {
return `${process.env.HOME}${node_path_1.default.sep}.local${node_path_1.default.sep}share${node_path_1.default.sep}uv${node_path_1.default.sep}python`;
}
} }
const dir = result.stdout.trim(); if (process.env.RUNNER_TEMP !== undefined) {
core.info(`Determined uv python dir: ${dir}`); return `${process.env.RUNNER_TEMP}${node_path_1.default.sep}uv-python-dir`;
return dir; }
throw Error("Could not determine UV_PYTHON_INSTALL_DIR. Please make sure RUNNER_TEMP is set or provide the UV_PYTHON_INSTALL_DIR environment variable");
} }
function getCacheDependencyGlob() { function getCacheDependencyGlob() {
const cacheDependencyGlobInput = core.getInput("cache-dependency-glob"); const cacheDependencyGlobInput = core.getInput("cache-dependency-glob");

40
dist/setup/index.js generated vendored
View File

@@ -125153,7 +125153,7 @@ async function restoreCache() {
core.info(`Trying to restore uv cache from GitHub Actions cache with key: ${cacheKey}`); core.info(`Trying to restore uv cache from GitHub Actions cache with key: ${cacheKey}`);
const cachePaths = [inputs_1.cacheLocalPath]; const cachePaths = [inputs_1.cacheLocalPath];
if (inputs_1.cachePython) { if (inputs_1.cachePython) {
cachePaths.push(await (0, inputs_1.getUvPythonDir)()); cachePaths.push(inputs_1.pythonDir);
} }
try { try {
matchedKey = await cache.restoreCache(cachePaths, cacheKey); matchedKey = await cache.restoreCache(cachePaths, cacheKey);
@@ -129538,6 +129538,7 @@ async function run() {
addToolBinToPath(); addToolBinToPath();
addUvToPathAndOutput(setupResult.uvDir); addUvToPathAndOutput(setupResult.uvDir);
setToolDir(); setToolDir();
addPythonDirToPath();
setupPython(); setupPython();
await activateEnvironment(); await activateEnvironment();
addMatchers(); addMatchers();
@@ -129647,6 +129648,17 @@ function setToolDir() {
core.info(`Set UV_TOOL_DIR to ${inputs_1.toolDir}`); core.info(`Set UV_TOOL_DIR to ${inputs_1.toolDir}`);
} }
} }
function addPythonDirToPath() {
core.exportVariable("UV_PYTHON_INSTALL_DIR", inputs_1.pythonDir);
core.info(`Set UV_PYTHON_INSTALL_DIR to ${inputs_1.pythonDir}`);
if (process.env.UV_NO_MODIFY_PATH !== undefined) {
core.info("UV_NO_MODIFY_PATH is set, not adding python dir to path");
}
else {
core.addPath(inputs_1.pythonDir);
core.info(`Added ${inputs_1.pythonDir} to the path`);
}
}
function setupPython() { function setupPython() {
if (inputs_1.pythonVersion !== "") { if (inputs_1.pythonVersion !== "") {
core.exportVariable("UV_PYTHON", inputs_1.pythonVersion); core.exportVariable("UV_PYTHON", inputs_1.pythonVersion);
@@ -129841,11 +129853,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0; exports.addProblemMatchers = exports.manifestFile = exports.githubToken = exports.pythonDir = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.cachePython = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.saveCache = exports.restoreCache = exports.enableCache = exports.checkSum = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = exports.workingDirectory = void 0;
exports.getUvPythonDir = getUvPythonDir; exports.getUvPythonDir = getUvPythonDir;
const node_path_1 = __importDefault(__nccwpck_require__(76760)); const node_path_1 = __importDefault(__nccwpck_require__(76760));
const core = __importStar(__nccwpck_require__(37484)); const core = __importStar(__nccwpck_require__(37484));
const exec = __importStar(__nccwpck_require__(95236));
const config_file_1 = __nccwpck_require__(27846); const config_file_1 = __nccwpck_require__(27846);
exports.workingDirectory = core.getInput("working-directory"); exports.workingDirectory = core.getInput("working-directory");
exports.version = core.getInput("version"); exports.version = core.getInput("version");
@@ -129865,6 +129876,7 @@ exports.ignoreNothingToCache = core.getInput("ignore-nothing-to-cache") === "tru
exports.ignoreEmptyWorkdir = core.getInput("ignore-empty-workdir") === "true"; exports.ignoreEmptyWorkdir = core.getInput("ignore-empty-workdir") === "true";
exports.toolBinDir = getToolBinDir(); exports.toolBinDir = getToolBinDir();
exports.toolDir = getToolDir(); exports.toolDir = getToolDir();
exports.pythonDir = getUvPythonDir();
exports.githubToken = core.getInput("github-token"); exports.githubToken = core.getInput("github-token");
exports.manifestFile = getManifestFile(); exports.manifestFile = getManifestFile();
exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true"; exports.addProblemMatchers = core.getInput("add-problem-matchers") === "true";
@@ -129954,19 +129966,23 @@ function getCacheDirFromConfig() {
} }
return undefined; return undefined;
} }
async function getUvPythonDir() { function getUvPythonDir() {
if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) { if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) {
core.info(`Using UV_PYTHON_INSTALL_DIR from environment: ${process.env.UV_PYTHON_INSTALL_DIR}`); core.info(`UV_PYTHON_INSTALL_DIR is already set to ${process.env.UV_PYTHON_INSTALL_DIR}`);
return process.env.UV_PYTHON_INSTALL_DIR; return process.env.UV_PYTHON_INSTALL_DIR;
} }
core.info("Determining uv python dir using `uv python dir`..."); if (process.env.RUNNER_ENVIRONMENT !== "github-hosted") {
const result = await exec.getExecOutput("uv", ["python", "dir"]); if (process.platform === "win32") {
if (result.exitCode !== 0) { return `${process.env.APPDATA}${node_path_1.default.sep}uv${node_path_1.default.sep}python`;
throw new Error(`Failed to get uv python dir: ${result.stderr || result.stdout}`); }
else {
return `${process.env.HOME}${node_path_1.default.sep}.local${node_path_1.default.sep}share${node_path_1.default.sep}uv${node_path_1.default.sep}python`;
}
} }
const dir = result.stdout.trim(); if (process.env.RUNNER_TEMP !== undefined) {
core.info(`Determined uv python dir: ${dir}`); return `${process.env.RUNNER_TEMP}${node_path_1.default.sep}uv-python-dir`;
return dir; }
throw Error("Could not determine UV_PYTHON_INSTALL_DIR. Please make sure RUNNER_TEMP is set or provide the UV_PYTHON_INSTALL_DIR environment variable");
} }
function getCacheDependencyGlob() { function getCacheDependencyGlob() {
const cacheDependencyGlobInput = core.getInput("cache-dependency-glob"); const cacheDependencyGlobInput = core.getInput("cache-dependency-glob");

View File

@@ -7,8 +7,8 @@ import {
cacheLocalPath, cacheLocalPath,
cachePython, cachePython,
cacheSuffix, cacheSuffix,
getUvPythonDir,
pruneCache, pruneCache,
pythonDir,
pythonVersion as pythonVersionInput, pythonVersion as pythonVersionInput,
restoreCache as shouldRestoreCache, restoreCache as shouldRestoreCache,
workingDirectory, workingDirectory,
@@ -34,7 +34,7 @@ export async function restoreCache(): Promise<void> {
); );
const cachePaths = [cacheLocalPath]; const cachePaths = [cacheLocalPath];
if (cachePython) { if (cachePython) {
cachePaths.push(await getUvPythonDir()); cachePaths.push(pythonDir);
} }
try { try {
matchedKey = await cache.restoreCache(cachePaths, cacheKey); matchedKey = await cache.restoreCache(cachePaths, cacheKey);

View File

@@ -12,8 +12,8 @@ import {
cacheLocalPath, cacheLocalPath,
cachePython, cachePython,
enableCache, enableCache,
getUvPythonDir,
ignoreNothingToCache, ignoreNothingToCache,
pythonDir,
pruneCache as shouldPruneCache, pruneCache as shouldPruneCache,
saveCache as shouldSaveCache, saveCache as shouldSaveCache,
} from "./utils/inputs"; } from "./utils/inputs";
@@ -73,7 +73,6 @@ async function saveCache(): Promise<void> {
const cachePaths = [actualCachePath]; const cachePaths = [actualCachePath];
if (cachePython) { if (cachePython) {
const pythonDir = await getUvPythonDir();
core.info(`Including Python cache path: ${pythonDir}`); core.info(`Including Python cache path: ${pythonDir}`);
if (!fs.existsSync(pythonDir) && !ignoreNothingToCache) { if (!fs.existsSync(pythonDir) && !ignoreNothingToCache) {
throw new Error( throw new Error(

View File

@@ -19,6 +19,7 @@ import {
githubToken, githubToken,
ignoreEmptyWorkdir, ignoreEmptyWorkdir,
manifestFile, manifestFile,
pythonDir,
pythonVersion, pythonVersion,
toolBinDir, toolBinDir,
toolDir, toolDir,
@@ -51,6 +52,7 @@ async function run(): Promise<void> {
addToolBinToPath(); addToolBinToPath();
addUvToPathAndOutput(setupResult.uvDir); addUvToPathAndOutput(setupResult.uvDir);
setToolDir(); setToolDir();
addPythonDirToPath();
setupPython(); setupPython();
await activateEnvironment(); await activateEnvironment();
addMatchers(); addMatchers();
@@ -194,6 +196,17 @@ function setToolDir(): void {
} }
} }
function addPythonDirToPath(): void {
core.exportVariable("UV_PYTHON_INSTALL_DIR", pythonDir);
core.info(`Set UV_PYTHON_INSTALL_DIR to ${pythonDir}`);
if (process.env.UV_NO_MODIFY_PATH !== undefined) {
core.info("UV_NO_MODIFY_PATH is set, not adding python dir to path");
} else {
core.addPath(pythonDir);
core.info(`Added ${pythonDir} to the path`);
}
}
function setupPython(): void { function setupPython(): void {
if (pythonVersion !== "") { if (pythonVersion !== "") {
core.exportVariable("UV_PYTHON", pythonVersion); core.exportVariable("UV_PYTHON", pythonVersion);

View File

@@ -1,6 +1,5 @@
import path from "node:path"; import path from "node:path";
import * as core from "@actions/core"; import * as core from "@actions/core";
import * as exec from "@actions/exec";
import { getConfigValueFromTomlFile } from "./config-file"; import { getConfigValueFromTomlFile } from "./config-file";
export const workingDirectory = core.getInput("working-directory"); export const workingDirectory = core.getInput("working-directory");
@@ -23,6 +22,7 @@ export const ignoreEmptyWorkdir =
core.getInput("ignore-empty-workdir") === "true"; core.getInput("ignore-empty-workdir") === "true";
export const toolBinDir = getToolBinDir(); export const toolBinDir = getToolBinDir();
export const toolDir = getToolDir(); export const toolDir = getToolDir();
export const pythonDir = getUvPythonDir();
export const githubToken = core.getInput("github-token"); export const githubToken = core.getInput("github-token");
export const manifestFile = getManifestFile(); export const manifestFile = getManifestFile();
export const addProblemMatchers = export const addProblemMatchers =
@@ -125,23 +125,26 @@ function getCacheDirFromConfig(): string | undefined {
return undefined; return undefined;
} }
export async function getUvPythonDir(): Promise<string> { export function getUvPythonDir(): string {
if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) { if (process.env.UV_PYTHON_INSTALL_DIR !== undefined) {
core.info( core.info(
`Using UV_PYTHON_INSTALL_DIR from environment: ${process.env.UV_PYTHON_INSTALL_DIR}`, `UV_PYTHON_INSTALL_DIR is already set to ${process.env.UV_PYTHON_INSTALL_DIR}`,
); );
return process.env.UV_PYTHON_INSTALL_DIR; return process.env.UV_PYTHON_INSTALL_DIR;
} }
core.info("Determining uv python dir using `uv python dir`..."); if (process.env.RUNNER_ENVIRONMENT !== "github-hosted") {
const result = await exec.getExecOutput("uv", ["python", "dir"]); if (process.platform === "win32") {
if (result.exitCode !== 0) { return `${process.env.APPDATA}${path.sep}uv${path.sep}python`;
throw new Error( } else {
`Failed to get uv python dir: ${result.stderr || result.stdout}`, return `${process.env.HOME}${path.sep}.local${path.sep}share${path.sep}uv${path.sep}python`;
); }
} }
const dir = result.stdout.trim(); if (process.env.RUNNER_TEMP !== undefined) {
core.info(`Determined uv python dir: ${dir}`); return `${process.env.RUNNER_TEMP}${path.sep}uv-python-dir`;
return dir; }
throw Error(
"Could not determine UV_PYTHON_INSTALL_DIR. Please make sure RUNNER_TEMP is set or provide the UV_PYTHON_INSTALL_DIR environment variable",
);
} }
function getCacheDependencyGlob(): string { function getCacheDependencyGlob(): string {