diff --git a/README.md b/README.md index b7bfb1b..09ed731 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,9 @@ Have a look under [Advanced Configuration](#advanced-configuration) for detailed # Add problem matchers add-problem-matchers: "true" + + # Attempt to retrieve from the Astral mirror first or use Github releases + use-mirror: "true" ``` ### Outputs diff --git a/__tests__/download/download-version.test.ts b/__tests__/download/download-version.test.ts index a638636..40f96a6 100644 --- a/__tests__/download/download-version.test.ts +++ b/__tests__/download/download-version.test.ts @@ -121,6 +121,7 @@ describe("download-version", () => { "0.9.26", undefined, "token", + true, ), ).rejects.toThrow("manifest unavailable"); @@ -138,6 +139,7 @@ describe("download-version", () => { "0.9.26", undefined, "token", + true, ), ).rejects.toThrow( "Could not find artifact for version 0.9.26, arch x86_64, platform unknown-linux-gnu in https://raw.githubusercontent.com/astral-sh/versions/main/v1/uv.ndjson .", @@ -160,6 +162,7 @@ describe("download-version", () => { "0.9.26", undefined, "token", + true, ); expect(mockValidateChecksum).toHaveBeenCalledWith( @@ -185,6 +188,7 @@ describe("download-version", () => { "0.9.26", undefined, "token", + true, ); expect(mockDownloadTool).toHaveBeenCalledWith( @@ -194,6 +198,30 @@ describe("download-version", () => { ); }); + it("doesn't rewrite GitHub Releases URLs to the Astral mirror if not use-mirror set", async () => { + mockGetArtifact.mockResolvedValue({ + archiveFormat: "tar.gz", + checksum: "abc123", + downloadUrl: + "https://github.com/astral-sh/uv/releases/download/0.9.26/uv-x86_64-unknown-linux-gnu.tar.gz", + }); + + await downloadVersion( + "unknown-linux-gnu", + "x86_64", + "0.9.26", + undefined, + "token", + false, + ); + + expect(mockDownloadTool).toHaveBeenCalledWith( + "https://github.com/astral-sh/uv/releases/download/0.9.26/uv-x86_64-unknown-linux-gnu.tar.gz", + undefined, + "token", + ); + }); + it("does not rewrite non-GitHub URLs", async () => { mockGetArtifact.mockResolvedValue({ archiveFormat: "tar.gz", @@ -207,6 +235,7 @@ describe("download-version", () => { "0.9.26", undefined, "token", + true, ); expect(mockDownloadTool).toHaveBeenCalledWith( @@ -234,6 +263,7 @@ describe("download-version", () => { "0.9.26", undefined, "token", + true, ); expect(mockDownloadTool).toHaveBeenCalledTimes(2); @@ -270,6 +300,7 @@ describe("download-version", () => { "0.9.26", undefined, "token", + true, ), ).rejects.toThrow("download failed"); @@ -289,6 +320,7 @@ describe("download-version", () => { "0.9.26", "", "token", + true, "https://example.com/custom.ndjson", ); @@ -314,6 +346,7 @@ describe("download-version", () => { "0.9.26", "user-checksum", "token", + true, "https://example.com/custom.ndjson", ); diff --git a/action-types.yml b/action-types.yml index 61335a0..c69e0e0 100644 --- a/action-types.yml +++ b/action-types.yml @@ -57,6 +57,8 @@ inputs: allowed-values: - highest - lowest + use-mirror: + type: boolean outputs: uv-version: diff --git a/action.yml b/action.yml index 8882beb..e6e5074 100644 --- a/action.yml +++ b/action.yml @@ -83,6 +83,10 @@ inputs: resolution-strategy: description: "Resolution strategy to use when resolving version ranges. 'highest' uses the latest compatible version, 'lowest' uses the oldest compatible version." default: "highest" + use-mirror: + description: "Whether to attempt to download from Astral mirror first or use the Github releases artifacts." + default: true + outputs: uv-version: description: "The installed uv version. Useful when using latest." diff --git a/dist/save-cache/index.cjs b/dist/save-cache/index.cjs index ecbfbbb..57d6dc4 100644 --- a/dist/save-cache/index.cjs +++ b/dist/save-cache/index.cjs @@ -62985,6 +62985,7 @@ function loadInputs() { const manifestFile = getManifestFile(); const addProblemMatchers = getInput("add-problem-matchers") === "true"; const resolutionStrategy = getResolutionStrategy(); + const useMirror = getInput("use-mirror") === "true"; return { activateEnvironment, addProblemMatchers, @@ -63006,6 +63007,7 @@ function loadInputs() { saveCache: saveCache4, toolBinDir, toolDir, + useMirror, venvPath, version: version3, versionFile, diff --git a/dist/setup/index.cjs b/dist/setup/index.cjs index d96aa48..33b0482 100644 --- a/dist/setup/index.cjs +++ b/dist/setup/index.cjs @@ -95702,7 +95702,7 @@ function tryGetFromToolCache(arch3, version3) { const installedPath = find(TOOL_CACHE_NAME, resolvedVersion, arch3); return { installedPath, version: resolvedVersion }; } -async function downloadVersion(platform2, arch3, version3, checksum, githubToken, manifestUrl) { +async function downloadVersion(platform2, arch3, version3, checksum, githubToken, useMirror, manifestUrl) { const artifact = await getArtifact(version3, arch3, platform2, manifestUrl); if (!artifact) { throw new Error( @@ -95710,7 +95710,7 @@ async function downloadVersion(platform2, arch3, version3, checksum, githubToken ); } const resolvedChecksum = manifestUrl === void 0 ? checksum : resolveChecksum(checksum, artifact.checksum); - const mirrorUrl = rewriteToMirror(artifact.downloadUrl); + const mirrorUrl = useMirror ? rewriteToMirror(artifact.downloadUrl) : void 0; const downloadUrl = mirrorUrl ?? artifact.downloadUrl; const downloadToken = mirrorUrl !== void 0 ? void 0 : githubToken; try { @@ -96591,6 +96591,7 @@ function loadInputs() { const manifestFile = getManifestFile(); const addProblemMatchers = getInput("add-problem-matchers") === "true"; const resolutionStrategy = getResolutionStrategy(); + const useMirror = getInput("use-mirror") === "true"; return { activateEnvironment: activateEnvironment2, addProblemMatchers, @@ -96612,6 +96613,7 @@ function loadInputs() { saveCache: saveCache2, toolBinDir, toolDir, + useMirror, venvPath, version: version3, versionFile, @@ -96985,6 +96987,7 @@ async function setupUv(inputs, platform2, arch3) { resolvedVersion, inputs.checksum, inputs.githubToken, + inputs.useMirror, inputs.manifestFile ); return { diff --git a/src/download/download-version.ts b/src/download/download-version.ts index 29f40d3..40f1faf 100644 --- a/src/download/download-version.ts +++ b/src/download/download-version.ts @@ -35,6 +35,7 @@ export async function downloadVersion( version: string, checksum: string | undefined, githubToken: string, + useMirror: boolean, manifestUrl?: string, ): Promise<{ version: string; cachedToolDir: string }> { const artifact = await getArtifact(version, arch, platform, manifestUrl); @@ -52,7 +53,9 @@ export async function downloadVersion( ? checksum : resolveChecksum(checksum, artifact.checksum); - const mirrorUrl = rewriteToMirror(artifact.downloadUrl); + const mirrorUrl = useMirror + ? rewriteToMirror(artifact.downloadUrl) + : undefined; const downloadUrl = mirrorUrl ?? artifact.downloadUrl; // Don't send the GitHub token to the Astral mirror. const downloadToken = mirrorUrl !== undefined ? undefined : githubToken; diff --git a/src/setup-uv.ts b/src/setup-uv.ts index e1d40c2..f0a8582 100644 --- a/src/setup-uv.ts +++ b/src/setup-uv.ts @@ -128,6 +128,7 @@ async function setupUv( resolvedVersion, inputs.checksum, inputs.githubToken, + inputs.useMirror, inputs.manifestFile, ); diff --git a/src/utils/inputs.ts b/src/utils/inputs.ts index be8ce83..44dc50b 100644 --- a/src/utils/inputs.ts +++ b/src/utils/inputs.ts @@ -41,6 +41,7 @@ export interface SetupInputs { manifestFile?: string; addProblemMatchers: boolean; resolutionStrategy: ResolutionStrategy; + useMirror: boolean; } export function loadInputs(): SetupInputs { @@ -73,6 +74,7 @@ export function loadInputs(): SetupInputs { const manifestFile = getManifestFile(); const addProblemMatchers = core.getInput("add-problem-matchers") === "true"; const resolutionStrategy = getResolutionStrategy(); + const useMirror = core.getInput("use-mirror") === "true"; return { activateEnvironment, @@ -95,6 +97,7 @@ export function loadInputs(): SetupInputs { saveCache, toolBinDir, toolDir, + useMirror, venvPath, version, versionFile,