Skip to content

Commit b13636f

Browse files
committed
Consider all installed toolchains in cache key
1 parent 230365f commit b13636f

File tree

4 files changed

+122
-36
lines changed

4 files changed

+122
-36
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ This cache is automatically keyed by:
143143

144144
- the github [`job_id`](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_id)
145145
(if `add-job-id-key` is `"true"`),
146-
- the rustc release / host / hash,
146+
- the rustc release / host / hash (for all installed toolchains when
147+
available),
147148
- the following values, if `add-rust-environment-hash-key` is `"true"`:
148149
- the value of some compiler-specific environment variables (eg. RUSTFLAGS, etc), and
149150
- a hash of all `Cargo.lock` / `Cargo.toml` files found anywhere in the repository (if present).

dist/restore/index.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150809,7 +150809,7 @@ class CacheConfig {
150809150809
/** The prefix portion of the cache key */
150810150810
this.keyPrefix = "";
150811150811
/** The rust version considered for the cache key */
150812-
this.keyRust = "";
150812+
this.keyRust = [];
150813150813
/** The environment variables considered for the cache key */
150814150814
this.keyEnvs = [];
150815150815
/** The files considered for the cache key */
@@ -150863,12 +150863,15 @@ class CacheConfig {
150863150863
// The env vars are sorted, matched by prefix and hashed into the
150864150864
// resulting environment hash.
150865150865
let hasher = external_crypto_default().createHash("sha1");
150866-
const rustVersion = await getRustVersion(cmdFormat);
150867-
let keyRust = `${rustVersion.release} ${rustVersion.host}`;
150868-
hasher.update(keyRust);
150869-
hasher.update(rustVersion["commit-hash"]);
150870-
keyRust += ` (${rustVersion["commit-hash"]})`;
150871-
self.keyRust = keyRust;
150866+
const rustVersions = Array.from(await getRustVersions(cmdFormat));
150867+
// Doesn't matter how they're sorted, just as long as it's deterministic.
150868+
rustVersions.sort();
150869+
for (const rustVersion of rustVersions) {
150870+
const { release, host, "commit-hash": commitHash } = rustVersion;
150871+
const keyRust = `${release} ${host} ${commitHash}`;
150872+
hasher.update(keyRust);
150873+
self.keyRust.push(keyRust);
150874+
}
150872150875
// these prefixes should cover most of the compiler / rust / cargo keys
150873150876
const envPrefixes = ["CARGO", "CC", "CFLAGS", "CXX", "CMAKE", "RUST"];
150874150877
envPrefixes.push(...lib_core.getInput("env-vars").split(/\s+/).filter(Boolean));
@@ -151052,7 +151055,10 @@ class CacheConfig {
151052151055
lib_core.info(`.. Prefix:`);
151053151056
lib_core.info(` - ${this.keyPrefix}`);
151054151057
lib_core.info(`.. Environment considered:`);
151055-
lib_core.info(` - Rust Version: ${this.keyRust}`);
151058+
lib_core.info(` - Rust Versions:`);
151059+
for (const rust of this.keyRust) {
151060+
lib_core.info(` - ${rust}`);
151061+
}
151056151062
for (const env of this.keyEnvs) {
151057151063
lib_core.info(` - ${env}`);
151058151064
}
@@ -151087,9 +151093,31 @@ function isCacheUpToDate() {
151087151093
function digest(hasher) {
151088151094
return hasher.digest("hex").substring(0, HASH_LENGTH);
151089151095
}
151090-
async function getRustVersion(cmdFormat) {
151091-
const stdout = await getCmdOutput(cmdFormat, "rustc -vV");
151092-
let splits = stdout
151096+
async function getRustVersions(cmdFormat) {
151097+
const versions = new Set();
151098+
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, "rustc -vV")));
151099+
const stdout = await (async () => {
151100+
try {
151101+
return await getCmdOutput(cmdFormat, "rustup toolchain list --quiet");
151102+
}
151103+
catch (e) {
151104+
lib_core.warning(`Error running rustup toolchain list, falling back to default toolchain only: ${e}`);
151105+
return undefined;
151106+
}
151107+
})();
151108+
if (stdout !== undefined) {
151109+
for (const toolchain of stdout.split(/[\n\r]+/)) {
151110+
const trimmed = toolchain.trim();
151111+
if (!trimmed) {
151112+
continue;
151113+
}
151114+
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, `rustup run ${toolchain} rustc -vV`)));
151115+
}
151116+
}
151117+
return versions;
151118+
}
151119+
function parseRustVersion(stdout) {
151120+
const splits = stdout
151093151121
.split(/[\n\r]+/)
151094151122
.filter(Boolean)
151095151123
.map((s) => s.split(":").map((s) => s.trim()))

dist/save/index.js

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150809,7 +150809,7 @@ class CacheConfig {
150809150809
/** The prefix portion of the cache key */
150810150810
this.keyPrefix = "";
150811150811
/** The rust version considered for the cache key */
150812-
this.keyRust = "";
150812+
this.keyRust = [];
150813150813
/** The environment variables considered for the cache key */
150814150814
this.keyEnvs = [];
150815150815
/** The files considered for the cache key */
@@ -150863,12 +150863,15 @@ class CacheConfig {
150863150863
// The env vars are sorted, matched by prefix and hashed into the
150864150864
// resulting environment hash.
150865150865
let hasher = external_crypto_default().createHash("sha1");
150866-
const rustVersion = await getRustVersion(cmdFormat);
150867-
let keyRust = `${rustVersion.release} ${rustVersion.host}`;
150868-
hasher.update(keyRust);
150869-
hasher.update(rustVersion["commit-hash"]);
150870-
keyRust += ` (${rustVersion["commit-hash"]})`;
150871-
self.keyRust = keyRust;
150866+
const rustVersions = Array.from(await getRustVersions(cmdFormat));
150867+
// Doesn't matter how they're sorted, just as long as it's deterministic.
150868+
rustVersions.sort();
150869+
for (const rustVersion of rustVersions) {
150870+
const { release, host, "commit-hash": commitHash } = rustVersion;
150871+
const keyRust = `${release} ${host} ${commitHash}`;
150872+
hasher.update(keyRust);
150873+
self.keyRust.push(keyRust);
150874+
}
150872150875
// these prefixes should cover most of the compiler / rust / cargo keys
150873150876
const envPrefixes = ["CARGO", "CC", "CFLAGS", "CXX", "CMAKE", "RUST"];
150874150877
envPrefixes.push(...core.getInput("env-vars").split(/\s+/).filter(Boolean));
@@ -151052,7 +151055,10 @@ class CacheConfig {
151052151055
core.info(`.. Prefix:`);
151053151056
core.info(` - ${this.keyPrefix}`);
151054151057
core.info(`.. Environment considered:`);
151055-
core.info(` - Rust Version: ${this.keyRust}`);
151058+
core.info(` - Rust Versions:`);
151059+
for (const rust of this.keyRust) {
151060+
core.info(` - ${rust}`);
151061+
}
151056151062
for (const env of this.keyEnvs) {
151057151063
core.info(` - ${env}`);
151058151064
}
@@ -151087,9 +151093,31 @@ function isCacheUpToDate() {
151087151093
function digest(hasher) {
151088151094
return hasher.digest("hex").substring(0, HASH_LENGTH);
151089151095
}
151090-
async function getRustVersion(cmdFormat) {
151091-
const stdout = await getCmdOutput(cmdFormat, "rustc -vV");
151092-
let splits = stdout
151096+
async function getRustVersions(cmdFormat) {
151097+
const versions = new Set();
151098+
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, "rustc -vV")));
151099+
const stdout = await (async () => {
151100+
try {
151101+
return await getCmdOutput(cmdFormat, "rustup toolchain list --quiet");
151102+
}
151103+
catch (e) {
151104+
core.warning(`Error running rustup toolchain list, falling back to default toolchain only: ${e}`);
151105+
return undefined;
151106+
}
151107+
})();
151108+
if (stdout !== undefined) {
151109+
for (const toolchain of stdout.split(/[\n\r]+/)) {
151110+
const trimmed = toolchain.trim();
151111+
if (!trimmed) {
151112+
continue;
151113+
}
151114+
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, `rustup run ${toolchain} rustc -vV`)));
151115+
}
151116+
}
151117+
return versions;
151118+
}
151119+
function parseRustVersion(stdout) {
151120+
const splits = stdout
151093151121
.split(/[\n\r]+/)
151094151122
.filter(Boolean)
151095151123
.map((s) => s.split(":").map((s) => s.trim()))

src/config.ts

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class CacheConfig {
4141
/** The prefix portion of the cache key */
4242
private keyPrefix = "";
4343
/** The rust version considered for the cache key */
44-
private keyRust = "";
44+
private keyRust: Array<string> = [];
4545
/** The environment variables considered for the cache key */
4646
private keyEnvs: Array<string> = [];
4747
/** The files considered for the cache key */
@@ -104,14 +104,16 @@ export class CacheConfig {
104104
// resulting environment hash.
105105

106106
let hasher = crypto.createHash("sha1");
107-
const rustVersion = await getRustVersion(cmdFormat);
108-
109-
let keyRust = `${rustVersion.release} ${rustVersion.host}`;
110-
hasher.update(keyRust);
111-
hasher.update(rustVersion["commit-hash"]);
112-
113-
keyRust += ` (${rustVersion["commit-hash"]})`;
114-
self.keyRust = keyRust;
107+
const rustVersions = Array.from(await getRustVersions(cmdFormat));
108+
// Doesn't matter how they're sorted, just as long as it's deterministic.
109+
rustVersions.sort();
110+
111+
for (const rustVersion of rustVersions) {
112+
const { release, host, "commit-hash": commitHash } = rustVersion;
113+
const keyRust = `${release} ${host} ${commitHash}`;
114+
hasher.update(keyRust);
115+
self.keyRust.push(keyRust);
116+
}
115117

116118
// these prefixes should cover most of the compiler / rust / cargo keys
117119
const envPrefixes = ["CARGO", "CC", "CFLAGS", "CXX", "CMAKE", "RUST"];
@@ -334,7 +336,10 @@ export class CacheConfig {
334336
core.info(`.. Prefix:`);
335337
core.info(` - ${this.keyPrefix}`);
336338
core.info(`.. Environment considered:`);
337-
core.info(` - Rust Version: ${this.keyRust}`);
339+
core.info(` - Rust Versions:`);
340+
for (const rust of this.keyRust) {
341+
core.info(` - ${rust}`);
342+
}
338343
for (const env of this.keyEnvs) {
339344
core.info(` - ${env}`);
340345
}
@@ -379,9 +384,33 @@ interface RustVersion {
379384
"commit-hash": string;
380385
}
381386

382-
async function getRustVersion(cmdFormat: string): Promise<RustVersion> {
383-
const stdout = await getCmdOutput(cmdFormat, "rustc -vV");
384-
let splits = stdout
387+
async function getRustVersions(cmdFormat: string): Promise<Set<RustVersion>> {
388+
const versions = new Set<RustVersion>();
389+
390+
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, "rustc -vV")));
391+
392+
const stdout = await (async () => {
393+
try {
394+
return await getCmdOutput(cmdFormat, "rustup toolchain list --quiet");
395+
} catch (e) {
396+
core.warning(`Error running rustup toolchain list, falling back to default toolchain only: ${e}`);
397+
return undefined;
398+
}
399+
})();
400+
if (stdout !== undefined) {
401+
for (const toolchain of stdout.split(/[\n\r]+/)) {
402+
const trimmed = toolchain.trim();
403+
if (!trimmed) {
404+
continue;
405+
}
406+
versions.add(parseRustVersion(await getCmdOutput(cmdFormat, `rustup run ${toolchain} rustc -vV`)));
407+
}
408+
}
409+
return versions;
410+
}
411+
412+
function parseRustVersion(stdout: string): RustVersion {
413+
const splits = stdout
385414
.split(/[\n\r]+/)
386415
.filter(Boolean)
387416
.map((s) => s.split(":").map((s) => s.trim()))

0 commit comments

Comments
 (0)