Skip to content

ci: switch from dtolnay/rust-toolchain to actions-rust-lang/setup-rust-toolchain#3

Merged
StefanSteiner merged 1 commit into
mainfrom
ssteiner/switch-to-setup-rust-toolchain
May 14, 2026
Merged

ci: switch from dtolnay/rust-toolchain to actions-rust-lang/setup-rust-toolchain#3
StefanSteiner merged 1 commit into
mainfrom
ssteiner/switch-to-setup-rust-toolchain

Conversation

@StefanSteiner
Copy link
Copy Markdown
Contributor

Switch from dtolnay/rust-toolchain to actions-rust-lang/setup-rust-toolchain

Summary

Replaces dtolnay/rust-toolchain@stable + Swatinem/rust-cache@v2 with the official actions-rust-lang/setup-rust-toolchain@v1 action across all 9 toolchain-install sites. Fixes a recurring CI failure on macos-14 runners and consolidates toolchain + cache into a single action.

Why

The macos-14 GitHub Actions runner image recently started shipping Homebrew's rust package, which symlinks cargo to rustup-init. With no toolchain installed, cargo test then invokes rustup-init's CLI parser and fails:

error: error: unexpected argument 'test' found
Usage: rustup-init[EXE] [OPTIONS]

I tried two workarounds before this PR:

  1. brew uninstall rust + symlink purge before dtolnay/rust-toolchain@stable runs. This unblocked the toolchain install, but dtolnay/rust-toolchain's internal : create cachekey composite step couldn't find rustc on PATH and failed mid-action.
  2. Manual echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" after the toolchain action. The "Ensure cargo is on PATH" step itself succeeded (which cargo printed /Users/runner/.cargo/bin/cargo), but the $GITHUB_PATH mechanism wasn't propagating to subsequent steps — the "Workspace tests" step still got cargo: command not found.

Both workarounds are brittle. The official actions-rust-lang/setup-rust-toolchain@v1 action is more actively maintained, handles macos-14 quirks, and bundles Swatinem/rust-cache internally so we can drop the explicit cache step.

What changes

9 toolchain-install sites converted across 4 workflows

Workflow Job(s) Cache key
.github/workflows/ci.yml fmt (cache disabled — rustfmt doesn't need it)
.github/workflows/ci.yml clippy clippy
.github/workflows/ci.yml test (matrix: ubuntu / macos-14 / windows) test-${{ matrix.os }}
.github/workflows/ci.yml publish-dry-run publish-dry-run
.github/workflows/ci.yml audit audit
.github/workflows/release.yml verify release-verify
.github/workflows/release.yml publish release-publish
.github/workflows/npm-build-publish.yml build-npm (matrix per target) npm-${{ matrix.target }}
.github/workflows/verify-hyperd-pin.yml verify verify-hyperd-pin

rustflags: "" on every site

The new action sets RUSTFLAGS="-D warnings" at the environment level by default. Our workspace has many warn-level lints (missing_docs, missing_debug_implementations, etc.) that would silently turn into hard errors in test/build jobs.

We disable the action's default with rustflags: "" everywhere so:

  • [workspace.lints] in Cargo.toml remains the single source of truth for lint policy.
  • The clippy job continues to enforce -D warnings via its explicit -- -D warnings argument (no behavior change there).
  • Test/build jobs continue to allow warn-level lints to be warnings, matching pre-migration behavior.

This was caught by adversarial review — without it, every test job would fail on the first warn-level lint hit.

macOS brew-uninstall steps kept as defense-in-depth

The Remove pre-installed Homebrew rust (macOS) steps in ci.yml (test job) and npm-build-publish.yml (build-npm job) stay. Comments document why: macos-14 runner image regressions are recurring, and the || true short-circuits make the steps no-ops when brew rust isn't installed.

Smaller cleanups

  • verify-hyperd-pin.yml: bumped actions/checkout@v4@v6 to match the other workflows.
  • Removed the now-redundant manual "Ensure cargo is on PATH" steps.
  • npm-build-publish.yml: dtolnay's targets: (plural) renamed to target: (singular) to match the new action's input.

Adversarial review

A code-reviewer subagent flagged:

  • CRITICAL: RUSTFLAGS regression — fixed by adding rustflags: "" to all 9 sites with explanatory comments. Verified by fetching the action's action.yml directly.
  • MAJOR: @v1 is a moving tag — accepted as the same risk profile as the previous dtolnay@stable.
  • MAJOR: cargo-audit cache doesn't auto-invalidate — accepted as not a regression.
  • MAJOR: brew-uninstall may be unnecessary now — kept as defense-in-depth with a comment.
  • MINOR: checkout version inconsistency — fixed.
  • MINOR: verify-hyperd-pin lost workspaces: . -> target — verified the action's default matches the previous explicit setting; not a regression.

Test plan

  • CI green on this PR — specifically the test (macos-14) matrix entry, which has been failing pre-fix.
  • CI green on the linux and windows test matrix entries (no behavior change expected).
  • clippy job still enforces -D warnings on all targets/features.
  • audit job still runs cargo audit --deny warnings against the live RustSec advisory-db.
  • After merge, watch the next push to main to confirm release-please.yml still works (no toolchain-install in that workflow, but want to confirm nothing else regressed).

…t-toolchain

The dtolnay action's macos-14 PATH handling regressed when GitHub
started shipping Homebrew's rust package on the runner image.
`cargo` resolved to `rustup-init`, and even after manually purging
brew's rust + writing $GITHUB_PATH, PATH wasn't propagating to
later steps. Switch all 9 toolchain-install sites to the
actions-rust-lang/setup-rust-toolchain@v1 action, which is the
official recommended setup and bundles Swatinem/rust-cache so we
can drop the explicit cache step.

Notes:
- Pass rustflags: "" everywhere to disable the new action's
  default RUSTFLAGS=-D warnings. Workspace lint policy lives in
  [workspace.lints] in Cargo.toml; promoting warn-level lints to
  hard errors at the env level would break test/build jobs that
  rely on warnings being warnings.
- Keep the macOS brew-uninstall steps as defense-in-depth.
- Bump verify-hyperd-pin.yml's actions/checkout to @v6 to match
  the rest of the workflows.
@StefanSteiner StefanSteiner merged commit 5dd1d02 into main May 14, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant