2024-09-05 08:06:45 -04:00
import * as cache from "@actions/cache" ;
import * as core from "@actions/core" ;
2025-08-12 22:12:10 +02:00
import { hashFiles } from "../hash/hash-files" ;
2026-03-28 16:23:26 +01:00
import type { SetupInputs } from "../utils/inputs" ;
2026-05-31 21:13:30 +02:00
import * as log from "../utils/logging" ;
2025-12-13 17:25:42 +01:00
import { getArch , getOSNameVersion , getPlatform } from "../utils/platforms" ;
2024-08-23 23:58:26 +02:00
2024-09-05 08:06:45 -04:00
export const STATE_CACHE_KEY = "cache-key" ;
export const STATE_CACHE_MATCHED_KEY = "cache-matched-key" ;
2026-01-06 18:06:29 +01:00
export const STATE_PYTHON_CACHE_MATCHED_KEY = "python-cache-matched-key" ;
2025-12-13 17:25:42 +01:00
const CACHE_VERSION = "2" ;
2024-08-23 23:58:26 +02:00
2026-03-28 16:23:26 +01:00
export async function restoreCache (
inputs : SetupInputs ,
pythonVersion? : string ,
) : Promise < void > {
const cacheKey = await computeKeys ( inputs , pythonVersion );
2025-09-14 14:55:08 +02:00
core . saveState ( STATE_CACHE_KEY , cacheKey );
2025-12-13 17:25:42 +01:00
core . setOutput ( "cache-key" , cacheKey );
2025-09-14 14:55:08 +02:00
2026-03-28 16:23:26 +01:00
if ( ! inputs . restoreCache ) {
2026-05-31 21:13:30 +02:00
log . info ( "restore-cache is false. Skipping restore cache step." );
2026-01-06 18:06:29 +01:00
core . setOutput ( "python-cache-hit" , false );
2025-09-14 14:55:08 +02:00
return ;
}
2024-08-23 23:58:26 +02:00
2026-03-28 16:23:26 +01:00
if ( inputs . cacheLocalPath === undefined ) {
2025-12-07 17:52:54 +01:00
throw new Error (
"cache-local-path is not set. Cannot restore cache without a valid cache path." ,
);
}
2026-01-06 18:06:29 +01:00
await restoreCacheFromKey (
cacheKey ,
2026-03-28 16:23:26 +01:00
inputs . cacheLocalPath . path ,
2026-01-06 18:06:29 +01:00
STATE_CACHE_MATCHED_KEY ,
"cache-hit" ,
);
2026-03-28 16:23:26 +01:00
if ( inputs . cachePython ) {
2026-01-06 18:06:29 +01:00
await restoreCacheFromKey (
` ${ cacheKey } -python` ,
2026-03-28 16:23:26 +01:00
inputs . pythonDir ,
2026-01-06 18:06:29 +01:00
STATE_PYTHON_CACHE_MATCHED_KEY ,
"python-cache-hit" ,
);
} else {
core . setOutput ( "python-cache-hit" , false );
2025-10-09 16:47:24 -04:00
}
2026-01-06 18:06:29 +01:00
}
async function restoreCacheFromKey (
cacheKey : string ,
cachePath : string ,
stateKey : string ,
outputKey : string ,
) : Promise < void > {
2026-05-31 21:13:30 +02:00
log . info (
2026-01-06 18:06:29 +01:00
`Trying to restore cache from GitHub Actions cache with key: ${ cacheKey } ` ,
);
let matchedKey : string | undefined ;
2024-08-23 23:58:26 +02:00
try {
2026-01-06 18:06:29 +01:00
matchedKey = await cache . restoreCache ([ cachePath ], cacheKey );
2024-08-23 23:58:26 +02:00
} catch ( err ) {
2024-09-05 08:06:45 -04:00
const message = ( err as Error ). message ;
2026-05-31 21:13:30 +02:00
log . warning ( message );
2026-01-06 18:06:29 +01:00
core . setOutput ( outputKey , false );
2024-09-05 08:06:45 -04:00
return ;
2024-08-23 23:58:26 +02:00
}
2026-01-06 18:06:29 +01:00
handleMatchResult ( matchedKey , cacheKey , stateKey , outputKey );
2024-08-23 23:58:26 +02:00
}
2026-03-28 16:23:26 +01:00
async function computeKeys (
inputs : SetupInputs ,
pythonVersion? : string ,
) : Promise < string > {
2024-09-05 08:06:45 -04:00
let cacheDependencyPathHash = "-" ;
2026-03-28 16:23:26 +01:00
if ( inputs . cacheDependencyGlob !== "" ) {
2026-05-31 21:13:30 +02:00
log . info (
2026-03-28 16:23:26 +01:00
`Searching files using cache dependency glob: ${ inputs . cacheDependencyGlob . split ( "\n" ). join ( "," ) } ` ,
);
cacheDependencyPathHash += await hashFiles (
inputs . cacheDependencyGlob ,
true ,
2024-09-06 14:44:31 +02:00
);
2024-09-05 08:06:45 -04:00
if ( cacheDependencyPathHash === "-" ) {
2026-05-31 21:13:30 +02:00
log . warning (
2026-03-28 16:23:26 +01:00
`No file matched to [ ${ inputs . cacheDependencyGlob . split ( "\n" ). join ( "," ) } ]. The cache will never get invalidated. Make sure you have checked out the target repository and configured the cache-dependency-glob input correctly.` ,
2024-09-05 08:06:45 -04:00
);
2024-08-23 23:58:26 +02:00
}
2024-12-20 11:42:38 +01:00
}
if ( cacheDependencyPathHash === "-" ) {
2024-12-20 11:32:52 +01:00
cacheDependencyPathHash = "-no-dependency-glob" ;
2024-08-23 23:58:26 +02:00
}
2026-03-28 16:23:26 +01:00
const suffix = inputs . cacheSuffix ? `- ${ inputs . cacheSuffix } ` : "" ;
2026-01-06 18:06:29 +01:00
const version = pythonVersion ?? "unknown" ;
2025-02-17 10:32:34 +01:00
const platform = await getPlatform ();
2025-12-13 17:25:42 +01:00
const osNameVersion = getOSNameVersion ();
2026-03-28 16:23:26 +01:00
const pruned = inputs . pruneCache ? "-pruned" : "" ;
const python = inputs . cachePython ? "-py" : "" ;
2026-01-06 18:06:29 +01:00
return `setup-uv- ${ CACHE_VERSION } - ${ getArch () } - ${ platform } - ${ osNameVersion } - ${ version }${ pruned }${ python }${ cacheDependencyPathHash }${ suffix } ` ;
2024-08-23 23:58:26 +02:00
}
function handleMatchResult (
matchedKey : string | undefined ,
2024-09-05 08:06:45 -04:00
primaryKey : string ,
2026-01-06 18:06:29 +01:00
stateKey : string ,
outputKey : string ,
2024-08-23 23:58:26 +02:00
) : void {
if ( ! matchedKey ) {
2026-05-31 21:13:30 +02:00
log . info ( `No GitHub Actions cache found for key: ${ primaryKey } ` );
2026-01-06 18:06:29 +01:00
core . setOutput ( outputKey , false );
2024-09-05 08:06:45 -04:00
return ;
2024-08-23 23:58:26 +02:00
}
2026-01-06 18:06:29 +01:00
core . saveState ( stateKey , matchedKey );
2026-05-31 21:13:30 +02:00
log . info ( `cache restored from GitHub Actions cache with key: ${ matchedKey } ` );
2026-01-06 18:06:29 +01:00
core . setOutput ( outputKey , true );
2024-08-23 23:58:26 +02:00
}