10
0
Fork 0
mirror of https://github.com/actions/setup-go.git synced 2026-04-05 14:26:56 +00:00
setup-go/src/cache-save.ts
Claude cf0b11600c
perf: add cache-build option and upgrade to v6.2.0
Add `cache-build` input (default: false) to control whether GOCACHE is
included in the cache. This dramatically reduces cache size from ~1.2GB
to ~200-400MB by excluding build artifacts that have low reuse across
code changes.

Also upgrades dependencies (@actions/cache v5, semver v7.7) and runtime
to node24 to align with upstream actions/setup-go.

https://claude.ai/code/session_01CqrWSjzGgd7Zi6LyJkd9XW
2026-04-04 17:58:19 +00:00

105 lines
3 KiB
TypeScript

import * as core from '@actions/core';
import * as cache from '@actions/cache';
import fs from 'fs';
import {State} from './constants';
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils';
import {computeMetaHash} from './hashdir';
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
// throw an uncaught exception. Instead of failing this action, just warn.
process.on('uncaughtException', e => {
const warningPrefix = '[warning]';
core.info(`${warningPrefix}${e.message}`);
});
// Added early exit to resolve issue with slow post action step:
// - https://github.com/actions/setup-node/issues/878
// https://github.com/actions/cache/pull/1217
export async function run(earlyExit?: boolean) {
try {
const cacheInput = core.getBooleanInput('cache');
if (cacheInput) {
await cachePackages();
if (earlyExit) {
process.exit(0);
}
}
} catch (error) {
let message = 'Unknown error!';
if (error instanceof Error) {
message = error.message;
}
if (typeof error === 'string') {
message = error;
}
core.warning(message);
}
}
const cachePackages = async () => {
const packageManager = 'default';
const state = core.getState(State.CacheMatchedKey);
const primaryKey = core.getState(State.CachePrimaryKey);
const prevBuildHash = core.getState(State.CacheBuildHash);
const packageManagerInfo = await getPackageManagerInfo(packageManager);
const cacheBuild = core.getBooleanInput('cache-build');
const cachePaths = await getCacheDirectoryPath(
packageManagerInfo,
cacheBuild
);
const nonExistingPaths = cachePaths.filter(
cachePath => !fs.existsSync(cachePath)
);
if (nonExistingPaths.length === cachePaths.length) {
core.warning('There are no cache folders on the disk');
return;
}
if (nonExistingPaths.length) {
logWarning(
`Cache folder path is retrieved but doesn't exist on disk: ${nonExistingPaths.join(
', '
)}`
);
}
if (!primaryKey) {
core.info(
'Primary key was not generated. Please check the log messages above for more errors or information'
);
return;
}
const buildHash =
cachePaths.length > 1 ? computeMetaHash([cachePaths[1]]) : '';
if (primaryKey === state && buildHash === prevBuildHash) {
core.info(
`Cache hit occurred on the primary key ${primaryKey} and build hash ${buildHash}, not saving cache.`
);
return;
}
const updatedKey = primaryKey + (buildHash ? `-${buildHash}` : '');
const start = Date.now();
const cacheId = await cache.saveCache(cachePaths, updatedKey);
core.info(`Time taken to save cache: ${Date.now() - start}ms`);
if (cacheId === -1) {
return;
}
core.info(`Cache saved with the key: ${updatedKey}`);
};
function logWarning(message: string): void {
const warningPrefix = '[warning]';
core.info(`${warningPrefix}${message}`);
}
run(true);