Skip to content

Fix ARM Rust cache to avoid reinstalling on every build#1665

Draft
zlav wants to merge 2 commits intomasterfrom
zach/fix-arm-rust-cache
Draft

Fix ARM Rust cache to avoid reinstalling on every build#1665
zlav wants to merge 2 commits intomasterfrom
zach/fix-arm-rust-cache

Conversation

@zlav
Copy link
Member

@zlav zlav commented Mar 10, 2026

Overview

Fix the Linux ARM build's Rust cache. Currently, Rust gets reinstalled from scratch every run because the cache action runs on the host but the build runs inside a Docker container — they see different filesystems.

Fix: point CARGO_HOME and RUSTUP_HOME to workspace-relative paths that both the host and container can see, then cache those paths.

Acceptance criteria

  • ARM build skips rustup install on cache hit.
  • cargo build --release gets incremental compilation from cached target/.
  • Non-ARM builds unchanged.

Testing plan

  1. First run: cold cache, same timing as before.
  2. Second run: cache restores, verify rustup install is skipped and cargo build is incremental.
  3. Check a non-ARM build (e.g. Linux x64) still works normally.

Risks

  • First run is identical to today (cold cache). If caching breaks, it falls back to a full install — no worse than current behavior.
  • The .rust/ dir lives in the workspace during CI only. It's not committed (workspace is ephemeral).

Metrics

  • Before: ~5-10 min on Rust install + full compile every ARM build.
  • After: seconds on cache hit (skip install, incremental compile).

References

N/A — internal CI improvement.

Checklist

  • I added tests for this PR's change (or explained in the PR description why tests don't make sense).
    • CI workflow change — validated by running the workflow itself.
  • If this PR introduced a user-visible change, I added documentation into docs/.
  • If this PR added docs, I added links as appropriate to the user manual's ToC in docs/README.ms and gave consideration to how discoverable or not my documentation is.
  • If this change is externally visible, I updated Changelog.md. If this PR did not mark a release, I added my changes into an ## Unreleased section at the top.
  • If I made changes to .fossa.yml or fossa-deps.{json.yml}, I updated docs/references/files/*.schema.json AND I have updated example files used by fossa init command. You may also need to update these if you have added/removed new dependency type (e.g. pip) or analysis target type (e.g. poetry).
  • If I made changes to a subcommand's options, I updated docs/references/subcommands/<subcommand>.md.

The ARM build installs Rust inside a Docker container, but the
Swatinem/rust-cache action runs on the host — so the cache was never
hitting. Move CARGO_HOME and RUSTUP_HOME to workspace-relative paths
(.rust/) and cache them with actions/cache, which sees the same
filesystem as the container mount. Skip rustup install when cargo
already exists from a cache restore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@zlav zlav requested a review from a team as a code owner March 10, 2026 23:09
@zlav zlav requested a review from Conor-FOSSA March 10, 2026 23:09
@zlav zlav marked this pull request as draft March 10, 2026 23:10
@zlav zlav removed the request for review from Conor-FOSSA March 10, 2026 23:11
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 10, 2026

Walkthrough

This pull request optimizes CI/CD workflows for ARM builds by introducing caching mechanisms and conditional Rust toolchain setup. Changes to .github/workflows/build-all.yml add an ARM-specific Rust cache strategy using actions/cache@v4 that caches .rust/ and target/ directories, with conditional logic to skip non-ARM cache steps on LinuxARM. Updates to .github/workflows/scripts/build-arm.sh replace unconditional Rust installation with a cache-friendly approach using workspace-relative CARGO_HOME and RUSTUP_HOME environment variables. A guard clause ensures Rust installation only occurs when cargo is unavailable, preventing redundant installations when cache is restored. Existing version checks and build steps remain unchanged.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing ARM Rust caching to prevent unnecessary reinstalls on each build.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description comprehensively covers all required template sections with clear explanations and concrete details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/build-all.yml:
- Around line 97-106: The ARM cache key for the actions/cache step (conditional
on matrix.os == 'LinuxARM' using actions/cache@v4) must include an explicit
toolchain version component so the cached .rust/ toolchain can be invalidated;
add an environment variable like ARM_RUST_CACHE_VERSION (e.g., stable-2026-03)
and include it in both the `key` and `restore-keys` values for the ARM job so
the cache changes when you bump that variable, ensuring the ARM job does not
remain pinned to an old toolchain.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c8ab3163-3133-4229-928a-567a23287aaa

📥 Commits

Reviewing files that changed from the base of the PR and between 925643a and a23cd68.

📒 Files selected for processing (2)
  • .github/workflows/build-all.yml
  • .github/workflows/scripts/build-arm.sh

Comment on lines +97 to +106
- uses: actions/cache@v4
if: ${{ matrix.os == 'LinuxARM' }}
name: Cache ARM Rust toolchain and build
with:
path: |
.rust/
target/
key: ${{ matrix.os-name }}-rust-${{ hashFiles('Cargo.lock') }}
restore-keys: |
${{ matrix.os-name }}-rust-
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== ARM cache key ==="
sed -n '97,106p' .github/workflows/build-all.yml

echo
echo "=== ARM toolchain bootstrap logic ==="
sed -n '15,26p' .github/workflows/scripts/build-arm.sh

Repository: fossas/fossa-cli

Length of output: 1070


🏁 Script executed:

cat -n .github/workflows/build-all.yml | head -100

Repository: fossas/fossa-cli

Length of output: 3902


🏁 Script executed:

# Check for rust-toolchain files in the repo
find . -name "rust-toolchain*" -o -name ".rust-version"

Repository: fossas/fossa-cli

Length of output: 42


🏁 Script executed:

# Search for Rust version specifications in workflows
rg "rust-version|toolchain" .github/workflows/ -A 2 -B 2

Repository: fossas/fossa-cli

Length of output: 2195


Add toolchain versioning to the ARM cache key.

The ARM cache stores .rust/ (the Rust toolchain itself), but its key only changes with Cargo.lock. Non-ARM jobs use dtolnay/rust-toolchain@stable to always install the latest stable Rust, while the ARM job will stay on whatever stable version was cached until the cache expires or Cargo.lock changes. This creates a divergence: ARM can remain on an outdated Rust version indefinitely, breaking independently from other platforms. Add an explicit version component to the cache key, such as an environment variable like ARM_RUST_CACHE_VERSION: stable-2026-03, and include it in both the key and restore-keys fields so you can invalidate the cache when needed.

Suggested direction
 jobs:
   build-all:
+    env:
+      ARM_RUST_CACHE_VERSION: stable-2026-03
     name: ${{ matrix.os-name }}-build
     runs-on: ${{ matrix.os }}
     container: ${{ matrix.container }}
@@ 
     - uses: actions/cache@v4
       if: ${{ matrix.os == 'LinuxARM' }}
       name: Cache ARM Rust toolchain and build
       with:
         path: |
           .rust/
           target/
-        key: ${{ matrix.os-name }}-rust-${{ hashFiles('Cargo.lock') }}
+        key: ${{ matrix.os-name }}-rust-${{ env.ARM_RUST_CACHE_VERSION }}-${{ hashFiles('Cargo.lock') }}
         restore-keys: |
-          ${{ matrix.os-name }}-rust-
+          ${{ matrix.os-name }}-rust-${{ env.ARM_RUST_CACHE_VERSION }}-
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/build-all.yml around lines 97 - 106, The ARM cache key for
the actions/cache step (conditional on matrix.os == 'LinuxARM' using
actions/cache@v4) must include an explicit toolchain version component so the
cached .rust/ toolchain can be invalidated; add an environment variable like
ARM_RUST_CACHE_VERSION (e.g., stable-2026-03) and include it in both the `key`
and `restore-keys` values for the ARM job so the cache changes when you bump
that variable, ensuring the ARM job does not remain pinned to an old toolchain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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