From ce0062aac78b2f340c6612e0e40b80a2fa668ced Mon Sep 17 00:00:00 2001 From: Kevin Stillhammer Date: Wed, 18 Sep 2024 11:29:09 +0200 Subject: [PATCH] Add support for semver version ranges (#82) Closes: #38 --- .github/workflows/test.yml | 21 ++++++++++- README.md | 19 ++++++++++ dist/setup/index.js | Bin 3604520 -> 3757673 bytes src/download/download-version.ts | 60 ++++++++++++++++++++++++++----- src/setup-uv.ts | 28 +++++++++------ 5 files changed, 109 insertions(+), 19 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 34d085e..0f33e20 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, macos-14, oracle-aarch64] - uv-version: ["latest", "0.3.0", "0.3.2"] + uv-version: ["latest", "0.3.0", "0.3.2", "0.3", "0.3.x", ">=0.3.0"] steps: - uses: actions/checkout@v4 - name: Install version ${{ matrix.uv-version }} @@ -49,6 +49,25 @@ jobs: version: ${{ matrix.uv-version }} - run: uv sync working-directory: __tests__/fixtures/uv-project + test-semver-range: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, oracle-aarch64] + steps: + - uses: actions/checkout@v4 + - name: Install version 0.3 + id: setup-uv + uses: ./ + with: + version: "0.3" + - name: Correct version gets installed + run: | + if [ "$UV_VERSION" != "0.3.5" ]; then + exit 1 + fi + env: + UV_VERSION: ${{ steps.setup-uv.outputs.uv-version }} test-checksum: runs-on: ${{ matrix.os }} strategy: diff --git a/README.md b/README.md index 56cd069..b1b8bf9 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,25 @@ For an example workflow, see version: "0.4.4" ``` +### Install a version by supplying a semver range + +You can also specify a [semver range](https://github.com/npm/node-semver?tab=readme-ov-file#ranges) +to install the latest version that satisfies the range. + +```yaml +- name: Install a semver range of uv + uses: astral-sh/setup-uv@v2 + with: + version: ">=0.3.0" +``` + +```yaml +- name: Pinning a minor version of uv + uses: astral-sh/setup-uv@v2 + with: + version: "0.3.x" +``` + ### Validate checksum You can also specify a checksum to validate the downloaded file. Checksums up to the default version diff --git a/dist/setup/index.js b/dist/setup/index.js index b311f34c5962e0cbc2c01da627a055f6f2569a70..3b7096531669faa53b3920764a735c85f83d98d0 100644 GIT binary patch delta 139387 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 delta 499 zcmYMt&oA3?7zgltXunmZigx`reCx-kAGMZe82Y7c;-ZP^ZI>kyK{5+jN?GDS7SvHP z@?0d$4k~^egnSMp;t!BCaabg?E!Yx~jKoobx0Aywc|Y&N`?=isE0U8x#pINjO4~`F zuqRS_IvBtR3YZ`R%#aBd$bxLJLJrs<7xEwl=y3hB)FO4_~Nc`+6A3=VK3j;cpc*Cq`vUB`pb_Q7KQ}R?(o~<#}P^ zKjt)rcT{R;>z?M47k-LZGCmA_ijNF;*KwClPL2l1|6B$B8C?85Ku4To#&+Cp(XYDTl9gdfq(Z0wJ>EG zJD#5M`yjdbe;al3O@I_$57H+83Sn { + githubToken: string, +): Promise<{ version: string; cachedToolDir: string }> { + const resolvedVersion = await resolveVersion(version, githubToken); const artifact = `uv-${arch}-${platform}`; - let downloadUrl = `https://github.com/${OWNER}/${REPO}/releases/download/${version}/${artifact}`; + let downloadUrl = `https://github.com/${OWNER}/${REPO}/releases/download/${resolvedVersion}/${artifact}`; if (platform === "pc-windows-msvc") { downloadUrl += ".zip"; } else { @@ -36,7 +43,13 @@ export async function downloadVersion( undefined, githubToken, ); - await validateChecksum(checkSum, downloadPath, arch, platform, version); + await validateChecksum( + checkSum, + downloadPath, + arch, + platform, + resolvedVersion, + ); let uvDir: string; if (platform === "pc-windows-msvc") { @@ -46,6 +59,37 @@ export async function downloadVersion( const extractedDir = await tc.extractTar(downloadPath); uvDir = path.join(extractedDir, artifact); } - - return await tc.cacheDir(uvDir, TOOL_CACHE_NAME, version, arch); + const cachedToolDir = await tc.cacheDir( + uvDir, + TOOL_CACHE_NAME, + resolvedVersion, + arch, + ); + return { version: resolvedVersion, cachedToolDir }; +} + +async function resolveVersion( + version: string, + githubToken: string, +): Promise { + if (tc.isExplicitVersion(version)) { + core.debug(`Version ${version} is an explicit version.`); + return version; + } + const availableVersions = await getAvailableVersions(githubToken); + const resolvedVersion = tc.evaluateVersions(availableVersions, version); + if (resolvedVersion === "") { + throw new Error(`No version found for ${version}`); + } + return resolvedVersion; +} + +async function getAvailableVersions(githubToken: string): Promise { + const octokit = github.getOctokit(githubToken); + + const response = await octokit.paginate(octokit.rest.repos.listReleases, { + owner: OWNER, + repo: REPO, + }); + return response.map((release) => release.tag_name); } diff --git a/src/setup-uv.ts b/src/setup-uv.ts index d899281..6d9d7e5 100644 --- a/src/setup-uv.ts +++ b/src/setup-uv.ts @@ -41,8 +41,8 @@ async function run(): Promise { ); addUvToPath(setupResult.uvDir); - core.setOutput("uv-version", version); - core.info(`Successfully installed uv version ${version}`); + core.setOutput("uv-version", setupResult.version); + core.info(`Successfully installed uv version ${setupResult.version}`); addMatchers(); setCacheDir(cacheLocalPath); @@ -50,10 +50,10 @@ async function run(): Promise { if (enableCache) { await restoreCache(setupResult.version); } + process.exit(0); } catch (err) { core.setFailed((err as Error).message); } - process.exit(0); } async function setupUv( @@ -61,29 +61,37 @@ async function setupUv( arch: Architecture, versionInput: string, checkSum: string | undefined, - githubToken: string | undefined, + githubToken: string, ): Promise<{ uvDir: string; version: string }> { let installedPath: string | undefined; let cachedToolDir: string; let version: string; if (versionInput === "latest") { - const result = await downloadLatest(platform, arch, checkSum, githubToken); - version = result.version; - cachedToolDir = result.cachedToolDir; + const latestResult = await downloadLatest( + platform, + arch, + checkSum, + githubToken, + ); + version = latestResult.version; + cachedToolDir = latestResult.cachedToolDir; } else { - version = versionInput; - installedPath = tryGetFromToolCache(arch, versionInput); + const toolCacheResult = tryGetFromToolCache(arch, versionInput); + version = toolCacheResult.version; + installedPath = toolCacheResult.installedPath; if (installedPath) { core.info(`Found uv in tool-cache for ${versionInput}`); return { uvDir: installedPath, version }; } - cachedToolDir = await downloadVersion( + const versionResult = await downloadVersion( platform, arch, versionInput, checkSum, githubToken, ); + cachedToolDir = versionResult.cachedToolDir; + version = versionResult.version; } return { uvDir: cachedToolDir, version };