chore(ci): stop rebuilding cross on every release run - #280
Conversation
rust-cache ran after `cargo install cross`, so CARGO_HOME/bin and the .crates manifests were never restored in time and cross was compiled from source on all three release runs today (~48s per Linux job). Also drops the setup-mold step, which had no effect: both Linux targets build inside the cross ubuntu:24.04 container, where the host linker is not visible, and nothing in Cross.toml or .cargo/config.toml selects it. fail-fast is off so one flaky target no longer cancels its siblings, which previously forced a full matrix rebuild. None of this changes the produced binary.
📝 WalkthroughWalkthroughThe release workflow now keeps remaining matrix targets running after failures and reorders build setup by configuring the Rust toolchain before caching, running the cache action before installing ChangesRelease workflow
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR refines the release workflow matrix to reduce unnecessary work and improve resiliency during multi-target release builds, without changing the built binaries or published artifacts.
Changes:
- Disable matrix
fail-fastso one flaky target doesn’t cancel sibling builds. - Remove
setup-moldfrom the release workflow since Linux builds run insidecrosscontainers where host-installed mold isn’t used. - Move
Swatinem/rust-cachebeforecargo install crossso the cargo home state is restored early enough to avoid rebuildingcrossfrom source each run.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yml:
- Around line 95-97: Update the rust-cache step in the release job to avoid
restoring cached release artifacts by using lookup-only for release/tag events
or disabling caching, and set cache-on-failure to false so failed releases
cannot save build state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 298c3139-5c82-4247-b18b-2673b8145d43
📒 Files selected for processing (1)
.github/workflows/release.yml
| - uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2 | ||
| with: | ||
| cache-on-failure: true |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
sed -n '1,62p' .github/workflows/release.yml
rg -n 'pull_request|pull_request_target|workflow_dispatch|release:|push:|tags:|permissions:' .github/workflows/release.ymlRepository: berachain/bera-reth
Length of output: 2475
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== release.yml outline relevant lines =="
wc -l .github/workflows/release.yml
sed -n '80,160p' .github/workflows/release.yml
sed -n '160,260p' .github/workflows/release.yml
echo
echo "== rust-cache uses in repo =="
rg -n 'Swatinem/rust-cache|cargo build|cargo package|cargo publish|cargo signing|tar |ghcr|docker|build|release|permissions:' .github/workflows/release.yml
echo
echo "== rust-cache README inputs from tag referenced in comment =="
python3 - <<'PY'
import urllib.request
url='https://raw.githubusercontent.com/Swatinem/rust-cache/v2.9.1/README.md'
try:
s=urllib.request.urlopen(url, timeout=20).read().decode()
for term in ['lookup-only','cache-on-failure','CARGO_HOME','registry/index-cache','Save workflow cache']:
print(f'--- {term} ---')
for i,line in enumerate(s.splitlines(),1):
if term.lower() in line.lower():
print(f'{i}: {line}')
except Exception as e:
print(f'ERROR fetching {url}: {e}')
PY
echo
echo "== workflow_dispatch trigger details =="
sed -n '1,25p' .github/workflows/release.ymlRepository: berachain/bera-reth
Length of output: 149
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file lengths =="
wc -l .github/workflows/release.yml
echo
echo "== top of release.yml =="
sed -n '1,120p' .github/workflows/release.yml
echo
echo "== mid release.yml =="
sed -n '120,220p' .github/workflows/release.yml
echo
echo "== rust-cache and command context =="
rg -n 'Swatinem/rust-cache|lookup-only|cache-on-failure|cargo (build|check|clippy|test|doc|package|install|publish|metadata)|docker|ghcr|RELEASE|upload|create |signature|sign|permissions:' .github/workflows/release.ymlRepository: berachain/bera-reth
Length of output: 149
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== files =="
git ls-files .github/workflows/release.yml
echo
echo "== line count =="
awk 'END{print NR}' .github/workflows/release.yml
echo
echo "== targeted grep =="
awk '
/Swatinem\/rust-cache|lookup-only|cache-on-failure|cargo (build|check|clippy|test|doc|package|install|publish|metadata)|docker|ghcr|RELEASE|upload|create |signature|sign|permissions:/ {
printf "%d: %s\n", NR, $0
}
' .github/workflows/release.ymlRepository: berachain/bera-reth
Length of output: 149
🏁 Script executed:
#!/bin/bash
set -euo pipefail
if [ -f .github/workflows/release.yml ]; then
stat --printf="size=%s, lines=%s\n" .github/workflows/release.yml
else
echo "missing release.yml"
exit 0
fi
echo
echo "== head =="
head -n 220 .github/workflows/release.yml
echo
echo "== rust-cache and command context =="
grep -nE 'Swatinem/rust-cache|lookup-only|cache-on-failure|cargo (build|check|clippy|test|doc|package|install|publish|metadata)|docker|ghcr|RELEASE|upload|create |signature|sign|permissions:' .github/workflows/release.yml || true
echo
echo "== fetch rust-cache README snippets =="
python3 - <<'PY'
import urllib.request, re
url='https://raw.githubusercontent.com/Swatinem/rust-cache/v2.9.1/README.md'
try:
s=urllib.request.urlopen(url, timeout=20).read().decode()
for term in ['lookup-only','cache-on-failure','CARGO_HOME','registry/index-cache','Save workflow cache','CARGO_TARGET_DIR','Cargo lock']:
lines=re.compile(r'.*', re.I).findall(s)
hits=[(i,line) for i,line in enumerate(lines,1) if term.lower() in line.lower()]
print(f'--- {term} ({len(hits)}) ---')
for i,line in hits[:8]:
print(f'{i}: {line}')
except Exception as e:
print(f'ERROR fetching {url}: {type(e).__name__}: {e}')
PY
echo
echo "== workflow_trigger =="
head -n 35 .github/workflows/release.ymlRepository: berachain/bera-reth
Length of output: 199
🏁 Script executed:
#!/bin/sh
set -euo pipefail
if [ -f .github/workflows/release.yml ]; then
wc -l .github/workflows/release.yml
echo
head -n 240 .github/workflows/release.yml
echo
grep -nE 'Swatinem/rust-cache|lookup-only|cache-on-failure|cargo (build|check|clippy|test|doc|package|install|publish|metadata|fmt)|rustc|docker|ghcr|cargo-vet|RELEASE|upload|create |signature|sign|permissions:' .github/workflows/release.yml || true
else
echo "missing release.yml"
fi
echo
python3 - <<'PY'
import urllib.request, re
url='https://raw.githubusercontent.com/Swatinem/rust-cache/v2.9.1/README.md'
try:
text=urllib.request.urlopen(url, timeout=20).read().decode()
terms=['lookup-only','cache-on-failure','CARGO_HOME','registry/index-cache','CARGO_TARGET_DIR']
for term in terms:
print(f'--- {term} ---')
for i,line in enumerate(text.splitlines(),1):
if term.lower() in line.lower():
print(f'{i}: {line}')
except Exception as e:
print(f'ERROR: {type(e).__name__}: {e}')
PYRepository: berachain/bera-reth
Length of output: 11832
🌐 Web query:
Swatinem rust-cache v2 README lookup-only cache-on-failure CARGO_HOME cargo install
💡 Result:
The rust-cache action (typically version 2+) provides several configuration options to manage how CARGO_HOME and other directories are cached, as well as how the cache is accessed and updated [1][2]. Key configuration options include: lookup-only When set to true, this option checks if a cache entry exists for the given key without actually downloading or restoring the cache contents [3][2]. This is useful for workflows where you only need to verify the existence of a cache or conditionally run steps based on whether a cache hit occurred [4][5]. cache-on-failure This boolean option (defaulting to false) determines whether the action should save the cache even if the workflow job fails [3][2]. Enabling this allows you to persist partial build artifacts or state even when a build process does not complete successfully [6][2]. CARGO_HOME and cache-bin The action automatically handles caching for the Rust registry and, by default, the ~/.cargo/bin directory [7][2]. You can toggle the caching of the bin directory using the cache-bin option [3][2]. Setting cache-bin to false is particularly relevant for long-lived runners (e.g., self-hosted) where wiping the bin directory could inadvertently remove system tools like rustup, rustc, or cargo [8]. For cargo install workflows, the action tracks installed binaries if cache-bin is true, ensuring that tools installed during the workflow are preserved across runs while system binaries are handled appropriately [7]. These options are specified in your workflow YAML file under the with section of the Swatinem/rust-cache step [6][2]. Example configuration: - uses: Swatinem/rust-cache@v2 with: lookup-only: false cache-on-failure: true cache-bin: true
Citations:
- 1: https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md
- 2: https://github.com/Swatinem/rust-cache/blob/master/action.yml
- 3: https://github.com/step-security/rust-cache/blob/main/action.yml
- 4: Adds an option to do lookup-only of the cache Swatinem/rust-cache#217
- 5: Add
lookup-onlyoption actions/cache#1041 - 6: https://context7.com/swatinem/rust-cache/llms.txt
- 7: https://deepwiki.com/Swatinem/rust-cache/3.3-caching-strategy
- 8: Allow opting out of caching $CARGO_HOME/bin. Swatinem/rust-cache#216
Do not restore release artifacts from rust-cache in the release job.
This release workflow is only triggered by signed tags or manual dispatch, and the build job restores ~/.cargo before installing cross, building release binaries, signing them with GPG_SIGNING_KEY, and uploading release artifacts. Use lookup-only: ${{ github.event_name == 'release' || startsWith(github.ref, 'refs/tags/') }} for tag releases, or disable caching here entirely; also set cache-on-failure: false so failed release jobs cannot persist corrupted build state.
🧰 Tools
🪛 zizmor (1.28.0)
[error] 95-95: runtime artifacts potentially vulnerable to a cache poisoning attack (cache-poisoning): enables caching by default
(cache-poisoning)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml around lines 95 - 97, Update the rust-cache
step in the release job to avoid restoring cached release artifacts by using
lookup-only for release/tag events or disabling caching, and set
cache-on-failure to false so failed releases cannot save build state.
Source: Linters/SAST tools
Summary
Three low-risk fixes to the release matrix. None of them change the compiled binary or the release artifacts.
crosswas recompiled from source on every run.Swatinem/rust-cachewas ordered aftercargo install cross, soCARGO_HOME/bin,.crates.tomland.crates2.jsonwere restored too late for cargo to see that the pinned rev was already installed. On top of that, the action's save step only keeps binaries that appeared after it ran, socrosswas never written to the cache in the first place. Moving the cache step ahead of the install fixes both halves. It cost ~48s on each Linux job in every release today (v1.4.3-rc.1, v1.4.3, v1.4.4-rc.0, v1.4.4).setup-molddid nothing. Both Linux targets build viacross build, which compiles inside theubuntu:24.04container declared inCross.toml. A linker installed on the host isn't visible there, and neitherCross.tomlnor.cargo/config.tomlselects it (rg -i 'mold|fuse-ld'matched only this step). Removed. Making mold actually apply inside the container is worth doing separately, but it changes linking under-C target-feature=+crt-staticand shouldn't ride along with a release-critical change.fail-fast: trueon a release matrix. A transient failure in one target (anapt-gethiccup in the cross container, for instance) cancelled the other two and required re-running all three ~25 minute builds. Now a single target can be retried on its own.Follow-ups not included here
aarch64-apple-darwinon the 3-coremacos-14runner is the critical path in every release (28m / 27m / 20m build step vs 21–26m on Linux). Since the matrix runs in parallel, a larger Apple-silicon runner is the only thing that shortens wall-clock release time.v1.4.4-rc.0andv1.4.4share the tree48c10a88edb4467d44157aef3ff6808f265e8ac6, so identical source was compiled twice ~35 minutes apart. Keying artifact reuse on the tree SHA would let an rc→final promotion re-sign the existing binaries instead of rebuilding.maxperfislto = "fat"withcodegen-units = 1, which is where most of the 20–28 minutes goes. Thin LTO for-rctags only would be measurable to evaluate without affecting shipped builds.Summary by CodeRabbit