Add input version-file (#486)

Closes: #411
This commit is contained in:
Kevin Stillhammer
2025-07-17 20:22:18 +02:00
committed by GitHub
parent c893ac1cb2
commit b75ff7d7b8
13 changed files with 369 additions and 136 deletions

View File

@ -155,6 +155,22 @@ jobs:
exit 1
fi
test-version-file-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install from requirements file
id: setup-uv
uses: ./
with:
version-file: "__tests__/fixtures/uv-in-requirements-txt-project/requirements.txt"
- name: Correct version gets installed
run: |
if [ "$(uv --version)" != "uv 0.6.17" ]; then
echo "Wrong uv version: $(uv --version)"
exit 1
fi
test-checksum:
runs-on: ${{ matrix.inputs.os }}
strategy:
@ -561,6 +577,7 @@ jobs:
- test-pyproject-file-version
- test-malformed-pyproject-file-fallback
- test-uv-file-version
- test-version-file-version
- test-checksum
- test-with-explicit-token
- test-uvx

View File

@ -15,6 +15,7 @@ Set up your GitHub Actions workflow with a specific version of [uv](https://docs
- [Install the latest version](#install-the-latest-version)
- [Install a specific version](#install-a-specific-version)
- [Install a version by supplying a semver range or pep440 specifier](#install-a-version-by-supplying-a-semver-range-or-pep440-specifier)
- [Install a version defined in a requirements or config file](#install-a-version-defined-in-a-requirements-or-config-file)
- [Python version](#python-version)
- [Activate environment](#activate-environment)
- [Working directory](#working-directory)
@ -92,6 +93,19 @@ to install the latest version that satisfies the range.
version: ">=0.4.25,<0.5"
```
### Install a version defined in a requirements or config file
You can use the `version-file` input to specify a file that contains the version of uv to install.
This can either be a `pyproject.toml` or `uv.toml` file which defines a `required-version` or
uv defined as a dependency in `pyproject.toml` or `requirements.txt`.
```yaml
- name: Install uv based on the version defined in pyproject.toml
uses: astral-sh/setup-uv@v6
with:
version-file: "pyproject.toml"
```
### Python version
You can use the input `python-version` to set the environment variable `UV_PYTHON` for the rest of your workflow

View File

@ -0,0 +1 @@
print("Hello world")

View File

@ -0,0 +1 @@
uv==0.6.17

View File

@ -6,6 +6,9 @@ inputs:
version:
description: "The version of uv to install e.g., `0.5.0` Defaults to the version in pyproject.toml or 'latest'."
default: ""
version-file:
description: "Path to a file containing the version of uv to install. Defaults to searching for uv.toml and if not found pyproject.toml."
default: ""
python-version:
description: "The version of Python to set UV_PYTHON to"
required: false

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

@ -88998,10 +88998,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.manifestFile = exports.githubToken = exports.serverUrl = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.workingDirectory = exports.activateEnvironment = exports.pythonVersion = exports.version = void 0;
exports.manifestFile = exports.githubToken = exports.serverUrl = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.workingDirectory = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = void 0;
const core = __importStar(__nccwpck_require__(7484));
const node_path_1 = __importDefault(__nccwpck_require__(6760));
exports.version = core.getInput("version");
exports.versionFile = core.getInput("version-file");
exports.pythonVersion = core.getInput("python-version");
exports.activateEnvironment = core.getBooleanInput("activate-environment");
exports.workingDirectory = core.getInput("working-directory");

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

@ -125217,7 +125217,7 @@ const platforms_1 = __nccwpck_require__(98361);
const inputs_1 = __nccwpck_require__(9612);
const exec = __importStar(__nccwpck_require__(95236));
const node_fs_1 = __importDefault(__nccwpck_require__(73024));
const config_file_1 = __nccwpck_require__(27846);
const resolve_1 = __nccwpck_require__(36772);
async function run() {
detectEmptyWorkdir();
const platform = await (0, platforms_1.getPlatform)();
@ -125285,8 +125285,15 @@ async function determineVersion(manifestFile) {
if (inputs_1.version !== "") {
return await (0, download_version_1.resolveVersion)(inputs_1.version, manifestFile, inputs_1.githubToken);
}
const versionFromUvToml = (0, config_file_1.getUvVersionFromConfigFile)(`${inputs_1.workingDirectory}${path.sep}uv.toml`);
const versionFromPyproject = (0, config_file_1.getUvVersionFromConfigFile)(`${inputs_1.workingDirectory}${path.sep}pyproject.toml`);
if (inputs_1.versionFile !== "") {
const versionFromFile = (0, resolve_1.getUvVersionFromFile)(inputs_1.versionFile);
if (versionFromFile === undefined) {
throw new Error(`Could not determine uv version from file: ${inputs_1.versionFile}`);
}
return await (0, download_version_1.resolveVersion)(versionFromFile, manifestFile, inputs_1.githubToken);
}
const versionFromUvToml = (0, resolve_1.getUvVersionFromFile)(`${inputs_1.workingDirectory}${path.sep}uv.toml`);
const versionFromPyproject = (0, resolve_1.getUvVersionFromFile)(`${inputs_1.workingDirectory}${path.sep}pyproject.toml`);
if (versionFromUvToml === undefined && versionFromPyproject === undefined) {
core.info("Could not determine uv version from uv.toml or pyproject.toml. Falling back to latest.");
}
@ -125356,88 +125363,6 @@ function addMatchers() {
run();
/***/ }),
/***/ 27846:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getUvVersionFromConfigFile = getUvVersionFromConfigFile;
const node_fs_1 = __importDefault(__nccwpck_require__(73024));
const core = __importStar(__nccwpck_require__(37484));
const toml = __importStar(__nccwpck_require__(27106));
function getUvVersionFromConfigFile(filePath) {
core.info(`Trying to find required-version for uv in: ${filePath}`);
if (!node_fs_1.default.existsSync(filePath)) {
core.info(`Could not find file: ${filePath}`);
return undefined;
}
let requiredVersion;
try {
requiredVersion = getRequiredVersion(filePath);
}
catch (err) {
const message = err.message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
if (requiredVersion?.startsWith("==")) {
requiredVersion = requiredVersion.slice(2);
}
if (requiredVersion !== undefined) {
core.info(`Found required-version for uv in ${filePath}: ${requiredVersion}`);
}
return requiredVersion;
}
function getRequiredVersion(filePath) {
const fileContent = node_fs_1.default.readFileSync(filePath, "utf-8");
if (filePath.endsWith("pyproject.toml")) {
const tomlContent = toml.parse(fileContent);
return tomlContent?.tool?.uv?.["required-version"];
}
const tomlContent = toml.parse(fileContent);
return tomlContent["required-version"];
}
/***/ }),
/***/ 56156:
@ -125525,10 +125450,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.manifestFile = exports.githubToken = exports.serverUrl = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.workingDirectory = exports.activateEnvironment = exports.pythonVersion = exports.version = void 0;
exports.manifestFile = exports.githubToken = exports.serverUrl = exports.toolDir = exports.toolBinDir = exports.ignoreEmptyWorkdir = exports.ignoreNothingToCache = exports.pruneCache = exports.cacheDependencyGlob = exports.cacheLocalPath = exports.cacheSuffix = exports.enableCache = exports.checkSum = exports.workingDirectory = exports.activateEnvironment = exports.pythonVersion = exports.versionFile = exports.version = void 0;
const core = __importStar(__nccwpck_require__(37484));
const node_path_1 = __importDefault(__nccwpck_require__(76760));
exports.version = core.getInput("version");
exports.versionFile = core.getInput("version-file");
exports.pythonVersion = core.getInput("python-version");
exports.activateEnvironment = core.getBooleanInput("activate-environment");
exports.workingDirectory = core.getInput("working-directory");
@ -125740,6 +125666,216 @@ async function isMuslOs() {
}
/***/ }),
/***/ 9931:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getRequiredVersionFromConfigFile = getRequiredVersionFromConfigFile;
const node_fs_1 = __importDefault(__nccwpck_require__(73024));
const toml = __importStar(__nccwpck_require__(27106));
function getRequiredVersionFromConfigFile(filePath) {
if (!filePath.endsWith(".toml")) {
return undefined;
}
const fileContent = node_fs_1.default.readFileSync(filePath, "utf-8");
if (filePath.endsWith("pyproject.toml")) {
const tomlContent = toml.parse(fileContent);
return tomlContent?.tool?.uv?.["required-version"];
}
const tomlContent = toml.parse(fileContent);
return tomlContent["required-version"];
}
/***/ }),
/***/ 4569:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getUvVersionFromRequirementsFile = getUvVersionFromRequirementsFile;
const toml = __importStar(__nccwpck_require__(27106));
const node_fs_1 = __importDefault(__nccwpck_require__(73024));
function getUvVersionFromRequirementsFile(filePath) {
const fileContent = node_fs_1.default.readFileSync(filePath, "utf-8");
if (filePath.endsWith(".txt")) {
return getUvVersionFromAllDependencies(fileContent.split("\n"));
}
const dependencies = parsePyprojectDependencies(fileContent);
return getUvVersionFromAllDependencies(dependencies);
}
function getUvVersionFromAllDependencies(allDependencies) {
return allDependencies
.find((dep) => dep.startsWith("uv"))
?.match(/^uv([^A-Z0-9._-]+.*)$/)?.[1]
.trim();
}
function parsePyprojectDependencies(pyprojectContent) {
const pyproject = toml.parse(pyprojectContent);
const dependencies = pyproject?.project?.dependencies || [];
const optionalDependencies = Object.values(pyproject?.project?.["optional-dependencies"] || {}).flat();
const devDependencies = Object.values(pyproject?.["dependency-groups"] || {})
.flat()
.filter((item) => typeof item === "string");
return dependencies.concat(optionalDependencies, devDependencies);
}
/***/ }),
/***/ 36772:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getUvVersionFromFile = getUvVersionFromFile;
const core = __importStar(__nccwpck_require__(37484));
const node_fs_1 = __importDefault(__nccwpck_require__(73024));
const config_file_1 = __nccwpck_require__(9931);
const requirements_file_1 = __nccwpck_require__(4569);
function getUvVersionFromFile(filePath) {
core.info(`Trying to find version for uv in: ${filePath}`);
if (!node_fs_1.default.existsSync(filePath)) {
core.info(`Could not find file: ${filePath}`);
return undefined;
}
let uvVersion;
try {
uvVersion = (0, config_file_1.getRequiredVersionFromConfigFile)(filePath);
if (uvVersion === undefined) {
uvVersion = (0, requirements_file_1.getUvVersionFromRequirementsFile)(filePath);
}
}
catch (err) {
const message = err.message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
if (uvVersion?.startsWith("==")) {
uvVersion = uvVersion.slice(2);
}
if (uvVersion !== undefined) {
core.info(`Found version for uv in ${filePath}: ${uvVersion}`);
}
return uvVersion;
}
/***/ }),
/***/ 42078:

View File

@ -25,13 +25,14 @@ import {
toolBinDir,
toolDir,
version as versionInput,
versionFile as versionFileInput,
workingDirectory,
serverUrl,
manifestFile,
} from "./utils/inputs";
import * as exec from "@actions/exec";
import fs from "node:fs";
import { getUvVersionFromConfigFile } from "./utils/config-file";
import { getUvVersionFromFile } from "./version/resolve";
async function run(): Promise<void> {
detectEmptyWorkdir();
@ -133,10 +134,19 @@ async function determineVersion(
if (versionInput !== "") {
return await resolveVersion(versionInput, manifestFile, githubToken);
}
const versionFromUvToml = getUvVersionFromConfigFile(
if (versionFileInput !== "") {
const versionFromFile = getUvVersionFromFile(versionFileInput);
if (versionFromFile === undefined) {
throw new Error(
`Could not determine uv version from file: ${versionFileInput}`,
);
}
return await resolveVersion(versionFromFile, manifestFile, githubToken);
}
const versionFromUvToml = getUvVersionFromFile(
`${workingDirectory}${path.sep}uv.toml`,
);
const versionFromPyproject = getUvVersionFromConfigFile(
const versionFromPyproject = getUvVersionFromFile(
`${workingDirectory}${path.sep}pyproject.toml`,
);
if (versionFromUvToml === undefined && versionFromPyproject === undefined) {

View File

@ -1,46 +0,0 @@
import fs from "node:fs";
import * as core from "@actions/core";
import * as toml from "smol-toml";
export function getUvVersionFromConfigFile(
filePath: string,
): string | undefined {
core.info(`Trying to find required-version for uv in: ${filePath}`);
if (!fs.existsSync(filePath)) {
core.info(`Could not find file: ${filePath}`);
return undefined;
}
let requiredVersion: string | undefined;
try {
requiredVersion = getRequiredVersion(filePath);
} catch (err) {
const message = (err as Error).message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
if (requiredVersion?.startsWith("==")) {
requiredVersion = requiredVersion.slice(2);
}
if (requiredVersion !== undefined) {
core.info(
`Found required-version for uv in ${filePath}: ${requiredVersion}`,
);
}
return requiredVersion;
}
function getRequiredVersion(filePath: string): string | undefined {
const fileContent = fs.readFileSync(filePath, "utf-8");
if (filePath.endsWith("pyproject.toml")) {
const tomlContent = toml.parse(fileContent) as {
tool?: { uv?: { "required-version"?: string } };
};
return tomlContent?.tool?.uv?.["required-version"];
}
const tomlContent = toml.parse(fileContent) as {
"required-version"?: string;
};
return tomlContent["required-version"];
}

View File

@ -3,6 +3,7 @@ import path from "node:path";
import { getManifestFromRepo } from "@actions/tool-cache";
export const version = core.getInput("version");
export const versionFile = core.getInput("version-file");
export const pythonVersion = core.getInput("python-version");
export const activateEnvironment = core.getBooleanInput("activate-environment");
export const workingDirectory = core.getInput("working-directory");

View File

@ -0,0 +1,22 @@
import fs from "node:fs";
import * as toml from "smol-toml";
export function getRequiredVersionFromConfigFile(
filePath: string,
): string | undefined {
if (!filePath.endsWith(".toml")) {
return undefined;
}
const fileContent = fs.readFileSync(filePath, "utf-8");
if (filePath.endsWith("pyproject.toml")) {
const tomlContent = toml.parse(fileContent) as {
tool?: { uv?: { "required-version"?: string } };
};
return tomlContent?.tool?.uv?.["required-version"];
}
const tomlContent = toml.parse(fileContent) as {
"required-version"?: string;
};
return tomlContent["required-version"];
}

View File

@ -0,0 +1,43 @@
import * as toml from "smol-toml";
import fs from "node:fs";
export function getUvVersionFromRequirementsFile(
filePath: string,
): string | undefined {
const fileContent = fs.readFileSync(filePath, "utf-8");
if (filePath.endsWith(".txt")) {
return getUvVersionFromAllDependencies(fileContent.split("\n"));
}
const dependencies = parsePyprojectDependencies(fileContent);
return getUvVersionFromAllDependencies(dependencies);
}
function getUvVersionFromAllDependencies(
allDependencies: string[],
): string | undefined {
return allDependencies
.find((dep: string) => dep.startsWith("uv"))
?.match(/^uv([^A-Z0-9._-]+.*)$/)?.[1]
.trim();
}
interface Pyproject {
project?: {
dependencies?: string[];
"optional-dependencies"?: Record<string, string[]>;
};
"dependency-groups"?: Record<string, Array<string | object>>;
}
function parsePyprojectDependencies(pyprojectContent: string): string[] {
const pyproject: Pyproject = toml.parse(pyprojectContent);
const dependencies: string[] = pyproject?.project?.dependencies || [];
const optionalDependencies: string[] = Object.values(
pyproject?.project?.["optional-dependencies"] || {},
).flat();
const devDependencies: string[] = Object.values(
pyproject?.["dependency-groups"] || {},
)
.flat()
.filter((item: string | object) => typeof item === "string");
return dependencies.concat(optionalDependencies, devDependencies);
}

30
src/version/resolve.ts Normal file
View File

@ -0,0 +1,30 @@
import * as core from "@actions/core";
import fs from "node:fs";
import { getRequiredVersionFromConfigFile } from "./config-file";
import { getUvVersionFromRequirementsFile } from "./requirements-file";
export function getUvVersionFromFile(filePath: string): string | undefined {
core.info(`Trying to find version for uv in: ${filePath}`);
if (!fs.existsSync(filePath)) {
core.info(`Could not find file: ${filePath}`);
return undefined;
}
let uvVersion: string | undefined;
try {
uvVersion = getRequiredVersionFromConfigFile(filePath);
if (uvVersion === undefined) {
uvVersion = getUvVersionFromRequirementsFile(filePath);
}
} catch (err) {
const message = (err as Error).message;
core.warning(`Error while parsing ${filePath}: ${message}`);
return undefined;
}
if (uvVersion?.startsWith("==")) {
uvVersion = uvVersion.slice(2);
}
if (uvVersion !== undefined) {
core.info(`Found version for uv in ${filePath}: ${uvVersion}`);
}
return uvVersion;
}