From 4a2f2f53ed0b8b32529adc498749888b2904f8e7 Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 17:06:02 +0800 Subject: [PATCH 01/10] fix(release): use cross main branch and simplify Cross.toml --- .github/workflows/release.yml | 6 ++--- .github/workflows/test-cross-build.yml | 36 ++++++++++++++++++++++++++ Cross.toml | 17 ------------ 3 files changed, 38 insertions(+), 21 deletions(-) create mode 100644 .github/workflows/test-cross-build.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9f3a1ba..d1cc6ce 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -99,10 +99,8 @@ jobs: cache-on-failure: true key: ${{ matrix.target }} - - name: Install cross - uses: taiki-e/install-action@v2 - with: - tool: cross + - name: Install cross main + run: cargo install cross --git https://github.com/cross-rs/cross - name: Build binary run: cross build --release --locked --target ${{ matrix.target }} --bin morph-reth diff --git a/.github/workflows/test-cross-build.yml b/.github/workflows/test-cross-build.yml new file mode 100644 index 0000000..859e695 --- /dev/null +++ b/.github/workflows/test-cross-build.yml @@ -0,0 +1,36 @@ +name: Test Cross Build (temporary) + +on: + push: + branches: ["fix/cross-build-release"] + +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: 0 + +jobs: + build: + name: Cross Build ${{ matrix.target }} + runs-on: ubuntu-latest + strategy: + matrix: + include: + - target: x86_64-unknown-linux-gnu + - target: aarch64-unknown-linux-gnu + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + key: cross-test-${{ matrix.target }} + + - name: Install cross main + run: cargo install cross --git https://github.com/cross-rs/cross + + - name: Build binary + run: cross build --release --locked --target ${{ matrix.target }} --bin morph-reth diff --git a/Cross.toml b/Cross.toml index 316255a..2a7689e 100644 --- a/Cross.toml +++ b/Cross.toml @@ -1,19 +1,2 @@ -[build] -pre-build = [ - # Use HTTPS for package sources - "apt-get update && apt-get install --assume-yes --no-install-recommends ca-certificates", - "find /etc/apt/ -type f \\( -name '*.list' -o -name '*.sources' \\) -exec sed -i 's|http://|https://|g' {} +", - - # Configure APT retries and timeouts to handle network issues - "echo 'Acquire::Retries \"3\";' > /etc/apt/apt.conf.d/80-retries", - "echo 'Acquire::http::Timeout \"60\";' >> /etc/apt/apt.conf.d/80-retries", - "echo 'Acquire::ftp::Timeout \"60\";' >> /etc/apt/apt.conf.d/80-retries", - - # rust-bindgen dependencies: llvm-dev libclang-dev (>= 10) clang (>= 10) - # Required for reth-mdbx-sys compilation. - # See: https://github.com/cross-rs/cross/wiki/FAQ#using-clang--bindgen - "apt-get update && apt-get install --assume-yes --no-install-recommends llvm-dev libclang-dev clang", -] - [build.env] passthrough = ["JEMALLOC_SYS_WITH_LG_PAGE"] From 952186ebeadc3f00fc585514f3e64930aa925439 Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 17:44:55 +0800 Subject: [PATCH 02/10] fix(docker): use full semver tag with v prefix, remove SHA and major.minor tags --- .github/workflows/docker.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 131e7a8..c42a493 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -39,9 +39,7 @@ jobs: with: images: ${{ env.IMAGE_NAME }} tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=sha,prefix= + type=semver,pattern=v{{version}} type=raw,value=latest,enable=${{ !contains(github.ref, '-') }} - name: Build and push From b1359c7bbc95e47674b98e4fca5af43e4b2cef9c Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 17:47:33 +0800 Subject: [PATCH 03/10] chore: remove temporary test-cross-build workflow --- .github/workflows/test-cross-build.yml | 36 -------------------------- 1 file changed, 36 deletions(-) delete mode 100644 .github/workflows/test-cross-build.yml diff --git a/.github/workflows/test-cross-build.yml b/.github/workflows/test-cross-build.yml deleted file mode 100644 index 859e695..0000000 --- a/.github/workflows/test-cross-build.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Test Cross Build (temporary) - -on: - push: - branches: ["fix/cross-build-release"] - -env: - CARGO_TERM_COLOR: always - CARGO_INCREMENTAL: 0 - -jobs: - build: - name: Cross Build ${{ matrix.target }} - runs-on: ubuntu-latest - strategy: - matrix: - include: - - target: x86_64-unknown-linux-gnu - - target: aarch64-unknown-linux-gnu - steps: - - uses: actions/checkout@v4 - - - uses: dtolnay/rust-toolchain@stable - with: - targets: ${{ matrix.target }} - - - uses: Swatinem/rust-cache@v2 - with: - cache-on-failure: true - key: cross-test-${{ matrix.target }} - - - name: Install cross main - run: cargo install cross --git https://github.com/cross-rs/cross - - - name: Build binary - run: cross build --release --locked --target ${{ matrix.target }} --bin morph-reth From ece9bb77c6a1c9ab8e6cbd4933552101b72c960a Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 18:25:49 +0800 Subject: [PATCH 04/10] chore(makefile): add cross build targets for linux x86_64 and aarch64 --- Makefile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Makefile b/Makefile index 8cf29ef..0357137 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,17 @@ install: ## Build and install the morph-reth binary under `$(CARGO_HOME)/bin`. --profile "$(PROFILE)" \ $(CARGO_INSTALL_EXTRA_FLAGS) +##@ Cross Build (requires Docker + cross: cargo install cross --git https://github.com/cross-rs/cross) + +# Pattern rule: cross-build for any target, e.g. `make build-x86_64-unknown-linux-gnu` +# See: https://github.com/cross-rs/cross/wiki/FAQ#undefined-reference-with-build-std +build-%: ## Cross-build morph-reth for a specific target (e.g. build-x86_64-unknown-linux-gnu). + RUSTFLAGS="-C link-arg=-lgcc -Clink-arg=-static-libgcc" \ + cross build --bin morph-reth --target $* --profile "$(PROFILE)" + +# aarch64 needs larger jemalloc page size (64KB pages on some ARM systems) +build-aarch64-unknown-linux-gnu: export JEMALLOC_SYS_WITH_LG_PAGE=16 + # Create a `.tar.gz` containing the morph-reth binary for a specific target. define tarball_release_binary cp $(CARGO_TARGET_DIR)/$(PROFILE)/morph-reth $(BIN_DIR)/morph-reth From c1e21bbb93dd381c80f3a9694e30a2d4c81317ad Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 19:11:16 +0800 Subject: [PATCH 05/10] fix(release): use make build- in CI and add --locked to cross build --- .github/workflows/release.yml | 2 +- Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d1cc6ce..a3f3dc9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -103,7 +103,7 @@ jobs: run: cargo install cross --git https://github.com/cross-rs/cross - name: Build binary - run: cross build --release --locked --target ${{ matrix.target }} --bin morph-reth + run: make build-${{ matrix.target }} - name: Package binary run: | diff --git a/Makefile b/Makefile index 0357137..bc2c588 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ install: ## Build and install the morph-reth binary under `$(CARGO_HOME)/bin`. # See: https://github.com/cross-rs/cross/wiki/FAQ#undefined-reference-with-build-std build-%: ## Cross-build morph-reth for a specific target (e.g. build-x86_64-unknown-linux-gnu). RUSTFLAGS="-C link-arg=-lgcc -Clink-arg=-static-libgcc" \ - cross build --bin morph-reth --target $* --profile "$(PROFILE)" + cross build --locked --bin morph-reth --target $* --profile "$(PROFILE)" # aarch64 needs larger jemalloc page size (64KB pages on some ARM systems) build-aarch64-unknown-linux-gnu: export JEMALLOC_SYS_WITH_LG_PAGE=16 From 6371da8bf199d9be35fe2222009e5da87e5eef21 Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 19:12:31 +0800 Subject: [PATCH 06/10] fix(release): add RUSTFLAGS and JEMALLOC env vars inline, keep CI independent of Makefile --- .github/workflows/release.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3f3dc9..fd325d0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -103,7 +103,10 @@ jobs: run: cargo install cross --git https://github.com/cross-rs/cross - name: Build binary - run: make build-${{ matrix.target }} + env: + RUSTFLAGS: "-C link-arg=-lgcc -Clink-arg=-static-libgcc" + JEMALLOC_SYS_WITH_LG_PAGE: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '16' || '' }} + run: cross build --release --locked --target ${{ matrix.target }} --bin morph-reth - name: Package binary run: | From b073bcd261cbd7fb57b5f130860c57f482317814 Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 19:19:38 +0800 Subject: [PATCH 07/10] fix(release): use make build- to align CI with Makefile env vars --- .github/workflows/release.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd325d0..a3f3dc9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -103,10 +103,7 @@ jobs: run: cargo install cross --git https://github.com/cross-rs/cross - name: Build binary - env: - RUSTFLAGS: "-C link-arg=-lgcc -Clink-arg=-static-libgcc" - JEMALLOC_SYS_WITH_LG_PAGE: ${{ matrix.target == 'aarch64-unknown-linux-gnu' && '16' || '' }} - run: cross build --release --locked --target ${{ matrix.target }} --bin morph-reth + run: make build-${{ matrix.target }} - name: Package binary run: | From 1dd13ff37ec26079b28937cbcbe7f45641b8a6ee Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 22:08:07 +0800 Subject: [PATCH 08/10] perf(docker): use cross-compiled binaries instead of QEMU emulation Replace slow QEMU-based multi-arch Docker build (~200min) with cross-compiled binaries + Dockerfile.cross (~15min), matching reth/scroll-reth approach. --- .github/workflows/docker.yml | 30 ++++++++++++++++++++++++++---- Dockerfile.cross | 14 ++++++++++++++ Makefile | 14 ++++++++++++-- 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 Dockerfile.cross diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c42a493..8ef4675 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -20,8 +20,30 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu + + - name: Cache Rust build artifacts + uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + - name: Install cross main + run: cargo install cross --git https://github.com/cross-rs/cross + + - name: Build x86_64 binary + run: make build-x86_64-unknown-linux-gnu + + - name: Build aarch64 binary + run: make build-aarch64-unknown-linux-gnu + + - name: Prepare binaries + run: | + mkdir -p dist/bin/amd64 dist/bin/arm64 + cp target/x86_64-unknown-linux-gnu/release/morph-reth dist/bin/amd64/morph-reth + cp target/aarch64-unknown-linux-gnu/release/morph-reth dist/bin/arm64/morph-reth - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -46,9 +68,9 @@ jobs: uses: docker/build-push-action@v6 with: context: . + file: ./Dockerfile.cross push: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') }} platforms: linux/amd64,linux/arm64 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max + provenance: false diff --git a/Dockerfile.cross b/Dockerfile.cross new file mode 100644 index 0000000..c70c099 --- /dev/null +++ b/Dockerfile.cross @@ -0,0 +1,14 @@ +# Cross-compilation image: assumes the morph-reth binary has already been +# compiled for $TARGETPLATFORM and placed in ./dist/bin/$TARGETARCH/ +FROM --platform=$TARGETPLATFORM ubuntu:22.04 + +LABEL org.opencontainers.image.source=https://github.com/morph-l2/morph-reth +LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0" + +# Filled by docker buildx +ARG TARGETARCH + +COPY ./dist/bin/$TARGETARCH/morph-reth /usr/local/bin/morph-reth + +EXPOSE 8545 8546 8551 30303 30303/udp +ENTRYPOINT ["/usr/local/bin/morph-reth"] diff --git a/Makefile b/Makefile index bc2c588..7d6be40 100644 --- a/Makefile +++ b/Makefile @@ -125,9 +125,19 @@ docker-build-push-latest: ## Build and push a Docker image tagged with the lates docker-build-push-git-sha: ## Build and push a Docker image tagged with the latest git sha. $(call docker_build_push,$(GIT_SHA),$(GIT_SHA)) +# Cross-compile binaries for both platforms, then build a multi-arch image +# using Dockerfile.cross (no QEMU needed). define docker_build_push - docker buildx build --file ./Dockerfile . \ - --platform linux/amd64 \ + $(MAKE) build-x86_64-unknown-linux-gnu + mkdir -p $(BIN_DIR)/amd64 + cp $(CARGO_TARGET_DIR)/x86_64-unknown-linux-gnu/$(PROFILE)/morph-reth $(BIN_DIR)/amd64/morph-reth + + $(MAKE) build-aarch64-unknown-linux-gnu + mkdir -p $(BIN_DIR)/arm64 + cp $(CARGO_TARGET_DIR)/aarch64-unknown-linux-gnu/$(PROFILE)/morph-reth $(BIN_DIR)/arm64/morph-reth + + docker buildx build --file ./Dockerfile.cross . \ + --platform linux/amd64,linux/arm64 \ --tag $(DOCKER_IMAGE_NAME):$(1) \ --tag $(DOCKER_IMAGE_NAME):$(2) \ --provenance=false \ From 7867ee7a22743df1951f4a26f06d6383bc3f8c7b Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 22:21:01 +0800 Subject: [PATCH 09/10] feat(release): add structured release notes template with checklists and binary table --- .github/workflows/release.yml | 44 +++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3f3dc9..56e4c9b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -151,22 +151,58 @@ jobs: else CHANGELOG=$(git log -n 20 --pretty=format:"- %s") fi - # Write to file to avoid escaping issues - echo "$CHANGELOG" > changelog.md + echo "CHANGELOG<> $GITHUB_OUTPUT + echo "$CHANGELOG" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT - name: Create draft release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VERSION: ${{ needs.extract-version.outputs.version }} + REPO_NAME: ${{ github.repository }} run: | - VERSION="${{ needs.extract-version.outputs.version }}" PRERELEASE="" if [[ "$VERSION" == *"alpha"* ]] || [[ "$VERSION" == *"beta"* ]] || [[ "$VERSION" == *"rc"* ]]; then PRERELEASE="--prerelease" fi + + cat < release_notes.md + ## Testing Checklist (DELETE ME) + + - [ ] Run on testnet for 1-3 days. + - [ ] Resync a node from genesis. + - [ ] Ensure all CI checks pass. + + ## Release Checklist (DELETE ME) + + - [ ] Ensure version has been bumped in \`Cargo.toml\`. + - [ ] Write the summary below. + - [ ] Ensure all binaries have been added. + + ## Summary + + + + ## All Changes + + ${{ steps.changelog.outputs.CHANGELOG }} + + ## Binaries + + | System | Architecture | Binary | + |:---:|:---:|:---:| + | | x86_64 | [morph-reth-${VERSION}-x86_64-linux.tar.gz](https://github.com/${REPO_NAME}/releases/download/v${VERSION}/morph-reth-${VERSION}-x86_64-linux.tar.gz) | + | | aarch64 | [morph-reth-${VERSION}-aarch64-linux.tar.gz](https://github.com/${REPO_NAME}/releases/download/v${VERSION}/morph-reth-${VERSION}-aarch64-linux.tar.gz) | + | | Docker | [ghcr.io/morph-l2/morph-reth:v${VERSION}](https://ghcr.io/morph-l2/morph-reth) | + ENDBODY + gh release create "v${VERSION}" \ --verify-tag \ --draft \ --title "v${VERSION}" \ - --notes-file changelog.md \ + --notes-file release_notes.md \ $PRERELEASE \ artifacts/* From e97123ab68ff3fd811c915ccf2c666add5305a9c Mon Sep 17 00:00:00 2001 From: panos Date: Tue, 7 Apr 2026 22:31:15 +0800 Subject: [PATCH 10/10] fix(docker): add non-root user to Dockerfile.cross for runtime isolation --- Dockerfile.cross | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Dockerfile.cross b/Dockerfile.cross index c70c099..ec255f1 100644 --- a/Dockerfile.cross +++ b/Dockerfile.cross @@ -8,7 +8,14 @@ LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0" # Filled by docker buildx ARG TARGETARCH +RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates && \ + useradd --system --create-home --home-dir /var/lib/morph-reth --shell /usr/sbin/nologin morph-reth && \ + rm -rf /var/lib/apt/lists/* + COPY ./dist/bin/$TARGETARCH/morph-reth /usr/local/bin/morph-reth EXPOSE 8545 8546 8551 30303 30303/udp + +WORKDIR /var/lib/morph-reth +USER morph-reth ENTRYPOINT ["/usr/local/bin/morph-reth"]