Consider all installed toolchains in cache key (#293)

This commit is contained in:
Tamir Duberstein
2025-12-16 12:30:13 +01:00
committed by GitHub
parent 0aa729bb7a
commit 5e4a767433
4 changed files with 162 additions and 54 deletions

68
dist/restore/index.js vendored
View File

@@ -149504,6 +149504,8 @@ var external_crypto_default = /*#__PURE__*/__nccwpck_require__.n(external_crypto
// EXTERNAL MODULE: external "fs/promises"
var promises_ = __nccwpck_require__(91943);
var promises_default = /*#__PURE__*/__nccwpck_require__.n(promises_);
;// CONCATENATED MODULE: external "stream/promises"
const external_stream_promises_namespaceObject = require("stream/promises");
// EXTERNAL MODULE: external "os"
var external_os_ = __nccwpck_require__(70857);
var external_os_default = /*#__PURE__*/__nccwpck_require__.n(external_os_);
@@ -150783,6 +150785,7 @@ class Workspace {
const HOME = external_os_default().homedir();
const config_CARGO_HOME = process.env.CARGO_HOME || external_path_default().join(HOME, ".cargo");
const STATE_CONFIG = "RUST_CACHE_CONFIG";
@@ -150806,7 +150809,7 @@ class CacheConfig {
/** The prefix portion of the cache key */
this.keyPrefix = "";
/** The rust version considered for the cache key */
this.keyRust = "";
this.keyRust = [];
/** The environment variables considered for the cache key */
this.keyEnvs = [];
/** The files considered for the cache key */
@@ -150860,12 +150863,15 @@ class CacheConfig {
// The env vars are sorted, matched by prefix and hashed into the
// resulting environment hash.
let hasher = external_crypto_default().createHash("sha1");
const rustVersion = await getRustVersion(cmdFormat);
let keyRust = `${rustVersion.release} ${rustVersion.host}`;
hasher.update(keyRust);
hasher.update(rustVersion["commit-hash"]);
keyRust += ` (${rustVersion["commit-hash"]})`;
self.keyRust = keyRust;
const rustVersions = Array.from(await getRustVersions(cmdFormat));
// Doesn't matter how they're sorted, just as long as it's deterministic.
rustVersions.sort();
for (const rustVersion of rustVersions) {
const { release, host, "commit-hash": commitHash } = rustVersion;
const keyRust = `${release} ${host} ${commitHash}`;
hasher.update(keyRust);
self.keyRust.push(keyRust);
}
// these prefixes should cover most of the compiler / rust / cargo keys
const envPrefixes = ["CARGO", "CC", "CFLAGS", "CXX", "CMAKE", "RUST"];
envPrefixes.push(...lib_core.getInput("env-vars").split(/\s+/).filter(Boolean));
@@ -150980,9 +150986,7 @@ class CacheConfig {
}
keyFiles = sort_and_uniq(keyFiles);
for (const file of keyFiles) {
for await (const chunk of external_fs_default().createReadStream(file)) {
hasher.update(chunk);
}
await (0,external_stream_promises_namespaceObject.pipeline)((0,external_fs_.createReadStream)(file), hasher);
}
keyFiles.push(...parsedKeyFiles);
self.keyFiles = sort_and_uniq(keyFiles);
@@ -151051,7 +151055,10 @@ class CacheConfig {
lib_core.info(`.. Prefix:`);
lib_core.info(` - ${this.keyPrefix}`);
lib_core.info(`.. Environment considered:`);
lib_core.info(` - Rust Version: ${this.keyRust}`);
lib_core.info(` - Rust Versions:`);
for (const rust of this.keyRust) {
lib_core.info(` - ${rust}`);
}
for (const env of this.keyEnvs) {
lib_core.info(` - ${env}`);
}
@@ -151086,9 +151093,31 @@ function isCacheUpToDate() {
function digest(hasher) {
return hasher.digest("hex").substring(0, HASH_LENGTH);
}
async function getRustVersion(cmdFormat) {
const stdout = await getCmdOutput(cmdFormat, "rustc -vV");
let splits = stdout
async function getRustVersions(cmdFormat) {
const versions = new Set();
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, "rustc -vV")));
const stdout = await (async () => {
try {
return await getCmdOutput(cmdFormat, "rustup toolchain list --quiet");
}
catch (e) {
lib_core.warning(`Error running rustup toolchain list, falling back to default toolchain only: ${e}`);
return undefined;
}
})();
if (stdout !== undefined) {
for (const toolchain of stdout.split(/[\n\r]+/)) {
const trimmed = toolchain.trim();
if (!trimmed) {
continue;
}
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, `rustup run ${toolchain} rustc -vV`)));
}
}
return versions;
}
function parseRustVersion(stdout) {
const splits = stdout
.split(/[\n\r]+/)
.filter(Boolean)
.map((s) => s.split(":").map((s) => s.trim()))
@@ -151099,10 +151128,17 @@ async function globFiles(pattern) {
const globber = await glob.create(pattern, {
followSymbolicLinks: false,
});
// fs.statSync resolve the symbolic link and returns stat for the
// fs.stat resolve the symbolic link and returns stat for the
// file it pointed to, so isFile would make sure the resolved
// file is actually a regular file.
return (await globber.glob()).filter((file) => external_fs_default().statSync(file).isFile());
const files = [];
for (const file of await globber.glob()) {
const stats = await promises_default().stat(file);
if (stats.isFile()) {
files.push(file);
}
}
return files;
}
function sort_and_uniq(a) {
return a

68
dist/save/index.js vendored
View File

@@ -149506,6 +149506,8 @@ var external_crypto_default = /*#__PURE__*/__nccwpck_require__.n(external_crypto
// EXTERNAL MODULE: external "fs/promises"
var promises_ = __nccwpck_require__(91943);
var promises_default = /*#__PURE__*/__nccwpck_require__.n(promises_);
;// CONCATENATED MODULE: external "stream/promises"
const external_stream_promises_namespaceObject = require("stream/promises");
// EXTERNAL MODULE: external "os"
var external_os_ = __nccwpck_require__(70857);
var external_os_default = /*#__PURE__*/__nccwpck_require__.n(external_os_);
@@ -150783,6 +150785,7 @@ class Workspace {
const HOME = external_os_default().homedir();
const CARGO_HOME = process.env.CARGO_HOME || external_path_default().join(HOME, ".cargo");
const STATE_CONFIG = "RUST_CACHE_CONFIG";
@@ -150806,7 +150809,7 @@ class CacheConfig {
/** The prefix portion of the cache key */
this.keyPrefix = "";
/** The rust version considered for the cache key */
this.keyRust = "";
this.keyRust = [];
/** The environment variables considered for the cache key */
this.keyEnvs = [];
/** The files considered for the cache key */
@@ -150860,12 +150863,15 @@ class CacheConfig {
// The env vars are sorted, matched by prefix and hashed into the
// resulting environment hash.
let hasher = external_crypto_default().createHash("sha1");
const rustVersion = await getRustVersion(cmdFormat);
let keyRust = `${rustVersion.release} ${rustVersion.host}`;
hasher.update(keyRust);
hasher.update(rustVersion["commit-hash"]);
keyRust += ` (${rustVersion["commit-hash"]})`;
self.keyRust = keyRust;
const rustVersions = Array.from(await getRustVersions(cmdFormat));
// Doesn't matter how they're sorted, just as long as it's deterministic.
rustVersions.sort();
for (const rustVersion of rustVersions) {
const { release, host, "commit-hash": commitHash } = rustVersion;
const keyRust = `${release} ${host} ${commitHash}`;
hasher.update(keyRust);
self.keyRust.push(keyRust);
}
// these prefixes should cover most of the compiler / rust / cargo keys
const envPrefixes = ["CARGO", "CC", "CFLAGS", "CXX", "CMAKE", "RUST"];
envPrefixes.push(...core.getInput("env-vars").split(/\s+/).filter(Boolean));
@@ -150980,9 +150986,7 @@ class CacheConfig {
}
keyFiles = sort_and_uniq(keyFiles);
for (const file of keyFiles) {
for await (const chunk of external_fs_default().createReadStream(file)) {
hasher.update(chunk);
}
await (0,external_stream_promises_namespaceObject.pipeline)((0,external_fs_.createReadStream)(file), hasher);
}
keyFiles.push(...parsedKeyFiles);
self.keyFiles = sort_and_uniq(keyFiles);
@@ -151051,7 +151055,10 @@ class CacheConfig {
core.info(`.. Prefix:`);
core.info(` - ${this.keyPrefix}`);
core.info(`.. Environment considered:`);
core.info(` - Rust Version: ${this.keyRust}`);
core.info(` - Rust Versions:`);
for (const rust of this.keyRust) {
core.info(` - ${rust}`);
}
for (const env of this.keyEnvs) {
core.info(` - ${env}`);
}
@@ -151086,9 +151093,31 @@ function isCacheUpToDate() {
function digest(hasher) {
return hasher.digest("hex").substring(0, HASH_LENGTH);
}
async function getRustVersion(cmdFormat) {
const stdout = await getCmdOutput(cmdFormat, "rustc -vV");
let splits = stdout
async function getRustVersions(cmdFormat) {
const versions = new Set();
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, "rustc -vV")));
const stdout = await (async () => {
try {
return await getCmdOutput(cmdFormat, "rustup toolchain list --quiet");
}
catch (e) {
core.warning(`Error running rustup toolchain list, falling back to default toolchain only: ${e}`);
return undefined;
}
})();
if (stdout !== undefined) {
for (const toolchain of stdout.split(/[\n\r]+/)) {
const trimmed = toolchain.trim();
if (!trimmed) {
continue;
}
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, `rustup run ${toolchain} rustc -vV`)));
}
}
return versions;
}
function parseRustVersion(stdout) {
const splits = stdout
.split(/[\n\r]+/)
.filter(Boolean)
.map((s) => s.split(":").map((s) => s.trim()))
@@ -151099,10 +151128,17 @@ async function globFiles(pattern) {
const globber = await glob.create(pattern, {
followSymbolicLinks: false,
});
// fs.statSync resolve the symbolic link and returns stat for the
// fs.stat resolve the symbolic link and returns stat for the
// file it pointed to, so isFile would make sure the resolved
// file is actually a regular file.
return (await globber.glob()).filter((file) => external_fs_default().statSync(file).isFile());
const files = [];
for (const file of await globber.glob()) {
const stats = await promises_default().stat(file);
if (stats.isFile()) {
files.push(file);
}
}
return files;
}
function sort_and_uniq(a) {
return a