Selecting the latest nightly to have a specific set of features?

I'm in a bit of a bind.

I've got a project that relies on Nightly, because one of the dependencies also does. I test that project on Travis, which uses the minimal rustup profile, which installs very few components; my .travis.yml includes rustup component add clippy rustfmt at the appropriate time in order to ensure the components my build needs are present. Underlying that, my rust-toolchain file normally specifies nightly, unconditionally.

However, this only works most of the time. Occasionally, a version of nightly will be released without rustfmt, or without clippy. That's fine, and that's an advertised behaviour for the nightly channel. What I'd really like is a way to query rustup to ask "what is the latest nightly to have these components," and then to install that nightly. Is such a thing possible? Is such a thing practical?

curl https://sh.rustup.rs -sSf | sh -s -- --profile complete --default-toolchain nightly should install a toolchain with everything.

However, there's still no guarantee that any nightly release is compatible with your code. Nightly features can change or be removed. For CI it's safest to pin nightly to a date and bump it manually.

2 Likes

I'd go further and say, one should always pin the dependency versions for executables, because once you know it runs, why take the risk of breaking it for new or changed features, that won't be needed for your project.
The quote

Don't change a running system

has its merits. If your code works today, you also want your code to work in 10 years.

Personally, I also use cargo vendor, which pulls all your dependencies into your project folder. The disadvantage is obviously the project/repository size being negatively affected, but it enables you to not depend on some online resource being available in 10 to 20 years.

Node.js has proven just how fast a whole ecosystem dependent on 100% availability of online resources will break like a card house, if just a single dependency (card) is removed.

2 Likes

I'm sympathetic to the position that "whatever nightly is latest" is probably a bit too risky for most users. This is a toy app, and I'd be no worse off if it were offline entirely, so I don't mind that, but it's worth keeping in mind.

Here's where I ended up: the project uses a GitHub Actions job, nightly-rust-update.yml, to run upgrade to the latest nightly once a month (arbitrarily, on the 8th, just to avoid the first-of-the-month thundering herds on the Actions job scheduler). If any tests fail, then no harm done - I get an email about it, so I know it happened, but I don't have to do anything about that and the project keeps running. If the tests all pass, then the action opens a pull request (example) with the changes it made to the rust-toolchain file, which I can review and merge at my leisure, or ignore.

I don't love having a robot bother me to commit a one-line change, even a one-line change with a large semantic footprint, on a regular basis, and I'm not a big fan of Dependabot, either, but it works and it manages the risks both @kornel and @Phlopsi called out pretty effectively.

The rest of the code for this is in the repo's tools directory. In particular, its notion of "upgrade to the latest nightly" is dumber than a sackful of hammers: it spews today's date directly into the rust-toolchain file, formatted appropriately. Since this whole apparatus rejects toolchains that can't complete the test suite, that's safe enough, but it does mean it can't easily walk backwards to find a date where the tests would have passed or do anything else that requires understanding what toolchain versions mean.

2 Likes

I had the same problem and to address it I created docker-rust-aio which is built daily. If one of the components is missing, even though the current image build fails, the previous full version is still available from Dockerhub.

It won't work if you depend on the very latest nightly. If you're fine with some nightly (from what I've seen the longest streak of "broken" nightlies was around 2 weeks) then the docker image could work for you.

My use case is a local CI build so I haven't looked into making this into a github action but I guess it wouldn't be that difficult.