mirror of
https://github.com/astral-sh/setup-uv.git
synced 2026-07-07 12:11:34 +00:00
Fix cache keys for Python version ranges (#937)
## Summary - URL-encode the Python version component before adding it to the cache key - URL-encode the user-provided cache suffix for the same reason - Add cache key tests for Python ranges, comma-containing suffixes, and unchanged simple inputs Fixes #914 Refs: pi-session 019f3164-85e7-7817-bffd-501d89b3a1fd ## Tests - npm run all
This commit is contained in:
committed by
GitHub
parent
3cc3c11fdf
commit
17c398959b
74
__tests__/cache/restore-cache.test.ts
vendored
Normal file
74
__tests__/cache/restore-cache.test.ts
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
import { beforeEach, describe, expect, it, jest } from "@jest/globals";
|
||||
import { createSetupInputs } from "../helpers/setup-inputs";
|
||||
|
||||
const mockRestoreCache = jest.fn();
|
||||
const mockSaveState = jest.fn();
|
||||
const mockSetOutput = jest.fn();
|
||||
|
||||
jest.unstable_mockModule("@actions/cache", () => ({
|
||||
restoreCache: mockRestoreCache,
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule("@actions/core", () => ({
|
||||
saveState: mockSaveState,
|
||||
setOutput: mockSetOutput,
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule("../../src/hash/hash-files", () => ({
|
||||
hashFiles: jest.fn(async () => "dependencyhash"),
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule("../../src/utils/logging", () => ({
|
||||
info: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule("../../src/utils/platforms", () => ({
|
||||
getArch: jest.fn(() => "x86_64"),
|
||||
getOSNameVersion: jest.fn(() => "ubuntu-24.04"),
|
||||
getPlatform: jest.fn(async () => "unknown-linux-gnu"),
|
||||
}));
|
||||
|
||||
const { restoreCache } = await import("../../src/cache/restore-cache");
|
||||
|
||||
function cacheKeyOutput(): string {
|
||||
const call = mockSetOutput.mock.calls.find(([name]) => name === "cache-key");
|
||||
expect(call).toBeDefined();
|
||||
return call?.[1] as string;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("restoreCache", () => {
|
||||
it("encodes Python version ranges before adding them to the cache key", async () => {
|
||||
await restoreCache(createSetupInputs(), ">3.10.11,<3.11");
|
||||
|
||||
const cacheKey = cacheKeyOutput();
|
||||
|
||||
expect(cacheKey).not.toContain(",");
|
||||
expect(cacheKey).toContain("-%3E3.10.11%2C%3C3.11-");
|
||||
});
|
||||
|
||||
it("encodes cache suffixes before adding them to the cache key", async () => {
|
||||
const inputs = createSetupInputs({ cacheSuffix: "tests-3.10,3.11" });
|
||||
|
||||
await restoreCache(inputs, "3.11");
|
||||
|
||||
const cacheKey = cacheKeyOutput();
|
||||
|
||||
expect(cacheKey).not.toContain(",");
|
||||
expect(cacheKey).toContain("-tests-3.10%2C3.11");
|
||||
});
|
||||
|
||||
it("keeps cache keys unchanged for exact Python versions and simple suffixes", async () => {
|
||||
const inputs = createSetupInputs({ cacheSuffix: "tests-3.11" });
|
||||
|
||||
await restoreCache(inputs, "3.11");
|
||||
|
||||
expect(cacheKeyOutput()).toBe(
|
||||
"setup-uv-2-x86_64-unknown-linux-gnu-ubuntu-24.04-3.11-pruned-dependencyhash-tests-3.11",
|
||||
);
|
||||
});
|
||||
});
|
||||
36
__tests__/helpers/setup-inputs.ts
Normal file
36
__tests__/helpers/setup-inputs.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { CacheLocalSource, type SetupInputs } from "../../src/utils/inputs";
|
||||
|
||||
export function createSetupInputs(
|
||||
overrides: Partial<SetupInputs> = {},
|
||||
): SetupInputs {
|
||||
return {
|
||||
activateEnvironment: false,
|
||||
addProblemMatchers: false,
|
||||
cacheDependencyGlob: "uv.lock",
|
||||
cacheLocalPath: {
|
||||
path: "/tmp/setup-uv-cache",
|
||||
source: CacheLocalSource.Input,
|
||||
},
|
||||
cachePython: false,
|
||||
cacheSuffix: "",
|
||||
checksum: "",
|
||||
downloadFromAstralMirror: false,
|
||||
enableCache: true,
|
||||
githubToken: "",
|
||||
ignoreEmptyWorkdir: false,
|
||||
ignoreNothingToCache: false,
|
||||
noProject: false,
|
||||
pruneCache: true,
|
||||
pythonDir: "/tmp/uv-python-dir",
|
||||
pythonVersion: "",
|
||||
quiet: false,
|
||||
resolutionStrategy: "highest",
|
||||
restoreCache: false,
|
||||
saveCache: true,
|
||||
venvPath: "/workspace/.venv",
|
||||
version: "",
|
||||
versionFile: "",
|
||||
workingDirectory: "/workspace",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
4
dist/setup/index.cjs
generated
vendored
4
dist/setup/index.cjs
generated
vendored
@@ -90621,8 +90621,8 @@ async function computeKeys(inputs, pythonVersion) {
|
||||
if (cacheDependencyPathHash === "-") {
|
||||
cacheDependencyPathHash = "-no-dependency-glob";
|
||||
}
|
||||
const suffix = inputs.cacheSuffix ? `-${inputs.cacheSuffix}` : "";
|
||||
const version3 = pythonVersion ?? "unknown";
|
||||
const suffix = inputs.cacheSuffix ? `-${encodeURIComponent(inputs.cacheSuffix)}` : "";
|
||||
const version3 = encodeURIComponent(pythonVersion ?? "unknown");
|
||||
const platform2 = await getPlatform();
|
||||
const osNameVersion = getOSNameVersion();
|
||||
const pruned = inputs.pruneCache ? "-pruned" : "";
|
||||
|
||||
6
src/cache/restore-cache.ts
vendored
6
src/cache/restore-cache.ts
vendored
@@ -94,8 +94,10 @@ async function computeKeys(
|
||||
if (cacheDependencyPathHash === "-") {
|
||||
cacheDependencyPathHash = "-no-dependency-glob";
|
||||
}
|
||||
const suffix = inputs.cacheSuffix ? `-${inputs.cacheSuffix}` : "";
|
||||
const version = pythonVersion ?? "unknown";
|
||||
const suffix = inputs.cacheSuffix
|
||||
? `-${encodeURIComponent(inputs.cacheSuffix)}`
|
||||
: "";
|
||||
const version = encodeURIComponent(pythonVersion ?? "unknown");
|
||||
const platform = await getPlatform();
|
||||
const osNameVersion = getOSNameVersion();
|
||||
const pruned = inputs.pruneCache ? "-pruned" : "";
|
||||
|
||||
Reference in New Issue
Block a user