Files
setup-go/src/cache-restore.ts
T
qmuntalandCopilot 57097ea729 refactor: simplify split-cache handling
Restore cache entries sequentially, keep saves parallel with per-entry error handling, and simplify the cache test setup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-11-09 12:29:31 +01:00

93 lines
3.0 KiB
TypeScript

import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import path from 'path';
import fs from 'fs';
import {State, Outputs} from './constants.js';
import {PackageManagerInfo} from './package-managers.js';
import {
CacheEntry,
getCacheDirectoryPath,
getPackageManagerInfo
} from './cache-utils.js';
export const restoreCache = async (
versionSpec: string,
packageManager: string,
cacheDependencyPath?: string
) => {
core.setOutput(Outputs.CacheHit, false);
const packageManagerInfo = await getPackageManagerInfo(packageManager);
const platform = process.env.RUNNER_OS;
const arch = process.arch;
const cachePaths = await getCacheDirectoryPath(packageManagerInfo);
const dependencyFilePath = cacheDependencyPath
? cacheDependencyPath
: findDependencyFile(packageManagerInfo);
const fileHash = await glob.hashFiles(dependencyFilePath);
if (!fileHash) {
throw new Error(
'Some specified paths were not resolved, unable to cache dependencies.'
);
}
const linuxVersion =
process.env.RUNNER_OS === 'Linux' ? `${process.env.ImageOS}-` : '';
const primaryKeys = {
// Downloaded module sources can be reused across Go versions and runner
// architectures. Keep OS isolation for filesystem compatibility.
modules: `setup-go-modules-${platform}-${fileHash}`,
build: `setup-go-build-${platform}-${arch}-${linuxVersion}go-${versionSpec}-${fileHash}`
};
const entries: CacheEntry[] = cachePaths.map(directory => ({
...directory,
primaryKey: primaryKeys[directory.kind]
}));
for (const entry of entries) {
core.debug(`${entry.kind} primary key is ${entry.primaryKey}`);
try {
entry.matchedKey = await cache.restoreCache(
[entry.path],
entry.primaryKey
);
if (entry.matchedKey) {
core.info(`${entry.kind} cache restored from key: ${entry.matchedKey}`);
} else {
core.info(`${entry.kind} cache is not found`);
}
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
core.warning(`Restore ${entry.kind} cache failed: ${message}`);
}
}
// Preserve the resolved paths so the post step uses the same cache versions,
// even if a later step changes the Go environment.
core.saveState(State.CacheEntries, entries);
core.setOutput(
Outputs.CacheHit,
entries.length === packageManagerInfo.cacheFolderCommandList.length &&
entries.every(entry => entry.matchedKey === entry.primaryKey)
);
};
const findDependencyFile = (packageManager: PackageManagerInfo) => {
const dependencyFile = packageManager.dependencyFilePattern;
const workspace = process.env.GITHUB_WORKSPACE!;
const rootContent = fs.readdirSync(workspace);
const goModFileExists = rootContent.includes(dependencyFile);
if (!goModFileExists) {
throw new Error(
`Dependencies file is not found in ${workspace}. Supported file pattern: ${dependencyFile}`
);
}
return path.join(workspace, dependencyFile);
};