Files
setup-uv/src/save-cache.ts
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

100 lines
3.1 KiB
TypeScript
Raw Normal View History

2025-08-12 22:12:10 +02:00
import * as fs from "node:fs";
2024-09-05 08:06:45 -04:00
import * as cache from "@actions/cache";
import * as core from "@actions/core";
import * as exec from "@actions/exec";
import {
STATE_CACHE_KEY,
2025-08-12 22:12:10 +02:00
STATE_CACHE_MATCHED_KEY,
2024-09-05 08:06:45 -04:00
} from "./cache/restore-cache";
2025-10-02 17:54:15 +02:00
import { STATE_UV_PATH } from "./utils/constants";
import {
cacheLocalPath,
enableCache,
ignoreNothingToCache,
pruneCache as shouldPruneCache,
saveCache as shouldSaveCache,
} from "./utils/inputs";
2024-08-23 23:58:26 +02:00
export async function run(): Promise<void> {
try {
if (enableCache) {
if (shouldSaveCache) {
await saveCache();
} else {
core.info("save-cache is false. Skipping save cache step.");
}
// node will stay alive if any promises are not resolved,
// which is a possibility if HTTP requests are dangling
// due to retries or timeouts. We know that if we got here
// that all promises that we care about have successfully
// resolved, so simply exit with success.
process.exit(0);
2024-08-23 23:58:26 +02:00
}
} catch (error) {
2024-09-05 08:06:45 -04:00
const err = error as Error;
core.setFailed(err.message);
2024-08-23 23:58:26 +02:00
}
}
async function saveCache(): Promise<void> {
2024-09-05 08:06:45 -04:00
const cacheKey = core.getState(STATE_CACHE_KEY);
const matchedKey = core.getState(STATE_CACHE_MATCHED_KEY);
2024-08-23 23:58:26 +02:00
if (!cacheKey) {
2024-09-05 08:06:45 -04:00
core.warning("Error retrieving cache key from state.");
return;
}
if (matchedKey === cacheKey) {
2024-09-05 08:06:45 -04:00
core.info(`Cache hit occurred on key ${cacheKey}, not saving cache.`);
return;
2024-08-23 23:58:26 +02:00
}
2024-08-24 10:08:12 +02:00
if (shouldPruneCache) {
await pruneCache();
}
2024-08-24 10:08:12 +02:00
2025-10-02 08:50:15 -07:00
let actualCachePath = cacheLocalPath;
if (process.env.UV_CACHE_DIR && process.env.UV_CACHE_DIR !== cacheLocalPath) {
core.warning(
`The environment variable UV_CACHE_DIR has been changed to "${process.env.UV_CACHE_DIR}", by an action or step running after astral-sh/setup-uv. This can lead to unexpected behavior. If you expected this to happen set the cache-local-path input to "${process.env.UV_CACHE_DIR}" instead of "${cacheLocalPath}".`,
);
actualCachePath = process.env.UV_CACHE_DIR;
}
core.info(`Saving cache path: ${actualCachePath}`);
if (!fs.existsSync(actualCachePath) && !ignoreNothingToCache) {
throw new Error(
2025-10-02 08:50:15 -07:00
`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.`,
);
}
try {
2025-10-02 08:50:15 -07:00
await cache.saveCache([actualCachePath], cacheKey);
core.info(`cache saved with the 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 paths were found. Ignoring because ignore-nothing-to-save is enabled.",
);
} else {
throw e;
}
}
2024-08-23 23:58:26 +02:00
}
2024-08-24 10:08:12 +02:00
async function pruneCache(): Promise<void> {
const options: exec.ExecOptions = {
2025-09-30 17:05:27 +02:00
silent: false,
2024-09-05 08:06:45 -04:00
};
const execArgs = ["cache", "prune", "--ci"];
2024-08-24 10:08:12 +02:00
2024-09-05 08:06:45 -04:00
core.info("Pruning cache...");
2025-10-02 17:54:15 +02:00
const uvPath = core.getState(STATE_UV_PATH);
await exec.exec(uvPath, execArgs, options);
2024-08-24 10:08:12 +02:00
}
2024-09-05 08:06:45 -04:00
run();