Shortcut to latest version for minimum version specifier (#598)

This is faster than downloading all available versions from GitHub to
determine the highest matching version.

Fixes: #585
This commit is contained in:
Kevin Stillhammer
2025-09-30 19:55:27 +02:00
committed by GitHub
parent d0cc045d04
commit d8a37f6566
3 changed files with 88 additions and 113 deletions

View File

@@ -76,78 +76,110 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
uv-version: ["0.3.0", "0.3.2", "0.3", "0.3.x", ">=0.3.0"] input:
- version-input: "0.3.0"
expected-version: "0.3.0"
- version-input: "0.3.2"
expected-version: "0.3.2"
- version-input: "0.3"
expected-version: "0.3.5"
- version-input: "0.3.x"
expected-version: "0.3.5"
- version-input: ">=0.4.25,<0.5"
expected-version: "0.4.30"
steps: steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install version ${{ matrix.uv-version }} - name: Install version ${{ matrix.input.version-input }}
uses: ./
with:
version: ${{ matrix.uv-version }}
- run: uv sync
working-directory: __tests__/fixtures/uv-project
test-semver-range:
strategy:
matrix:
os: [ ubuntu-latest, selfhosted-ubuntu-arm64 ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install version 0.3
id: setup-uv id: setup-uv
uses: ./ uses: ./
with: with:
version: "0.3" version: ${{ matrix.input.version-input }}
- name: Correct version gets installed - name: Correct version gets installed
run: | run: |
if [ "$(uv --version)" != "uv 0.3.5" ]; then if [ "$(uv --version)" != "uv ${{ matrix.input.expected-version }}" ]; then
echo "Wrong uv version: $(uv --version)" echo "Wrong uv version: $(uv --version)"
exit 1 exit 1
fi fi
- name: Output has correct version - name: Output has correct version
run: | run: |
if [ "$UV_VERSION" != "0.3.5" ]; then if [ "$UV_VERSION" != "${{ matrix.input.expected-version }}" ]; then
exit 1 exit 1
fi fi
env: env:
UV_VERSION: ${{ steps.setup-uv.outputs.uv-version }} UV_VERSION: ${{ steps.setup-uv.outputs.uv-version }}
test-pep440-version: test-latest-version:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
version-input: ["latest", ">=0.8"]
steps: steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install version 0.4.30 - name: Install version ${{ matrix.version-input }}
id: setup-uv
uses: ./ uses: ./
with: with:
version: ">=0.4.25,<0.5" version: ${{ matrix.version-input }}
- name: Latest version gets installed
run: |
LATEST_VERSION=$(gh api -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" /repos/astral-sh/uv/releases/latest | jq -r '.tag_name')
echo "Latest version is $LATEST_VERSION"
if [ "$(uv --version)" != "uv $LATEST_VERSION" ]; then
echo "Wrong uv version: $(uv --version)"
exit 1
fi
env:
GH_TOKEN: ${{ github.token }}
test-from-working-directory-version:
runs-on: ubuntu-latest
strategy:
matrix:
input:
- working-directory: "__tests__/fixtures/pyproject-toml-project"
expected-version: "0.5.14"
- working-directory: "__tests__/fixtures/uv-toml-project"
expected-version: "0.5.15"
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install version from ${{ matrix.input.working-directory }}
uses: ./
with:
working-directory: ${{ matrix.input.working-directory }}
- name: Correct version gets installed - name: Correct version gets installed
run: | run: |
if [ "$(uv --version)" != "uv 0.4.30" ]; then if [ "$(uv --version)" != "uv ${{ matrix.input.expected-version }}" ]; then
echo "Wrong uv version: $(uv --version)" echo "Wrong uv version: $(uv --version)"
exit 1 exit 1
fi fi
test-pyproject-file-version: test-version-file-version:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy:
matrix:
input:
- version-file: "__tests__/fixtures/uv-in-requirements-txt-project/requirements.txt"
expected-version: "0.6.17"
- version-file: "__tests__/fixtures/uv-in-requirements-hash-txt-project/requirements.txt"
expected-version: "0.8.3"
- version-file: "__tests__/fixtures/.tool-versions"
expected-version: "0.5.15"
steps: steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with: with:
persist-credentials: false persist-credentials: false
- name: Install version 0.5.14 - name: Install version from ${{ matrix.input.version-file }}
id: setup-uv
uses: ./ uses: ./
with: with:
working-directory: "__tests__/fixtures/pyproject-toml-project" version-file: ${{ matrix.input.version-file }}
- name: Correct version gets installed - name: Correct version gets installed
run: | run: |
if [ "$(uv --version)" != "uv 0.5.14" ]; then if [ "$(uv --version)" != "uv ${{ matrix.input.expected-version }}" ]; then
echo "Wrong uv version: $(uv --version)" echo "Wrong uv version: $(uv --version)"
exit 1 exit 1
fi fi
@@ -165,78 +197,6 @@ jobs:
working-directory: "__tests__/fixtures/malformed-pyproject-toml-project" working-directory: "__tests__/fixtures/malformed-pyproject-toml-project"
- run: uv --help - run: uv --help
test-uv-file-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install version 0.5.15
id: setup-uv
uses: ./
with:
working-directory: "__tests__/fixtures/uv-toml-project"
- name: Correct version gets installed
run: |
if [ "$(uv --version)" != "uv 0.5.15" ]; then
echo "Wrong uv version: $(uv --version)"
exit 1
fi
test-version-file-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- 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-version-file-hash-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install from requirements file
id: setup-uv
uses: ./
with:
version-file: "__tests__/fixtures/uv-in-requirements-hash-txt-project/requirements.txt"
- name: Correct version gets installed
run: |
if [ "$(uv --version)" != "uv 0.8.3" ]; then
echo "Wrong uv version: $(uv --version)"
exit 1
fi
test-tool-versions-file-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:
persist-credentials: false
- name: Install from .tools-versions file
id: setup-uv
uses: ./
with:
version-file: "__tests__/fixtures/.tool-versions"
- name: Correct version gets installed
run: |
if [ "$(uv --version)" != "uv 0.5.15" ]; then
echo "Wrong uv version: $(uv --version)"
exit 1
fi
test-checksum: test-checksum:
runs-on: ${{ matrix.inputs.os }} runs-on: ${{ matrix.inputs.os }}
strategy: strategy:
@@ -796,14 +756,10 @@ jobs:
- lint - lint
- test-default-version - test-default-version
- test-specific-version - test-specific-version
- test-semver-range - test-latest-version
- test-pep440-version - test-from-working-directory-version
- test-pyproject-file-version
- test-malformed-pyproject-file-fallback - test-malformed-pyproject-file-fallback
- test-uv-file-version
- test-version-file-version - test-version-file-version
- test-version-file-hash-version
- test-tool-versions-file-version
- test-checksum - test-checksum
- test-with-explicit-token - test-with-explicit-token
- test-uvx - test-uvx

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

@@ -129037,20 +129037,29 @@ function getExtension(platform) {
async function resolveVersion(versionInput, manifestFile, githubToken) { async function resolveVersion(versionInput, manifestFile, githubToken) {
core.debug(`Resolving version: ${versionInput}`); core.debug(`Resolving version: ${versionInput}`);
let version; let version;
const isSimpleMinimumVersionSpecifier = versionInput.includes(">") && !versionInput.includes(",");
if (isSimpleMinimumVersionSpecifier) {
core.info("Found minimum version specifier, using latest version");
}
if (manifestFile) { if (manifestFile) {
version = version =
versionInput === "latest" versionInput === "latest" || isSimpleMinimumVersionSpecifier
? await (0, version_manifest_1.getLatestKnownVersion)(manifestFile) ? await (0, version_manifest_1.getLatestKnownVersion)(manifestFile)
: versionInput; : versionInput;
} }
else { else {
version = version =
versionInput === "latest" versionInput === "latest" || isSimpleMinimumVersionSpecifier
? await getLatestVersion(githubToken) ? await getLatestVersion(githubToken)
: versionInput; : versionInput;
} }
if (tc.isExplicitVersion(version)) { if (tc.isExplicitVersion(version)) {
core.debug(`Version ${version} is an explicit version.`); core.debug(`Version ${version} is an explicit version.`);
if (isSimpleMinimumVersionSpecifier) {
if (!pep440.satisfies(version, versionInput)) {
throw new Error(`No version found for ${versionInput}`);
}
}
return version; return version;
} }
const availableVersions = await getAvailableVersions(githubToken); const availableVersions = await getAvailableVersions(githubToken);

View File

@@ -135,19 +135,29 @@ export async function resolveVersion(
): Promise<string> { ): Promise<string> {
core.debug(`Resolving version: ${versionInput}`); core.debug(`Resolving version: ${versionInput}`);
let version: string; let version: string;
const isSimpleMinimumVersionSpecifier =
versionInput.includes(">") && !versionInput.includes(",");
if (isSimpleMinimumVersionSpecifier) {
core.info("Found minimum version specifier, using latest version");
}
if (manifestFile) { if (manifestFile) {
version = version =
versionInput === "latest" versionInput === "latest" || isSimpleMinimumVersionSpecifier
? await getLatestVersionInManifest(manifestFile) ? await getLatestVersionInManifest(manifestFile)
: versionInput; : versionInput;
} else { } else {
version = version =
versionInput === "latest" versionInput === "latest" || isSimpleMinimumVersionSpecifier
? await getLatestVersion(githubToken) ? await getLatestVersion(githubToken)
: versionInput; : versionInput;
} }
if (tc.isExplicitVersion(version)) { if (tc.isExplicitVersion(version)) {
core.debug(`Version ${version} is an explicit version.`); core.debug(`Version ${version} is an explicit version.`);
if (isSimpleMinimumVersionSpecifier) {
if (!pep440.satisfies(version, versionInput)) {
throw new Error(`No version found for ${versionInput}`);
}
}
return version; return version;
} }
const availableVersions = await getAvailableVersions(githubToken); const availableVersions = await getAvailableVersions(githubToken);