mirror of
https://github.com/astral-sh/setup-uv.git
synced 2025-01-19 00:08:17 +08:00
Detect required-version from config file (#233)
1. If defined use version input 2. If defined use uv-file input 3. If defined use pyproject-file input 4. Search for required-version in uv.toml in repo root 5. Search for required-version in pyproject.toml in repo root 6. Use latest Closes: #215
This commit is contained in:
parent
d577e74f98
commit
5ce9ee0011
33
.github/workflows/test.yml
vendored
33
.github/workflows/test.yml
vendored
@ -64,6 +64,39 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
env:
|
env:
|
||||||
UV_VERSION: ${{ steps.setup-uv.outputs.uv-version }}
|
UV_VERSION: ${{ steps.setup-uv.outputs.uv-version }}
|
||||||
|
test-pyproject-file-version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install version 0.5.14
|
||||||
|
id: setup-uv
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
pyproject-file: "__tests__/fixtures/pyproject-toml-project/pyproject.toml"
|
||||||
|
- name: Correct version gets installed
|
||||||
|
run: |
|
||||||
|
if [ "$UV_VERSION" != "0.5.14" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
UV_VERSION: ${{ steps.setup-uv.outputs.uv-version }}
|
||||||
|
test-uv-file-version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install version 0.5.15
|
||||||
|
id: setup-uv
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
pyproject-file: "__tests__/fixtures/uv-toml-project/pyproject.toml"
|
||||||
|
uv-file: "__tests__/fixtures/uv-toml-project/uv.toml"
|
||||||
|
- name: Correct version gets installed
|
||||||
|
run: |
|
||||||
|
if [ "$UV_VERSION" != "0.5.15" ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
env:
|
||||||
|
UV_VERSION: ${{ steps.setup-uv.outputs.uv-version }}
|
||||||
test-checksum:
|
test-checksum:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
3.11
|
0
__tests__/fixtures/pyproject-toml-project/README.md
Normal file
0
__tests__/fixtures/pyproject-toml-project/README.md
Normal file
6
__tests__/fixtures/pyproject-toml-project/hello.py
Normal file
6
__tests__/fixtures/pyproject-toml-project/hello.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
def main():
|
||||||
|
print("Hello from pyproject-toml-project!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
10
__tests__/fixtures/pyproject-toml-project/pyproject.toml
Normal file
10
__tests__/fixtures/pyproject-toml-project/pyproject.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[project]
|
||||||
|
name = "pyproject-toml-project"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
required-version = "==0.5.14"
|
1
__tests__/fixtures/uv-toml-project/.python-version
Normal file
1
__tests__/fixtures/uv-toml-project/.python-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.11
|
0
__tests__/fixtures/uv-toml-project/README.md
Normal file
0
__tests__/fixtures/uv-toml-project/README.md
Normal file
6
__tests__/fixtures/uv-toml-project/hello.py
Normal file
6
__tests__/fixtures/uv-toml-project/hello.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
def main():
|
||||||
|
print("Hello from uv-toml-project!")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
10
__tests__/fixtures/uv-toml-project/pyproject.toml
Normal file
10
__tests__/fixtures/uv-toml-project/pyproject.toml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
[project]
|
||||||
|
name = "uv-toml-project"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
[tool.uv]
|
||||||
|
required-version = "==0.5.14"
|
1
__tests__/fixtures/uv-toml-project/uv.toml
Normal file
1
__tests__/fixtures/uv-toml-project/uv.toml
Normal file
@ -0,0 +1 @@
|
|||||||
|
required-version = "==0.5.15"
|
12
action.yml
12
action.yml
@ -4,8 +4,14 @@ description:
|
|||||||
author: "astral-sh"
|
author: "astral-sh"
|
||||||
inputs:
|
inputs:
|
||||||
version:
|
version:
|
||||||
description: "The version of uv to install"
|
description: "The version of uv to install e.g., `0.5.0` Defaults to the version in pyproject.toml or 'latest'."
|
||||||
default: "latest"
|
default: ""
|
||||||
|
pyproject-file:
|
||||||
|
description: "Path to a pyproject.toml"
|
||||||
|
default: ""
|
||||||
|
uv-file:
|
||||||
|
description: "Path to a uv.toml"
|
||||||
|
default: ""
|
||||||
python-version:
|
python-version:
|
||||||
description: "The version of Python to set UV_PYTHON to"
|
description: "The version of Python to set UV_PYTHON to"
|
||||||
required: false
|
required: false
|
||||||
@ -18,7 +24,7 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: ${{ github.token }}
|
default: ${{ github.token }}
|
||||||
enable-cache:
|
enable-cache:
|
||||||
description: "Enable caching of the uv cache"
|
description: "Enable uploading of the uv cache"
|
||||||
default: "auto"
|
default: "auto"
|
||||||
cache-dependency-glob:
|
cache-dependency-glob:
|
||||||
description:
|
description:
|
||||||
|
BIN
dist/save-cache/index.js
generated
vendored
BIN
dist/save-cache/index.js
generated
vendored
Binary file not shown.
BIN
dist/setup/index.js
generated
vendored
BIN
dist/setup/index.js
generated
vendored
Binary file not shown.
11
package-lock.json
generated
11
package-lock.json
generated
@ -16,6 +16,7 @@
|
|||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.5.0",
|
||||||
"@actions/io": "^1.1.3",
|
"@actions/io": "^1.1.3",
|
||||||
"@actions/tool-cache": "^2.0.1",
|
"@actions/tool-cache": "^2.0.1",
|
||||||
|
"@iarna/toml": "^2.2.5",
|
||||||
"@octokit/rest": "^21.0.2"
|
"@octokit/rest": "^21.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -1104,6 +1105,11 @@
|
|||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@iarna/toml": {
|
||||||
|
"version": "2.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
|
||||||
|
"integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="
|
||||||
|
},
|
||||||
"node_modules/@istanbuljs/load-nyc-config": {
|
"node_modules/@istanbuljs/load-nyc-config": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||||
@ -5918,6 +5924,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz",
|
||||||
"integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA=="
|
"integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA=="
|
||||||
},
|
},
|
||||||
|
"@iarna/toml": {
|
||||||
|
"version": "2.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
|
||||||
|
"integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="
|
||||||
|
},
|
||||||
"@istanbuljs/load-nyc-config": {
|
"@istanbuljs/load-nyc-config": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||||
|
@ -30,7 +30,8 @@
|
|||||||
"@actions/glob": "^0.5.0",
|
"@actions/glob": "^0.5.0",
|
||||||
"@actions/io": "^1.1.3",
|
"@actions/io": "^1.1.3",
|
||||||
"@actions/tool-cache": "^2.0.1",
|
"@actions/tool-cache": "^2.0.1",
|
||||||
"@octokit/rest": "^21.0.2"
|
"@octokit/rest": "^21.0.2",
|
||||||
|
"@iarna/toml": "^2.2.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "1.9.4",
|
||||||
|
@ -18,12 +18,16 @@ import {
|
|||||||
checkSum,
|
checkSum,
|
||||||
enableCache,
|
enableCache,
|
||||||
githubToken,
|
githubToken,
|
||||||
|
pyProjectFile,
|
||||||
pythonVersion,
|
pythonVersion,
|
||||||
toolBinDir,
|
toolBinDir,
|
||||||
toolDir,
|
toolDir,
|
||||||
version,
|
uvFile,
|
||||||
|
version as versionInput,
|
||||||
} from "./utils/inputs";
|
} from "./utils/inputs";
|
||||||
import * as exec from "@actions/exec";
|
import * as exec from "@actions/exec";
|
||||||
|
import fs from "node:fs";
|
||||||
|
import { getUvVersionFromConfigFile } from "./utils/pyproject";
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
const platform = getPlatform();
|
const platform = getPlatform();
|
||||||
@ -36,13 +40,7 @@ async function run(): Promise<void> {
|
|||||||
if (arch === undefined) {
|
if (arch === undefined) {
|
||||||
throw new Error(`Unsupported architecture: ${process.arch}`);
|
throw new Error(`Unsupported architecture: ${process.arch}`);
|
||||||
}
|
}
|
||||||
const setupResult = await setupUv(
|
const setupResult = await setupUv(platform, arch, checkSum, githubToken);
|
||||||
platform,
|
|
||||||
arch,
|
|
||||||
version,
|
|
||||||
checkSum,
|
|
||||||
githubToken,
|
|
||||||
);
|
|
||||||
|
|
||||||
addUvToPath(setupResult.uvDir);
|
addUvToPath(setupResult.uvDir);
|
||||||
addToolBinToPath();
|
addToolBinToPath();
|
||||||
@ -66,11 +64,10 @@ async function run(): Promise<void> {
|
|||||||
async function setupUv(
|
async function setupUv(
|
||||||
platform: Platform,
|
platform: Platform,
|
||||||
arch: Architecture,
|
arch: Architecture,
|
||||||
versionInput: string,
|
|
||||||
checkSum: string | undefined,
|
checkSum: string | undefined,
|
||||||
githubToken: string,
|
githubToken: string,
|
||||||
): Promise<{ uvDir: string; version: string }> {
|
): Promise<{ uvDir: string; version: string }> {
|
||||||
const resolvedVersion = await resolveVersion(versionInput, githubToken);
|
const resolvedVersion = await determineVersion();
|
||||||
const toolCacheResult = tryGetFromToolCache(arch, resolvedVersion);
|
const toolCacheResult = tryGetFromToolCache(arch, resolvedVersion);
|
||||||
if (toolCacheResult.installedPath) {
|
if (toolCacheResult.installedPath) {
|
||||||
core.info(`Found uv in tool-cache for ${toolCacheResult.version}`);
|
core.info(`Found uv in tool-cache for ${toolCacheResult.version}`);
|
||||||
@ -94,6 +91,28 @@ async function setupUv(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function determineVersion(): Promise<string> {
|
||||||
|
if (versionInput !== "") {
|
||||||
|
return await resolveVersion(versionInput, githubToken);
|
||||||
|
}
|
||||||
|
const configFile = uvFile !== "" ? uvFile : pyProjectFile;
|
||||||
|
if (configFile !== "") {
|
||||||
|
const versionFromConfigFile = getUvVersionFromConfigFile(configFile);
|
||||||
|
if (versionFromConfigFile === undefined) {
|
||||||
|
core.warning(
|
||||||
|
`Could not find required-version under [tool.uv] in ${configFile}. Falling back to latest`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return await resolveVersion(versionFromConfigFile || "latest", githubToken);
|
||||||
|
}
|
||||||
|
if (!fs.existsSync("uv.toml") && !fs.existsSync("pyproject.toml")) {
|
||||||
|
return await resolveVersion("latest", githubToken);
|
||||||
|
}
|
||||||
|
const versionFile = fs.existsSync("uv.toml") ? "uv.toml" : "pyproject.toml";
|
||||||
|
const versionFromConfigFile = getUvVersionFromConfigFile(versionFile);
|
||||||
|
return await resolveVersion(versionFromConfigFile || "latest", githubToken);
|
||||||
|
}
|
||||||
|
|
||||||
function addUvToPath(cachedPath: string): void {
|
function addUvToPath(cachedPath: string): void {
|
||||||
core.addPath(cachedPath);
|
core.addPath(cachedPath);
|
||||||
core.info(`Added ${cachedPath} to the path`);
|
core.info(`Added ${cachedPath} to the path`);
|
||||||
|
@ -2,6 +2,8 @@ import * as core from "@actions/core";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
|
||||||
export const version = core.getInput("version");
|
export const version = core.getInput("version");
|
||||||
|
export const pyProjectFile = core.getInput("pyproject-file");
|
||||||
|
export const uvFile = core.getInput("uv-file");
|
||||||
export const pythonVersion = core.getInput("python-version");
|
export const pythonVersion = core.getInput("python-version");
|
||||||
export const checkSum = core.getInput("checksum");
|
export const checkSum = core.getInput("checksum");
|
||||||
export const enableCache = getEnableCache();
|
export const enableCache = getEnableCache();
|
||||||
|
38
src/utils/pyproject.ts
Normal file
38
src/utils/pyproject.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import fs from "node:fs";
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
import * as toml from "@iarna/toml";
|
||||||
|
|
||||||
|
export function getUvVersionFromConfigFile(
|
||||||
|
filePath: string,
|
||||||
|
): string | undefined {
|
||||||
|
if (!fs.existsSync(filePath)) {
|
||||||
|
core.warning(`Could not find file: ${filePath}`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let requiredVersion = getRequiredVersion(filePath);
|
||||||
|
|
||||||
|
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"];
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user