feat: opt in to caching mise rust toolchains#467
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a cache_rust option to allow caching of Rust toolchains installed by mise. It updates the documentation, action configuration, and core logic to manage MISE_RUSTUP_HOME and MISE_CARGO_HOME within the cache. Feedback was provided to improve the implementation by using asynchronous file system operations for setupRustCache to maintain consistency with other setup functions and prevent blocking the event loop.
Greptile SummaryThis PR adds an explicit
Confidence Score: 5/5Safe to merge — the change is a pure opt-in with no effect on existing workflows that leave cache_rust at its default of false. The implementation is carefully ordered: env vars are exported before cache restore so both restore and save operate on consistent paths; isPathInside correctly avoids redundant cache path entries for the default layout where rustup/cargo homes are already inside miseDir(); the -rust cache key segment prevents stale cache reuse on first enable; and warnings are emitted for known misconfigurations. No changed code path alters behavior for workflows that do not opt in. No files require special attention. Important Files Changed
Reviews (5): Last reviewed commit: "test: avoid hardcoded rust cache paths" | Re-trigger Greptile |
This comment was marked as off-topic.
This comment was marked as off-topic.
…lchains # Conflicts: # dist/index.js.map
This comment was marked as outdated.
This comment was marked as outdated.
| description: | | ||
| Opt in to caching Rust toolchains installed by mise's Rust backend. | ||
|
|
||
| When `true`, the action exports `MISE_RUSTUP_HOME` and `MISE_CARGO_HOME` |
There was a problem hiding this comment.
I would just use asdf-rust for this behavior
There was a problem hiding this comment.
It doesn't use rustup, so it can't support components or other options.
I can make a vfox plugin and use it, but I think it's better if we can support Rust in mise-action. Currently, it just doesn't work properly.
Should we fix mise itself to detect broken Rust in installs/rust? I'm not sure if we can, but it might be better; I can cache the default RUSTUP_HOME and CARGO_HOME if I would like to.
There was a problem hiding this comment.
idk, but I don't think "cache rust" is really communicating what this is doing. I don't think I want to support this model in any case though.
There was a problem hiding this comment.
I see. I'll have a look at some other solutions.
|
Closing this in favor of fixing the Rust install-completeness check in mise itself: jdx/mise#9839. That keeps mise-action from owning a separate Rust cache model, while still making restored mise install markers correct for The docs-only follow-up for Cargo/Rust cache composition is here: #474. This comment was generated by an AI coding assistant. |
Summary
cache_rust: trueas an explicit opt-in for caching Rust toolchains installed by miseMISE_RUSTUP_HOMEandMISE_CARGO_HOMEbefore cache restore/install so rustup toolchains and cargo/rustup proxies are saved with the existing mise cache-rustsegment to the default cache key, expose{{cache_rust}}to custom cache key templates, document the compatibility tradeoffs, and add a lightweight workflow check for the opt-in pathFixes #215
Addresses #184
Refs #353
Research notes
Failure mode
The failure mode in #215/#184/#353 is specific to Rust because mise delegates Rust installation to rustup instead of placing the complete toolchain under
~/.local/share/mise/installslike most tools.When mise-action restores only the mise data dir, the cached
installs/rust/...symlink/marker can makemise installreport that Rust is already installed, while the corresponding rustup toolchain/components are absent from the runner. The next plaincargo fmtorcargo clippythen goes through rustup, which may auto-install only the base toolchain and fail becauserustfmt/clippywere never restored.Primary references:
What must be restored
Rustup and Cargo split state across two homes:
RUSTUP_HOME: rustup metadata and installed toolchains/components.CARGO_HOME: cargo/rustup proxy binaries inbin, Cargo-installed binary metadata, registry cache, and git dependency cache.For the mise-action bug, the required restore set is the rustup toolchain/component state plus the proxy binaries that make plain
cargo,rustfmt, andclippyresolve to the same mise-managed toolchain aftermise envexportsRUSTUP_HOME/CARGO_HOME.Cache-key scope and Cargo safety
A single mise-action cache key is appropriate for the toolchain/proxy state because the Rust version/components come from mise config and
mise.lock, which are already part of the defaultfile_hashkey.CARGO_HOMEcan also contain Cargo registry and git caches. Those caches are generally correctness-safe because Cargo validates package versions/checksums and refreshes as needed, but they are not ideal to key only by mise config. They can also be large. This PR therefore documentscache_rustas a toolchain/proxy cache, not a replacement for Cargo dependency ortargetbuild caching.For workflows that need dependency/build caches, the recommended shape is:
mise-actionwithcache_rust: trueto restore mise-owned rustup/Cargo proxy state.Swatinem/rust-cacheafter mise-action to manage Cargo registry, git dependency, andtargetcaches using Rust/Cargo lockfile-aware keys.cache-bin: "false"on rust-cache when mise should remain the owner of cargo/rustup proxy binaries and Cargo tools installed by mise.Related rust-cache docs:
Workarounds found in issue/PR references
I checked the cross-reference timelines for #215, #184, and #353, then followed code-search references to their workflow workarounds.
Direct issue/PR references:
cargo-clippy; commenters found that disabling mise-action cache made mise install clippy correctly, and suggested caching~/.rustupplus cargo paths.cargo fmtfailure;cache: falsefixed it by forcing a fresh rustup install withrustfmt/clippy.cargo fmtcached-run failure withprofile = "default".cache: falseon mise-action plus explicitrustup component addas the workaround: build: migrate to mise for unified toolchain management fang2hou/wow-sharedmedia#23~/.local/share/mise/installs,~/.cargo/bin, and~/.rustup: build: Rust toolchain管理をmiseに統一しflakeを廃止 cffnpwr/github-todo-bar#22Additional public workflow workarounds:
RUSTUP_HOMEunderMISE_DATA_DIR, use a temporaryCARGO_HOMEduring mise install, then move Cargo home for later use: https://github.com/nikobockerman/github-actions/blob/main/.github/actions/mise-project-setup/action.yamlactions/cachefor mise installs,~/.cargo/bin, and~/.rustup; mise-actioncache: false: https://github.com/cffnpwr/github-todo-bar/blob/7925e5f6c4c0a527713ba17080a5de1781b54523/.github/actions/setup-mise/action.yaml~/.cargo/bin,~/.cargo/binstall,~/.cargo/env,~/.rustup, followed bymise exec rust -- rustup component add rustfmt clippy: https://github.com/kossnocorp/nmcr/blob/e72a04e51e0c5e5f6790be2687d32fdcea574124/.github/workflows/ci.ymlrustup component add clippy rustfmtafter mise, then separately cache Cargo registry/git/target: https://github.com/sargunv/has-nerd-font/blob/7f3914bb19941533fd73b02016dfb778a7cfae2a/.github/actions/setup/action.yml~/.rustup/toolchains, useSwatinem/rust-cache, and still runrustup component add rustfmt clippy llvm-tools-preview: https://github.com/melonswork/ironsubst/blob/59a899cdb552bfa98096121eccf57e85a334617c/.github/workflows/ci.ymlThese workarounds all point to the same missing primitive: mise-action needs an opt-in way to restore the rustup toolchain home and the Cargo proxy/bin home together with the mise install marker.
Downstream verification
Verified in risu729/biwa#606: risu729/biwa#606
That PR removed the existing
mise install --locked rust --forceworkaround, enabledcache_rust: true, and combined this action withSwatinem/rust-cache.Evidence from the retry run on the PR branch:
Lintjob restored a mise cache key containing-rust:mise-v1-linux-x64-ubuntu24-rust-2026.5.5-13c29379e886bda7bbab6becd116612e36e434b18dc6a761629fce60be0103f7-releaseCARGO_HOME=/home/runner/.local/share/mise/cargoandRUSTUP_HOME=/home/runner/.local/share/mise/rustupcargo clippy --all-targets -- --deny warningsandcargo fmt --checkboth passed without the force reinstall workaroundTestrestored the same-rustmise cache and also restored rust-cache's separate Cargo cacheEvidence after #606 was merged to
main:Lintjob got an exact mise cache hit formise-v1-linux-x64-ubuntu24-rust-2026.5.5-13c29379e886bda7bbab6becd116612e36e434b18dc6a761629fce60be0103f7mise install --locked,cargo clippy --all-targets -- --deny warnings, andcargo fmt --checksuccessfullySwatinem/rust-cacherestored a separate cache keyed from Rust/Cargo environment and lockfiles, showing the two caches can coexistThe functional verification used commit
f2054108d3926f722fd54c7fc70a1224cb691032. Later commits update documentation/action metadata, merge currentupstream/main, regeneratedistagainst the merged lockfile, and make therust_cache_setupsmoke test derive its expected mise data dir instead of hardcoding$HOME/.local/share/mise. The runtime Rust cache implementation is unchanged after the verified commit.Compatibility and cache behavior
Default behavior is unchanged.
cache_rustdefaults tofalse, so existing workflows keep the same cache paths, cache keys, and environment unless they opt in.When
cache_rust: true, this action uses mise-specific settings (MISE_RUSTUP_HOME,MISE_CARGO_HOME) instead of setting genericRUSTUP_HOME/CARGO_HOMEfor everyone. That keeps setup scoped to Rust as managed by mise and avoids silently taking over workflows that install Rust through rustup, setup-rust-toolchain, or another Rust setup action while using mise for unrelated tools.The default cache key gains
-rustonly when the option is enabled. This avoids restoring older mise-only caches where theinstalls/rust/...marker exists but the rustup/cargo homes were never cached. Users with a customcache_keyshould include{{cache_rust}}or manually invalidate their key when enabling this option.The current workaround,
mise install --locked rust --forceorrustup component add rustfmt clippyafter cache restore, should no longer be needed oncecache_rust: truehas produced a Rust-enabled cache entry.Test plan
npm run allactionlint .github/workflows/test.ymlgit diff --checkmainrun