diff --git a/README.md b/README.md index ccb16f8..a3f3cd6 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/action.yml b/action.yml index d20981c..ee9362d 100644 --- a/action.yml +++ b/action.yml @@ -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 diff --git a/src/common.ts b/src/common.ts index 63236b9..a27c74a 100644 --- a/src/common.ts +++ b/src/common.ts @@ -71,7 +71,9 @@ export async function getCacheConfig(): Promise { } } - key += `${getEnvKey()}-`; + const extraEnvKeys = core.getInput("envVars").split(/\s+/); + + key += `${getEnvKey(extraEnvKeys)}-`; key += await getRustKey(); return { @@ -106,9 +108,22 @@ export async function getCargoBins(): Promise> { } } -function getEnvKey(): 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 validKeys = [ + const defaultValidKeys = [ /^CARGO_.+$/, /^CC_.+$/, /^CXX_.+$/, @@ -120,8 +135,11 @@ function getEnvKey(): string { /^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 (validKeys.some((re) => re.test(key)) && value) { + if (keyFilter.some((re) => re.test(key)) && value) { hasher.update(`${key}=${value}`); } }