mirror of
https://github.com/actions/setup-go.git
synced 2026-11-15 05:00:35 +08:00
feat: split Go module and build caches
Reuse downloaded modules across Go versions, runner architectures, and runner images on the same OS instead of duplicating them in each build cache archive. Restore and save each entry independently, running operations in parallel when safe. Serialize restores for overlapping or aliased paths, preserve the original paths for the post step, and report cache-hit only when both entries match their primary keys. Update the documented manual restore keys and generated action bundles.
This commit is contained in:
+48
-13
@@ -6,13 +6,19 @@ import fs from 'fs';
|
||||
|
||||
import {State, Outputs} from './constants.js';
|
||||
import {PackageManagerInfo} from './package-managers.js';
|
||||
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils.js';
|
||||
import {
|
||||
CacheEntry,
|
||||
canRestoreCachesInParallel,
|
||||
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;
|
||||
@@ -32,22 +38,51 @@ export const restoreCache = async (
|
||||
|
||||
const linuxVersion =
|
||||
process.env.RUNNER_OS === 'Linux' ? `${process.env.ImageOS}-` : '';
|
||||
const primaryKey = `setup-go-${platform}-${arch}-${linuxVersion}go-${versionSpec}-${fileHash}`;
|
||||
core.debug(`primary key is ${primaryKey}`);
|
||||
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]
|
||||
}));
|
||||
|
||||
core.saveState(State.CachePrimaryKey, primaryKey);
|
||||
const restoreEntry = async (entry: CacheEntry) => {
|
||||
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}`);
|
||||
}
|
||||
};
|
||||
|
||||
const cacheKey = await cache.restoreCache(cachePaths, primaryKey);
|
||||
core.setOutput(Outputs.CacheHit, Boolean(cacheKey));
|
||||
|
||||
if (!cacheKey) {
|
||||
core.info(`Cache is not found`);
|
||||
core.setOutput(Outputs.CacheHit, false);
|
||||
return;
|
||||
if (canRestoreCachesInParallel(entries)) {
|
||||
await Promise.all(entries.map(restoreEntry));
|
||||
} else {
|
||||
for (const entry of entries) {
|
||||
await restoreEntry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
core.saveState(State.CacheMatchedKey, cacheKey);
|
||||
core.info(`Cache restored from key: ${cacheKey}`);
|
||||
// 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) => {
|
||||
|
||||
Reference in New Issue
Block a user