Updating Rust Version
This guide explains how to update the Rust version across the entire Step Repository. It's critical that all locations are updated together to ensure consistency across development environments, CI/CD pipelines, and production builds.
Overview
The Step Repository uses Rust stable version 1.96.0 throughout the entire codebase. We maintain a single, consistent version across:
- GitHub Actions (CI/CD pipelines)
- All Dockerfiles (development and production)
- Nix development environment (devenv.nix)
Why Synchronization Matters
Rust versions must be synchronized across all systems to ensure:
- Reproducible builds - Same code compiles identically everywhere
- Consistent behavior - No surprises from compiler version differences
- Dependency compatibility - All dependencies work with the chosen version
- CI/CD reliability - Tests and builds don't fail due to version mismatches
- Developer experience - Local development matches production
Complete Update Checklist
When updating the Rust version, you MUST update it in all of the following locations:
1. GitHub Actions Workflows
Update the toolchain version in these workflow files:
-
.github/workflows/tests.yml(line 43)- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
profile: minimal
toolchain: 1.90.0 # ← Update this
components: rustfmt
target: x86_64-unknown-linux-musl -
.github/workflows/lint_prettify.yml(line 102)- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
profile: minimal
toolchain: 1.90.0 # ← Update this
components: rustfmt
target: x86_64-unknown-linux-musl -
.github/workflows/step_cli_build.yml(line 38)- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
profile: minimal
toolchain: 1.90.0 # ← Update this
components: rustfmt
target: x86_64-unknown-linux-musl
2. Dockerfiles
Update the FROM rust:X.Y.Z line in all Dockerfiles:
-
packages/Dockerfile.cargo-packages(line 10)FROM rust:1.90.0-slim-bookworm # ← Update this -
packages/braid/Dockerfile(line 5)FROM rust:1.90.0-slim-bookworm # ← Update this -
packages/braid/Dockerfile.prod -
packages/braid/Dockerfile.prod-vstl-dependencies -
packages/windmill/Dockerfile -
packages/windmill/Dockerfile.prod -
packages/windmill/Dockerfile.prod-vstl-dependencies -
packages/harvest/Dockerfile -
packages/harvest/Dockerfile.prod -
packages/harvest/Dockerfile.prod-vstl-dependencies -
packages/b3/Dockerfile.prod -
packages/b3/Dockerfile.prod-vstl-dependencies -
packages/e2e/src/mock_server/Dockerfile.prod -
packages/loadtesting/Dockerfile -
packages/Dockerfile.immudb-init-vstl-dependencies -
packages/Dockerfile.immudb-init.prod -
packages/step-cli/Dockerfile -
packages/orare/doc_renderer/Dockerfile
Important: Remove any rustup toolchain install nightly-* commands if present. We only use stable Rust.
3. Nix Configuration
Update the pinned Rust version in the Nix development environment:
devenv.nix(lines 4–15) — update therust-overlaycommit and the version string inrust-bin.stable:let
rustOverlay = import (builtins.fetchTarball {
# Replace with a commit from oxalica/rust-overlay made after the target Rust release
url = "https://github.com/oxalica/rust-overlay/archive/<COMMIT_HASH>.tar.gz";
# Leave as "" or a dummy hash first, then paste the hash Nix reports
sha256 = "<SHA256_HASH>";
});
pkgs' = pkgs.extend rustOverlay;
# Pinned to stable version X.Y.Z
rustStable = pkgs'.rust-bin.stable."X.Y.Z".default.override {
targets = [ "wasm32-unknown-unknown" "wasm32-wasip1" "wasm32-wasip2" ];
extensions = [ "rust-src" "rust-analyzer-preview" ];
};
in
How to update the sha256 hash: set it to "" (empty string), run devenv shell, and Nix will fail with the actual hash — paste that value back in.
Note: Because rust-overlay is pinned to a specific commit, the Rust version is fully reproducible and does not depend on the nixpkgs snapshot. The version in rust-bin.stable."X.Y.Z" is the authoritative source — this is the same version number that must be used in GitHub Actions and Dockerfiles.
packages/sequent-core/flake.nix— used to build thesequent-coreWASM package (nix develop+wasm-pack build, see.github/workflows/build_wasm.yml). UpdateconfigureRustTargetsto point atrust-bin.stable."X.Y.Z":This flake'sconfigureRustTargets = targets : pkgs
.rust-bin
.stable
."X.Y.Z"
.default
.override {
extensions = [ "rust-src" ];
${if (builtins.length targets) > 0 then "targets" else null} = targets;
};rust-overlayinput is pinned viapackages/sequent-core/flake.lock. If the target Rust version isn't available yet in that pinned revision, refresh it with:cd packages/sequent-core && nix flake update rust-overlay
Step-by-Step Update Process
1. Update Nix First
Always start by updating the Nix environment first, as this pins the Rust version for local development.
Update devenv.nix
In devenv.nix, two things must be updated together:
rust-overlaycommit — find a recent commit from oxalica/rust-overlay that was pushed after the target Rust release, and update theurlandsha256fields in therustOverlayblock.- Version string — update the version number inside
pkgs'.rust-bin.stable."X.Y.Z".
rustOverlay = import (builtins.fetchTarball {
url = "https://github.com/oxalica/rust-overlay/archive/<NEW_COMMIT_HASH>.tar.gz";
sha256 = ""; # leave empty first — Nix will print the correct hash
});
# ...
rustStable = pkgs'.rust-bin.stable."X.Y.Z".default.override {
targets = [ "wasm32-unknown-unknown" "wasm32-wasip1" "wasm32-wasip2" ];
extensions = [ "rust-src" "rust-analyzer-preview" ];
};
Get the sha256 Hash
After setting the new commit URL, leave sha256 = "" and run:
devenv shell
Nix will fail and print the actual hash. Paste it into sha256, then run devenv shell again — it should succeed.
Verify the Rust Version in Nix
# Enter the devenv shell
devenv shell
# Check the actual Rust version
rustc --version
# Output example: rustc 1.90.0 (abc123def 2024-10-01)
The version shown must match the string in rust-bin.stable."X.Y.Z". This is the version you should use for all other files (GitHub Actions and Dockerfiles).
2. Check Current Versions in Other Files
Now identify the Rust versions currently used in other parts of the codebase:
# Search for Rust versions in Dockerfiles
grep -r "FROM rust:" packages/
# Search for Rust versions in GitHub Actions
grep -r "toolchain:" .github/workflows/
Compare these versions with what you found in Nix. They should all match.
3. Decide on Target Version
If you need to update to a newer Rust version:
- Choose the target version - Pick the stable Rust version you want (e.g.
1.91.0) - Find a
rust-overlaycommit - Browse oxalica/rust-overlay commits and pick one made after the target release date - Review breaking changes - Check https://www.rust-lang.org/ and release notes
- Ensure compatibility - Verify existing dependencies work with the target version
With rust-overlay, the version is fully explicit — devenv.nix is the authoritative source and Dockerfiles / GitHub Actions must match it.
4. Update All Other Files to Match Nix
Update all files to use the same version that Nix is providing:
- Update GitHub Actions - Set
toolchain:to the version from Nix - Update Dockerfiles - Set
FROM rust:X.Y.Zto the version from Nix
This ensures consistency: your local development environment (Nix), CI/CD (GitHub Actions), and production builds (Dockerfiles) all use the same Rust version.
5. Use Search and Replace
To update all versions at once:
# Update stable version in GitHub Actions
find .github/workflows/ -name "*.yml" -type f -exec sed -i 's/toolchain: 1.90.0/toolchain: X.Y.Z/g' {} +
# Update stable version in Dockerfiles
find packages/ -name "Dockerfile*" -type f -exec sed -i 's/FROM rust:1.90.0/FROM rust:X.Y.Z/g' {} +
# Remove any nightly references (if any exist)
find packages/ -name "Dockerfile*" -type f -exec sed -i '/rustup toolchain install nightly/d' {} +
find packages/ -name "Dockerfile*" -type f -exec sed -i '/rustup default nightly/d' {} +
Warning: Always review changes after automated replacements!
6. Test the Changes
After updating, test thoroughly:
Local Testing
# Rebuild devenv to use new Rust version
devenv shell
# Verify Rust version
rustc --version
# Should output: rustc X.Y.Z (expected version)
cargo --version
# Run tests locally
cd packages/
cargo test
cargo fmt -- --check
CI Testing
- Commit your changes to a feature branch
- Open a pull request
- Wait for all CI checks to pass:
- Tests workflow
- Lint & Prettify workflow
- Step CLI build workflow
Docker Testing
Build a few key Docker images to verify:
# Test building services
cd packages/
docker build -f braid/Dockerfile -t test-braid .
docker build -f windmill/Dockerfile -t test-windmill .
docker build -f Dockerfile.cargo-packages -t test-cargo .
7. Verify Consistency
After all updates, verify everything is in sync:
# Should show consistent versions across all files
grep -r "toolchain: 1\." .github/workflows/
grep -r "FROM rust:1\." packages/
# Should return NO results (no nightly versions should exist)
grep -r "nightly" packages/ | grep -i rust
Reference: Complete File List
Here's the complete list of files that need updating:
GitHub Actions (3 files)
.github/workflows/tests.yml.github/workflows/lint_prettify.yml.github/workflows/step_cli_build.yml
Nix Configuration (2 files)
devenv.nixpackages/sequent-core/flake.nix(pluspackages/sequent-core/flake.lockifrust-overlayneeds updating)
Dockerfiles (19 files)
packages/Dockerfile.cargo-packagespackages/braid/Dockerfilepackages/braid/Dockerfile.prodpackages/braid/Dockerfile.prod-vstl-dependenciespackages/windmill/Dockerfilepackages/windmill/Dockerfile.prodpackages/windmill/Dockerfile.prod-vstl-dependenciespackages/harvest/Dockerfilepackages/harvest/Dockerfile.prodpackages/harvest/Dockerfile.prod-vstl-dependenciespackages/b3/Dockerfile.prodpackages/b3/Dockerfile.prod-vstl-dependenciespackages/e2e/src/mock_server/Dockerfile.prodpackages/loadtesting/Dockerfilepackages/Dockerfile.immudb-init-vstl-dependenciespackages/Dockerfile.immudb-init.prodpackages/step-cli/Dockerfilepackages/orare/doc_renderer/Dockerfile
Best Practices
- Update regularly - Stay reasonably current with stable Rust releases
- Test thoroughly - Don't skip the testing steps
- Update together - Never update just one location; always update all
- Document changes - Note any code changes required for the new version
- Monitor CI - Watch for failures in the automated pipeline
- Use stable only - We don't use nightly features; stick to stable Rust