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` : `sharedKey`
An additional key that is stable over multiple jobs. 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` : `working-directory`
The working directory the action operates in, is case the cargo project is not The working directory the action operates in, is case the cargo project is not
located in the repo root. located in the repo root.

View File

@ -8,6 +8,9 @@ inputs:
sharedKey: sharedKey:
description: "An additional cache key that is stable over multiple jobs" description: "An additional cache key that is stable over multiple jobs"
required: false required: false
envVars:
description: "Additional environment variables to include in the cache key, separeted by spaces"
required: false
working-directory: working-directory:
description: "The working directory this action should operate in" description: "The working directory this action should operate in"
required: false 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(); key += await getRustKey();
return { 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> { async function getRustKey(): Promise<string> {
const rustc = await getRustVersion(); const rustc = await getRustVersion();
return `${rustc.release}-${rustc.host}-${rustc["commit-hash"].slice(0, 12)}`; return `${rustc.release}-${rustc.host}-${rustc["commit-hash"].slice(0, 12)}`;
@ -261,5 +303,5 @@ export async function rm(parent: string, dirent: fs.Dirent) {
} else if (dirent.isDirectory()) { } else if (dirent.isDirectory()) {
await io.rmRF(fileName); await io.rmRF(fileName);
} }
} catch {} } catch { }
} }