New Presents Every Six Weeks
In Rust-land, it’s Christmas time every six weeks! That is, the Rust language project uses a regular release cadence sometimes referred to as a release train. It’s been the practice of the Habitat project to consume these new releases as they come out, opting to eat any pain early and frequently. In practice, this has been a very easy activity as new Rust releases typically don’t introduce compilation failures (only potential new warnings), major logic bugs, or regressions. Our record goes back to Rust 1.3.0 spanning almost 3 years of continuous improvement.
Rustfmt Is Game-Changing
Another early decision in the Habitat project was to adopt the rustfmt tool which started life as an external standalone project and is now formally adopted by the Rust project and integrated into the rustup tool as a component. We wanted an objective tool that would give all developers a common starting point for formatting Rust code and ultimately make our codebase look more “rustic”. During early days the rustfmt tool was iterating quickly and would often result in large formatting changes that churned code. We’ve kept up the practice of upgrading when a new version of rustfmt is released and today this is made much easier via rustup. The catch now is that upgrading to a new version of Rust may result in a new version of rustfmt as well. As such the practice of upgrading to a new Rust release and a new rustfmt release are one in the same activity.
Developer Workstation Upgrade
As Habitat uses the stable releases of Rust, and assuming a normal installation of the rustup tool, simply running rustup update
should be enough to pull the latest stable Rust release down. You can confirm your active version of Rust by running rustc --version
and rustfmt with rustfmt --version
(note that currently the version of rustfmt does not match the version of Rust). Doing this first is ideal as it will allow you to use the rustfmt tooling to update any code pro-actively.
Codebase Upgrade Approach
As our project has slowly started to span more than one Git repository, upgrading to a new version Rust involves a change to each of our 4 primary code repositories. Here are the changes to consider:
habitat-sh/core-plans
There are 2 Habitat Rust Plans, including a 64-bit Linux Plan and a 64-bit Windows Plan. It is important to update these Plans as this will be the version of Rust used when building Habitat software components and Builder services. Our project isn’t considered “upgraded” until these Plans are updated, merged, and new packages are ready in the “stable” channel.
Both the Linux and Windows Plans should be updated, ideally in a single commit (or at least a single pull request).
habitat-sh/core
This codebase is shared behavior and is used by both the habitat-sh/habitat and habitat-sh/builder repositories. It also tends to be fairly stable and slow moving, thus often forgotten about (hint: that’s it’s being called out first).
To upgrade the version used in CI, bump the rust:
value in .travis.yml
and to pro-actively update any source code formatting changes, run cargo fmt
from the root of the repository.
habitat-sh/habitat
To upgrade the version used in CI, bump the rust:
value in travis.yml
, the RUST_TOOLCHAIN
value in .buildkite/env
, and to pro-actively update any source code formatting changes, run cargo fmt
from the root of the repository.
Note that if there are any other important code/behavior changes in the core
repository, you may want to consider bumping the Git SHA reference for core in this repository. Thankfully this is very rare and is not 100% critical.
habitat-sh/builder
To upgrade the version used in CI, bump the rust:
value in travis.yml
and to pro-actively update any source code formatting changes, run cargo fmt
from the root of the repository.
Note that if there are any other important code/behavior changes in the core
repository, you may want to consider bumping the Git SHA reference for core in this repository. Thankfully this is very rare and is not 100% critical.
The New Warnings
Occasionally upgrading to a new version of Rust may introduce new lint and compiler warnings. While these warnings don’t fail the builds, these warnings should be addressed in a reasonable time period. Often what gets introduced as a warning may later become an error in later Rust releases.
In general, we consider Rust lints and compiler warnings to be actionable but not mission critical. We strive to eliminate these warnings in short order, but addressing these warnings could involve behavior changes potentially introducing new bugs. As such, dealing with compiler warnings that are more than trivial is considered a bad practice in Rust-upgrading pull requests and is better to be dealt with as follow-on work that can easily be code-reviewed without considering code reformatting noise.