Open-source project
dtolnay/rust-toolchain avatar
dtolnay/rust-toolchain

dtolnay/rust-toolchain picks the compiler from the action reference itself

Concise GitHub Action for installing a Rust toolchain

1,592 stars97 forksShellMIT

At a glance

What is it?
This GitHub Action installs a Rust toolchain through rustup and takes the version from the revision you reference it by, so a workflow can name the compiler in one line. It also exposes a hash and the rustup toolchain name as outputs, and it documents a real hazard for anyone who pins the action to a commit SHA.
Who is it for?
Adopt dtolnay/rust-toolchain when you want a Rust CI job that reads as one line and that keeps the compiler version next to the action reference, because the version and the action live in the same place in the workflow file. Do not adopt it if you want to pin a toolchain explicitly and expect the action revision to follow, since an explicit `toolchain` input requires using the master revision of the action.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The reference decides the toolchain

The mechanism that makes this action different from a generic rustup installer is that the version selector is the action reference itself. The documentation states that the selection of the Rust toolchain is made based on the particular revision of the action being requested, and gives two examples: `dtolnay/rust-toolchain@nightly` pulls in the nightly Rust toolchain, while `dtolnay/[email protected]` pulls in that exact release. There is no `with:` block and no separate file. The consequence is that the compiler version lives in the same place as the action, which means a reviewer looking at a workflow can see the toolchain without cross-referencing another step, and a version bump is a one token change on the same line as everything else.

A minimal workflow is three steps

The example workflow in the documentation is the whole pitch. The action is designed for one-line concise usage and good defaults, and the example is a test suite that runs on a pull request or a push:

yaml
name: test suite
on: [push, pull_request]

jobs:
  test:
    name: cargo test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo test --all-features

The `@stable` reference means the most recent stable compiler, and the result is a job that checks out the code, installs the toolchain and runs the test command. All inputs are optional, so nothing else needs to be declared. For a project with a Cargo manifest that already pins its minimum Rust version, this is close to the whole configuration, which is the point of the design.

Explicit versions, targets and components come as inputs

Three inputs are documented, all optional. The `toolchain` input takes a rustup toolchain specifier, with `stable`, `nightly`, `1.89.0` and `nightly-2025-01-01` given as examples, and the documentation adds an important note about how it interacts with the reference. The default is to match the revision, so when you pass an explicit `toolchain` input instead of using the reference, the documentation tells you to use `dtolnay/rust-toolchain@master` as the revision of the action. The `targets` input is a comma-separated string of additional targets to install, with `wasm32-unknown-unknown` as the example, and `components` is a comma-separated string of additional components, with `clippy, rustfmt` as the example. The clippy and rustfmt example is the one most projects need, since linting and formatting in CI usually want both.

Two outputs, one for caching and one for cargo

The action exposes two outputs and both are meant to be consumed. The `cachekey` output is described as a short hash of the installed rustc version, appropriate for use as a cache key, with the example value `20250627a831`. That is the value you would feed to a cache action so that the Cargo registry and target directory are not rebuilt on every run, and the fact that it is a hash of the compiler version rather than a fixed string is what makes the cache invalidate when the toolchain changes. The `name` output is rustup's own name for the selected version of the toolchain, like `1.62.0`, and the documentation says it is suitable for use with `cargo +${{steps.toolchain.outputs.name}}`, which is how you invoke a specific toolchain when a workflow needs more than the one that is active by default.

Toolchain expressions for a sliding support window

The action also handles the case where your project supports a range of compilers rather than one. The documentation gives two forms, and they are the part most people have not seen in a rustup setup. The first installs the most recent stable toolchain as of a specified time offset, which may be written in years, months, weeks or days, and the example is `stable 18 months ago` with the action referenced at master. The second installs the stable toolchain which preceded the most recent one by a number of minor versions, and the example is `stable minus 8 releases`. Both are used with `dtolnay/rust-toolchain@master` and a `with:` block:

yaml
  - uses: dtolnay/rust-toolchain@master
    with:
      toolchain: stable 18 months ago

The point of this is that a test matrix over compiler versions can be expressed in a way that moves with time. Instead of pinning an old version number and forgetting to update it, you say how far back you want to support, and the expression resolves against the current release. The documentation frames these forms as available for projects that use a sliding window of compiler support.

Pinning to a commit SHA has a garbage collection trap

The last technical section is the one that should make you slow down if you are hardening a workflow. The documentation explains that in a workflow that pins the action using a full-length commit SHA, as opposed to something like `@nightly` or `@1.89.0`, it is required to pick a SHA that is within the history of the master branch. Any commit that is not within the history of master will eventually be garbage collected, and your workflows will fail. So the usual security advice of pinning third-party actions to an immutable SHA has a catch here: the commit has to be reachable from master, otherwise the pin rots and the build breaks later, without anyone changing the workflow. The documentation links the GitHub documentation on secure use of third-party actions, which is where the pinning recommendation comes from. The repository is small by design, holding only the `.github/` directory, the LICENSE, the README, an `action.yml` and a `scripts/` directory, and the scripts and documentation are released under the MIT licence.

Editorial conclusion

Adopt dtolnay/rust-toolchain when you want a Rust CI job that reads as one line and that keeps the compiler version next to the action reference, because the version and the action live in the same place in the workflow file. Do not adopt it if you want to pin a toolchain explicitly and expect the action revision to follow, since an explicit `toolchain` input requires using the master revision of the action. Verify first that any commit SHA you pin sits inside the history of the master branch, because the documentation warns that commits outside it will be garbage collected and the workflow will fail, and check that your nightly- dated toolchain is still available from rustup at the time the job runs.

Frequently asked questions

How do I choose the Rust version in the dtolnay/rust-toolchain action?

The selection is made from the revision you reference the action by. `dtolnay/rust-toolchain@nightly` installs the nightly toolchain and `dtolnay/[email protected]` installs that exact version. Passing an explicit `toolchain` input instead means using `dtolnay/rust-toolchain@master` as the revision.

What inputs does dtolnay/rust-toolchain accept?

All inputs are optional. `toolchain` takes a rustup specifier such as `stable`, `nightly`, `1.89.0` or `nightly-2025-01-01`, `targets` is a comma-separated list of extra targets such as `wasm32-unknown-unknown`, and `components` is a comma-separated list such as `clippy, rustfmt`.

What are the outputs of dtolnay/rust-toolchain?

The `cachekey` output is a short hash of the installed rustc version, suitable as a cache key, and the `name` output is rustup's name for the selected toolchain, for example `1.62.0`, suitable for use with `cargo +${{steps.toolchain.outputs.name}}`.

What problem occurs if I pin dtolnay/rust-toolchain to an old commit SHA?

The documentation warns that a pinned SHA must be within the history of the master branch, because any commit outside that history will eventually be garbage collected and the workflow will fail.

Can dtolnay/rust-toolchain install an older stable compiler automatically?

Yes. The `toolchain` input accepts expressions such as `stable 18 months ago` for the most recent stable release at a time offset, and `stable minus 8 releases` for the stable release before the most recent one. Both are used with the action referenced at `@master`.

Official sources

  1. dtolnay/rust-toolchain on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dtolnay-rust-toolchain.svg)](https://hysenlabs.com/projects/dtolnay-rust-toolchain)

Was this useful?