fix: warn instead of error when no python to cache (#762)

Fixes: #754
This commit is contained in:
Kevin Stillhammer 2026-02-06 16:00:33 +01:00 committed by GitHub
parent a3b3eaea92
commit 02182fa02a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 74 additions and 49 deletions

View file

@ -878,6 +878,29 @@ jobs:
exit 1 exit 1
fi fi
test-cache-python-missing-managed-install-dir:
runs-on: ubuntu-latest
env:
UV_PYTHON_INSTALL_DIR: /tmp/missing-uv-python
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Setup uv with cache and python cache enabled
uses: ./
with:
enable-cache: true
cache-python: true
python-version: "3.12"
cache-local-path: /tmp/setup-uv-cache
cache-suffix: ${{ github.run_id }}-${{ github.run_attempt }}-test-cache-python-missing-managed-install-dir
- name: Ensure uv cache dir exists so only python-cache behavior is tested
run: uv sync
working-directory: __tests__/fixtures/uv-project
shell: bash
- name: Ensure managed Python install dir does not exist and this does not break caching
run: rm -rf "$UV_PYTHON_INSTALL_DIR"
test-cache-python-installs: test-cache-python-installs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -1029,6 +1052,7 @@ jobs:
- test-relative-path - test-relative-path
- test-cache-prune-force - test-cache-prune-force
- test-cache-dir-from-file - test-cache-dir-from-file
- test-cache-python-missing-managed-install-dir
- test-cache-python-installs - test-cache-python-installs
- test-restore-python-installs - test-restore-python-installs
- test-python-install-dir - test-python-install-dir

35
dist/save-cache/index.js generated vendored
View file

@ -90852,11 +90852,25 @@ async function saveCache() {
await pruneCache(); await pruneCache();
} }
const actualCachePath = getUvCachePath(); const actualCachePath = getUvCachePath();
await saveCacheToKey(cacheKey, actualCachePath, restore_cache_1.STATE_CACHE_MATCHED_KEY, "uv cache", `Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`); if (!fs.existsSync(actualCachePath)) {
if (inputs_1.ignoreNothingToCache) {
core.info("No cacheable uv cache paths were found. Ignoring because ignore-nothing-to-cache is enabled.");
}
else {
throw new Error(`Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`);
}
}
else {
await saveCacheToKey(cacheKey, actualCachePath, restore_cache_1.STATE_CACHE_MATCHED_KEY, "uv cache");
}
} }
if (inputs_1.cachePython) { if (inputs_1.cachePython) {
if (!fs.existsSync(inputs_1.pythonDir)) {
core.warning(`Python cache path ${inputs_1.pythonDir} does not exist on disk. Skipping Python cache save because no managed Python installation was found. If you want uv to install managed Python instead of using a system interpreter, set UV_PYTHON_PREFERENCE=only-managed.`);
return;
}
const pythonCacheKey = `${cacheKey}-python`; const pythonCacheKey = `${cacheKey}-python`;
await saveCacheToKey(pythonCacheKey, inputs_1.pythonDir, restore_cache_1.STATE_PYTHON_CACHE_MATCHED_KEY, "Python cache", `Python cache path ${inputs_1.pythonDir} does not exist on disk. This likely indicates that there are no Python installations to cache. Consider disabling the cache input if it is not needed.`); await saveCacheToKey(pythonCacheKey, inputs_1.pythonDir, restore_cache_1.STATE_PYTHON_CACHE_MATCHED_KEY, "Python cache");
} }
} }
async function pruneCache() { async function pruneCache() {
@ -90883,31 +90897,16 @@ function getUvCachePath() {
} }
return inputs_1.cacheLocalPath.path; return inputs_1.cacheLocalPath.path;
} }
async function saveCacheToKey(cacheKey, cachePath, stateKey, cacheName, pathNotExistErrorMessage) { async function saveCacheToKey(cacheKey, cachePath, stateKey, cacheName) {
const matchedKey = core.getState(stateKey); const matchedKey = core.getState(stateKey);
if (matchedKey === cacheKey) { if (matchedKey === cacheKey) {
core.info(`${cacheName} hit occurred on key ${cacheKey}, not saving cache.`); core.info(`${cacheName} hit occurred on key ${cacheKey}, not saving cache.`);
return; return;
} }
core.info(`Including ${cacheName} path: ${cachePath}`); core.info(`Including ${cacheName} path: ${cachePath}`);
if (!fs.existsSync(cachePath) && !inputs_1.ignoreNothingToCache) {
throw new Error(pathNotExistErrorMessage);
}
try {
await cache.saveCache([cachePath], cacheKey); await cache.saveCache([cachePath], cacheKey);
core.info(`${cacheName} saved with key: ${cacheKey}`); core.info(`${cacheName} saved with key: ${cacheKey}`);
} }
catch (e) {
if (e instanceof Error &&
e.message ===
"Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved.") {
core.info(`No cacheable ${cacheName} paths were found. Ignoring because ignore-nothing-to-save is enabled.`);
}
else {
throw e;
}
}
}
run(); run();

View file

@ -199,6 +199,10 @@ By default, the Python install dir (`uv python dir` / `UV_PYTHON_INSTALL_DIR`) i
for the same reason that the dependency cache is pruned. for the same reason that the dependency cache is pruned.
If you want to cache Python installs along with your dependencies, set the `cache-python` input to `true`. If you want to cache Python installs along with your dependencies, set the `cache-python` input to `true`.
Note that this only caches Python versions that uv actually installs into `UV_PYTHON_INSTALL_DIR`
(i.e. managed Python installs). If uv uses a system Python, there may be nothing to cache.
To force managed Python installs, set `UV_PYTHON_PREFERENCE=only-managed`.
```yaml ```yaml
- name: Cache Python installs - name: Cache Python installs
uses: astral-sh/setup-uv@v7 uses: astral-sh/setup-uv@v7

View file

@ -59,23 +59,40 @@ async function saveCache(): Promise<void> {
} }
const actualCachePath = getUvCachePath(); const actualCachePath = getUvCachePath();
if (!fs.existsSync(actualCachePath)) {
if (ignoreNothingToCache) {
core.info(
"No cacheable uv cache paths were found. Ignoring because ignore-nothing-to-cache is enabled.",
);
} else {
throw new Error(
`Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`,
);
}
} else {
await saveCacheToKey( await saveCacheToKey(
cacheKey, cacheKey,
actualCachePath, actualCachePath,
STATE_CACHE_MATCHED_KEY, STATE_CACHE_MATCHED_KEY,
"uv cache", "uv cache",
`Cache path ${actualCachePath} does not exist on disk. This likely indicates that there are no dependencies to cache. Consider disabling the cache input if it is not needed.`,
); );
} }
}
if (cachePython) { if (cachePython) {
if (!fs.existsSync(pythonDir)) {
core.warning(
`Python cache path ${pythonDir} does not exist on disk. Skipping Python cache save because no managed Python installation was found. If you want uv to install managed Python instead of using a system interpreter, set UV_PYTHON_PREFERENCE=only-managed.`,
);
return;
}
const pythonCacheKey = `${cacheKey}-python`; const pythonCacheKey = `${cacheKey}-python`;
await saveCacheToKey( await saveCacheToKey(
pythonCacheKey, pythonCacheKey,
pythonDir, pythonDir,
STATE_PYTHON_CACHE_MATCHED_KEY, STATE_PYTHON_CACHE_MATCHED_KEY,
"Python cache", "Python cache",
`Python cache path ${pythonDir} does not exist on disk. This likely indicates that there are no Python installations to cache. Consider disabling the cache input if it is not needed.`,
); );
} }
} }
@ -119,7 +136,6 @@ async function saveCacheToKey(
cachePath: string, cachePath: string,
stateKey: string, stateKey: string,
cacheName: string, cacheName: string,
pathNotExistErrorMessage: string,
): Promise<void> { ): Promise<void> {
const matchedKey = core.getState(stateKey); const matchedKey = core.getState(stateKey);
@ -131,26 +147,8 @@ async function saveCacheToKey(
} }
core.info(`Including ${cacheName} path: ${cachePath}`); core.info(`Including ${cacheName} path: ${cachePath}`);
if (!fs.existsSync(cachePath) && !ignoreNothingToCache) {
throw new Error(pathNotExistErrorMessage);
}
try {
await cache.saveCache([cachePath], cacheKey); await cache.saveCache([cachePath], cacheKey);
core.info(`${cacheName} saved with key: ${cacheKey}`); core.info(`${cacheName} saved with key: ${cacheKey}`);
} catch (e) {
if (
e instanceof Error &&
e.message ===
"Path Validation Error: Path(s) specified in the action for caching do(es) not exist, hence no cache is being saved."
) {
core.info(
`No cacheable ${cacheName} paths were found. Ignoring because ignore-nothing-to-save is enabled.`,
);
} else {
throw e;
}
}
} }
run(); run();