Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ on:
jobs:
extract-version:
name: Extract version
runs-on: warp-ubuntu-2404-x64-16x
runs-on: warp-ubuntu-2404-x64-2x
outputs:
VERSION: ${{ steps.extract_version.outputs.VERSION }}
steps:
Expand Down Expand Up @@ -82,62 +82,60 @@ jobs:
- ${{ github.event.inputs.features || '' }}

steps:
- name: Install dependencies
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Install rust
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
curl \
git \
libclang-dev \
libssl-dev \
pkg-config \
protobuf-compiler
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

- uses: actions/checkout@v4

- name: Build
- name: Build reproducible binary with Docker
run: |
FEATURES=${{ matrix.features }} make build
VERSION=${{ needs.extract-version.outputs.VERSION }} make build-deb
RUST_TOOLCHAIN=$(rustc --version | cut -d' ' -f2)
docker build \
--build-arg "RUST_TOOLCHAIN=${RUST_TOOLCHAIN}" \
--build-arg "FEATURES=${{ matrix.features }}" \
--build-arg "VERSION=${{ needs.extract-version.outputs.VERSION }}" \
-f docker/Dockerfile.reproducible -t rbuilder:release \
--output type=local,dest=./target .

- name: Upload rbuilder artifact
uses: actions/upload-artifact@v4
with:
name: rbuilder-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }}
path: target/${{ matrix.configs.target }}/${{ matrix.configs.profile }}/rbuilder
path: target/${{ matrix.configs.profile }}/rbuilder

- name: Upload rbuilder-operator artifact
uses: actions/upload-artifact@v4
with:
name: rbuilder-operator-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }}
path: target/${{ matrix.configs.target }}/${{ matrix.configs.profile }}/rbuilder-operator
path: target/${{ matrix.configs.profile }}/rbuilder-operator

- name: Upload reth-rbuilder artifact
uses: actions/upload-artifact@v4
with:
name: reth-rbuilder-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }}
path: target/${{ matrix.configs.target }}/${{ matrix.configs.profile }}/reth-rbuilder
path: target/${{ matrix.configs.profile }}/reth-rbuilder

- name: Upload bid-scraper artifact
uses: actions/upload-artifact@v4
with:
name: bid-scraper-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }}
path: target/${{ matrix.configs.target }}/${{ matrix.configs.profile }}/bid-scraper
path: target/${{ matrix.configs.profile }}/bid-scraper

- name: Upload rbuilder-rebalancer artifact
uses: actions/upload-artifact@v4
with:
name: rbuilder-rebalancer-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }}
path: target/${{ matrix.configs.target }}/${{ matrix.configs.profile }}/rbuilder-rebalancer
path: target/${{ matrix.configs.profile }}/rbuilder-rebalancer

- name: Upload *.deb packages
uses: actions/upload-artifact@v4
with:
name: deb-${{ needs.extract-version.outputs.VERSION }}-${{ matrix.configs.target }}${{ matrix.features && '-' }}${{ matrix.features }}
path: target/${{ matrix.configs.target }}/debian/*.deb
path: target/debian/*.deb


draft-release:
Expand Down
78 changes: 78 additions & 0 deletions .github/workflows/reprotest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: reproducible-build-test

on:
workflow_dispatch: {}
schedule:
- cron: "0 1 */2 * *"

jobs:
build:
name: build reproducible binaries
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include:
- runner: warp-ubuntu-2404-x64-32x
machine: machine-1
- runner: warp-ubuntu-2204-x64-32x
machine: machine-2
steps:
- uses: actions/checkout@v5

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Install rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
- name: Build reproducible binary with Docker
run: |
RUST_TOOLCHAIN=$(rustc --version | cut -d' ' -f2)
Comment on lines +25 to +31
Copy link
Contributor

@ilyaluk ilyaluk Nov 7, 2025

Choose a reason for hiding this comment

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

If rust is installed only for latest version, would it be better to just pin the version here instead of installing toolchain?

Same for release.yaml.

Copy link
Contributor Author

@bakhtin bakhtin Nov 7, 2025

Choose a reason for hiding this comment

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

I install rust toolchain just to parse rust-toolchain.yml file and pull the correct Docker/Rust image. rust-toolchain may contain something like stable or a numerical version of Rust. So it is hard to directly parse the file without (some) rust toolchain installed

docker build \
--build-arg "RUST_TOOLCHAIN=${RUST_TOOLCHAIN}" \
-f docker/Dockerfile.reproducible -t rbuilder:release \
--output type=local,dest=./target .
- name: Calculate SHA256
id: sha256
run: |
sha256sum target/reproducible/{rbuilder-operator,rbuilder-rebalancer} > checksums.sha256
echo "Binaries SHA256 on ${{ matrix.machine }}: $(cat checksums.sha256)"
- name: Upload the hash
uses: actions/upload-artifact@v4
with:
name: checksums-${{ matrix.machine }}
path: |
checksums.sha256
retention-days: 1

compare:
name: compare reproducible binaries
needs: build
runs-on: ubuntu-latest
steps:
- name: Download artifacts from machine-1
uses: actions/download-artifact@v4
with:
name: checksums-machine-1
path: machine-1/
- name: Download artifacts from machine-2
uses: actions/download-artifact@v4
with:
name: checksums-machine-2
path: machine-2/
- name: Compare SHA256 hashes
run: |
echo "=== SHA256 Comparison ==="
echo "Machine 1 hashes:"
cat machine-1/checksums.sha256
echo "Machine 2 hashes:"
cat machine-2/checksums.sha256
if cmp -s machine-1/checksums.sha256 machine-2/checksums.sha256; then
echo "βœ… SUCCESS: Binaries are identical (reproducible build verified)"
else
echo "❌ FAILURE: Binaries differ (reproducible build failed)"
exit 1
fi
35 changes: 26 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ ifeq ($(IS_X86_64),1)
BUILD_ENV = SOURCE_DATE_EPOCH=$(SOURCE_DATE) \
RUSTFLAGS="${RUST_BUILD_FLAGS}" \
LC_ALL=${LOCALE_VAL} \
TZ=${TZ_VAL}
TZ=${TZ_VAL} \
JEMALLOC_OVERRIDE=/usr/lib/x86_64-linux-gnu/libjemalloc.a
else
# Non-x86_64: Use release profile without reproducible build flags
BUILD_PROFILE = release
Expand All @@ -72,19 +73,19 @@ endif

.PHONY: build
build: ## Build (release version)
$(BUILD_ENV) cargo build --features "$(FEATURES)" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --profile $(BUILD_PROFILE) --workspace
$(BUILD_ENV) cargo build --features "$(FEATURES) jemalloc-unprefixed" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --profile $(BUILD_PROFILE) --workspace

.PHONY: build-bid-scraper
build-bid-scraper: ## Build the bid-scraper binary (release version)
$(BUILD_ENV) cargo build --features "$(FEATURES)" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --bin bid-scraper --profile $(BUILD_PROFILE)

.PHONY: build-rbuilder-operator
build-rbuilder-operator: ## Build the rbuilder-operator binary (release version)
$(BUILD_ENV) cargo build --features "$(FEATURES)" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --bin rbuilder-operator --profile $(BUILD_PROFILE)
$(BUILD_ENV) cargo build --features "$(FEATURES) jemalloc-unprefixed" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --bin rbuilder-operator --profile $(BUILD_PROFILE)

.PHONY: build-rbuilder-rebalancer
build-rbuilder-rebalancer: ## Build the rbuilder-rebalancer binary (release version)
$(BUILD_ENV) cargo build --features "$(FEATURES)" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --bin rbuilder-rebalancer --profile $(BUILD_PROFILE)
$(BUILD_ENV) cargo build --features "$(FEATURES) jemalloc-unprefixed" --locked $(if $(BUILD_TARGET),--target $(BUILD_TARGET)) --bin rbuilder-rebalancer --profile $(BUILD_PROFILE)

.PHONY: build-dev
build-dev: ## Build (debug version)
Expand All @@ -94,35 +95,51 @@ build-dev: ## Build (debug version)
docker-image-rbuilder: ## Build a rbuilder Docker image
docker build --platform linux/amd64 --target rbuilder-runtime --build-arg FEATURES="$(FEATURES)" -t rbuilder -f docker/Dockerfile.rbuilder .

.PHONE: docker-image-rbuilder-operator
docker build --platform linux/amd64 --target rbuilder-runtime --build-arg FEATURES="$(FEATURES)" -t rbuilder -f docker/Dockerfile.rbuilder-operator .
.PHONY: docker-image-rbuilder-operator
docker-image-rbuilder-operator: ## Build a rbuilder-operator Docker image
docker build --platform linux/amd64 --target rbuilder-runtime --build-arg FEATURES="$(FEATURES) jemalloc-unprefixed" -t rbuilder-operator -f docker/Dockerfile.rbuilder-operator .

.PHONY: docker-image-test-relay
docker-image-test-relay: ## Build a test relay Docker image
docker build --platform linux/amd64 --target test-relay-runtime --build-arg FEATURES="$(FEATURES)" . -t test-relay

##@ Debian Packages

# Define binary paths for smart dependencies
BID_SCRAPER_BIN := target/$(if $(BUILD_TARGET),$(BUILD_TARGET)/)$(BUILD_PROFILE)/bid-scraper
RBUILDER_OPERATOR_BIN := target/$(if $(BUILD_TARGET),$(BUILD_TARGET)/)$(BUILD_PROFILE)/rbuilder-operator
RBUILDER_REBALANCER_BIN := target/$(if $(BUILD_TARGET),$(BUILD_TARGET)/)$(BUILD_PROFILE)/rbuilder-rebalancer

.PHONY: install-cargo-deb
install-cargo-deb:
@command -v cargo-deb >/dev/null 2>&1 || cargo install cargo-deb@3.6.0 --locked

# Build individual binaries only if they don't exist - delegate to existing build targets
$(BID_SCRAPER_BIN): build-bid-scraper
@# Binary built by build-bid-scraper target

$(RBUILDER_OPERATOR_BIN): build-rbuilder-operator
@# Binary built by build-rbuilder-operator target

$(RBUILDER_REBALANCER_BIN): build-rbuilder-rebalancer
@# Binary built by build-rbuilder-rebalancer target

.PHONY: build-deb-bid-scraper
build-deb-bid-scraper: install-cargo-deb build-bid-scraper ## Build bid-scraper Debian package
build-deb-bid-scraper: install-cargo-deb $(BID_SCRAPER_BIN) ## Build bid-scraper Debian package
cargo deb --profile $(BUILD_PROFILE) --no-build --no-dbgsym --no-strip \
-p bid-scraper \
$(if $(BUILD_TARGET),--target $(BUILD_TARGET)) \
$(if $(VERSION),--deb-version "1~$(VERSION)")

.PHONY: build-deb-rbuilder-operator
build-deb-rbuilder-operator: install-cargo-deb build-rbuilder-operator ## Build rbuilder-operator Debian package
build-deb-rbuilder-operator: install-cargo-deb $(RBUILDER_OPERATOR_BIN) ## Build rbuilder-operator Debian package
cargo deb --profile $(BUILD_PROFILE) --no-build --no-dbgsym --no-strip \
-p rbuilder-operator \
$(if $(BUILD_TARGET),--target $(BUILD_TARGET)) \
$(if $(VERSION),--deb-version "1~$(VERSION)")

.PHONY: build-deb-rbuilder-rebalancer
build-deb-rbuilder-rebalancer: install-cargo-deb build-rbuilder-rebalancer ## Build rbuilder-rebalancer Debian package
build-deb-rbuilder-rebalancer: install-cargo-deb $(RBUILDER_REBALANCER_BIN) ## Build rbuilder-rebalancer Debian package
cargo deb --profile $(BUILD_PROFILE) --no-build --no-dbgsym --no-strip \
-p rbuilder-rebalancer \
$(if $(BUILD_TARGET),--target $(BUILD_TARGET)) \
Expand Down
1 change: 1 addition & 0 deletions crates/rbuilder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ criterion = { workspace = true, features = ["html_reports", "async_tokio"] }
# TODO: remove?
optimism = []
redact-sensitive = []
jemalloc-unprefixed = ["tikv-jemallocator/unprefixed_malloc_on_supported_platforms"]

[[bench]]
name = "bench_main"
Expand Down
18 changes: 18 additions & 0 deletions docker/Dockerfile.reproducible
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ARG RUST_TOOLCHAIN=1.89.0
FROM docker.io/rust:$RUST_TOOLCHAIN-trixie AS builder

ARG FEATURES VERSION
# Switch to snapshot repository
RUN sed -i '/^# http/{N;s|^# \(http[^ ]*\)\nURIs: .*|# \1\nURIs: \1|}' /etc/apt/sources.list.d/debian.sources
RUN apt-get -o Acquire::Check-Valid-Until=false update && \
apt-get install -y \
libjemalloc-dev \
libclang-dev \
protobuf-compiler \
cmake
WORKDIR /build
COPY . .
RUN SOURCE_DATE=1730000000 make build && make build-deb
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe use last commit timestamp as SOURCE_DATE?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It may not even be a git tree (e.g., if downloaded as a tar archive from GH) so I don't want to rely on it


FROM scratch AS artifacts
COPY --from=builder /build/target/x86_64-unknown-linux-gnu/ /
1 change: 0 additions & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[toolchain]
channel = "stable"
version = "1.88.0"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

version is not recognized as the valid option and ignored: https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file

components = ["rustfmt", "clippy"]
Loading