Skip to content

Reuse the pre-installed rust toolchain if possible #63

@Veetaha

Description

@Veetaha

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:

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 components or targets 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions