Skip to content

chore(ci): stop rebuilding cross on every release run - #280

Open
chuck-bear wants to merge 1 commit into
mainfrom
ci/release-build-quick-wins
Open

chore(ci): stop rebuilding cross on every release run#280
chuck-bear wants to merge 1 commit into
mainfrom
ci/release-build-quick-wins

Conversation

@chuck-bear

@chuck-bear chuck-bear commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Three low-risk fixes to the release matrix. None of them change the compiled binary or the release artifacts.

cross was recompiled from source on every run. Swatinem/rust-cache was ordered after cargo install cross, so CARGO_HOME/bin, .crates.toml and .crates2.json were 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, so cross was 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-mold did nothing. Both Linux targets build via cross build, which compiles inside the ubuntu:24.04 container declared in Cross.toml. A linker installed on the host isn't visible there, and neither Cross.toml nor .cargo/config.toml selects 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-static and shouldn't ride along with a release-critical change.

fail-fast: true on a release matrix. A transient failure in one target (an apt-get hiccup 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-darwin on the 3-core macos-14 runner 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.0 and v1.4.4 share the tree 48c10a88edb4467d44157aef3ff6808f265e8ac6, 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.
  • maxperf is lto = "fat" with codegen-units = 1, which is where most of the 20–28 minutes goes. Thin LTO for -rc tags only would be measurable to evaluate without affecting shipped builds.

Summary by CodeRabbit

  • Chores
    • Release builds now continue testing remaining targets when one matrix target fails.
    • Updated build setup and toolchain caching steps to improve release workflow reliability.

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.
Copilot AI review requested due to automatic review settings July 29, 2026 22:30
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The 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 cross, and removing Mold setup.

Changes

Release workflow

Layer / File(s) Summary
Matrix failure handling
.github/workflows/release.yml
The build matrix changes fail-fast from true to false, allowing sibling targets to continue running.
Build tool setup ordering
.github/workflows/release.yml
Mold setup is removed, Rust toolchain configuration precedes caching, and the pinned cross installation follows the cache step.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: rezbera

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main CI change: avoiding rebuilding cross on each release run.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-build-quick-wins

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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-fast so one flaky target doesn’t cancel sibling builds.
  • Remove setup-mold from the release workflow since Linux builds run inside cross containers where host-installed mold isn’t used.
  • Move Swatinem/rust-cache before cargo install cross so the cargo home state is restored early enough to avoid rebuilding cross from source each run.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 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

📥 Commits

Reviewing files that changed from the base of the PR and between aa9bc73 and 748c380.

📒 Files selected for processing (1)
  • .github/workflows/release.yml

Comment on lines +95 to +97
- uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
cache-on-failure: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 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.yml

Repository: 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.yml

Repository: 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.yml

Repository: 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.yml

Repository: 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.yml

Repository: 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}')
PY

Repository: 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:


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

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.

2 participants