-
Notifications
You must be signed in to change notification settings - Fork 47
Description
Problem
I've been quite annoyed by the performance of Rust toolchain installation. For example, it takes ~40 seconds to install it (with additional rust-src
and clippy
) components on the Github-managed Windows runner. Performance on Ubuntu is much better though, but still not ideal: 14 seconds, and MacOS is in the middle with 22 seconds.
Proposed Solution
Github-managed runner images happen to be blessed with the pre-installed latest stable rust toolchain on them. These images are quite well-maintained, but they can lag for some time, so it's not guaranteed that they are always up-to-date. For example, at the time of this writing the runners do have the latest stable 1.87.0
version of rust toolchain in them. This includes all images, even the images with the oldest OS versions:
- Ubuntu 24.04
- Ubuntu 22.04
- Windows 2025
- Windows 2022
- Windows 2019
- MacOS 13 (including ARM)
- MacOS 14 (including ARM)
- MacOS 15 (including ARM)
Anyhow, I think it would be cool to benefit from this to optimize the toolchain installation for the case of a pinned requirement (e.g. when one specifies 1.87.0
in the rust-toolchain.toml
file precisely.
This action could check if there is already an existing stable
toolchain installed and that its semver version is equal to the pinned rust toolchain version, and skip downloading it. Instead - copy the toolchain from the stable
directory and call it done (almost).
This optimization will work only under the following conditions:
- The repo uses an exact version requirement for the toolchain
- The exact version requirement coincides with the version of the
stable
toolchain already installed on the runner
Note that the action can be specified with the additional component
s or target
s to install. I'm not sure if, for example rustfmt
or clippy
are already available in Github managed runner images, but it's easy to check. In any case, installing additional components is fine - the main point is to reuse what's already available on the runner's FS if possible, and if something extra is needed - then download only that extra part instead of the full toolchain from scratch.
I understand that this may be an issue for rustup
specifically. I believe this problem is unique to CI environments, so I began this discussion here, but if you feel like this should be moved to rustup
, then that's fine. The fundamental problem here is that rustup separates stable
and x.y.z
toolchain even if the stable
's toolchain is of the x.y.z
version. It doesn't try to reuse it when installing the x.y.z
version.
Alternatives
I also thought about caching the toolchain via the Github's builtin cache functionality, but I'm not sure how much of a win that would be. It probably will be a win since Github's cache is likely located very closely to their runners