Include env vars in the generated cache key

This commit is contained in:
Dominik Nakamura 2021-10-07 11:35:31 +09:00 committed by Arpad Borsos
parent 81d053bdb0
commit fa61956921
No known key found for this signature in database
GPG Key ID: FC7BCA77824B3298
3 changed files with 50 additions and 1 deletions

View File

@ -26,6 +26,10 @@ An optional key that is added to the automatic cache key.
: `sharedKey`
An additional key that is stable over multiple jobs.
: `envVars`
A space-separated list of regular expressions that define additional environment variable filters.
These are added to an additional cache key that's generated from environment variable contents.
: `working-directory`
The working directory the action operates in, is case the cargo project is not
located in the repo root.

View File

@ -8,6 +8,9 @@ inputs:
sharedKey:
description: "An additional cache key that is stable over multiple jobs"
required: false
envVars:
description: "Additional environment variables to include in the cache key, separeted by spaces"
required: false
working-directory:
description: "The working directory this action should operate in"
required: false

View File

@ -71,6 +71,9 @@ export async function getCacheConfig(): Promise<CacheConfig> {
}
}
const extraEnvKeys = core.getInput("envVars").split(/\s+/);
key += `${getEnvKey(extraEnvKeys)}-`;
key += await getRustKey();
return {
@ -105,6 +108,45 @@ export async function getCargoBins(): Promise<Set<string>> {
}
}
/**
* Create a key hash, generated from environment variables.
*
* The available environment variables are filtered by a set of defaults that are common for Rust
* projects and should apply to almost all runs, as they modify the Rustc compiler's, Clippy's and
* other tools' behavior.
*
* @param extraKeys additional user-provided keys that are added to the default list. These are
* treated as regular expressions ({@link RegExp}), and will each be surrounded by a `^` and `$`,
* to make sure they are matched against the whole env var name.
* @returns An SHA-1 hash over all the environment variable values, whose names were not filtered
* out. The hash is returned as hex-string, **reduced to half its length**.
*/
function getEnvKey(extraKeys: string[]): string {
const hasher = crypto.createHash("sha1");
const defaultValidKeys = [
/^CARGO_.+$/,
/^CC_.+$/,
/^CXX_.+$/,
/^RUSTC_.+$/,
/^RUSTC$/,
/^RUSTDOC$/,
/^RUSTDOCFLAGS$/,
/^RUSTFLAGS$/,
/^RUSTFMT$/,
];
// Combine default key filters with user-provided ones.
const keyFilter = defaultValidKeys.concat(extraKeys.map((key) => new RegExp(`^${key}$`)));
for (const [key, value] of Object.entries(process.env)) {
if (keyFilter.some((re) => re.test(key)) && value) {
hasher.update(`${key}=${value}`);
}
}
return hasher.digest("hex").slice(0, 20);
}
async function getRustKey(): Promise<string> {
const rustc = await getRustVersion();
return `${rustc.release}-${rustc.host}-${rustc["commit-hash"].slice(0, 12)}`;