Skip to content
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
target/
.git/
.github/
.claude/
.worktrees/
.config/
local-test/
tests/
*.md
deny.toml
typos.toml
.editorconfig
.gitignore
56 changes: 56 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Docker

on:
push:
tags: ["v*"]
workflow_dispatch:
Comment thread
coderabbitai[bot] marked this conversation as resolved.

permissions:
contents: read
packages: write

env:
IMAGE_NAME: ghcr.io/morph-l2/morph-reth

jobs:
build-push:
name: Build and Push
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

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

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=
type=raw,value=latest,enable=${{ !contains(github.ref, '-') }}

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
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
174 changes: 174 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
name: Release

on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
tag:
description: "Tag to release (e.g., v0.1.0)"
required: true
dry_run:
description: "Dry run (skip release creation)"
type: boolean
default: true

permissions:
contents: read

env:
CARGO_TERM_COLOR: always

jobs:
extract-version:
name: Extract Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
ref: ${{ steps.version.outputs.ref }}
steps:
- name: Determine tag
id: version
run: |
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
TAG="${{ inputs.tag }}"
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$ ]]; then
echo "::error::Invalid tag format: '$TAG'. Expected format like v0.1.0 or v0.1.0-rc.1"
exit 1
fi
REF="refs/tags/${TAG}"
else
TAG="${GITHUB_REF#refs/tags/}"
REF="${GITHUB_REF}"
fi
VERSION="${TAG#v}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "ref=$REF" >> "$GITHUB_OUTPUT"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
echo "Extracted version: $VERSION"
Comment thread
coderabbitai[bot] marked this conversation as resolved.

check-version:
name: Check Version
runs-on: ubuntu-latest
needs: extract-version
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ needs.extract-version.outputs.ref }}
persist-credentials: false

- name: Verify Cargo.toml version matches tag
run: |
CARGO_VERSION=$(cargo metadata --format-version 1 --no-deps \
| jq -r '.packages[] | select(.name == "morph-reth") | .version')
TAG_VERSION="${{ needs.extract-version.outputs.version }}"
echo "Cargo.toml version: $CARGO_VERSION"
echo "Tag version: $TAG_VERSION"
if [[ "$TAG_VERSION" != "$CARGO_VERSION"* ]]; then
echo "::error::Tag version ($TAG_VERSION) does not match Cargo.toml version ($CARGO_VERSION)"
exit 1
fi

build:
name: Build ${{ matrix.target }}
runs-on: ubuntu-latest
needs: [extract-version, check-version]
if: ${{ !cancelled() && needs.check-version.result == 'success' }}
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
archive: morph-reth-${{ needs.extract-version.outputs.version }}-x86_64-linux
- target: aarch64-unknown-linux-gnu
archive: morph-reth-${{ needs.extract-version.outputs.version }}-aarch64-linux
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ needs.extract-version.outputs.ref }}
persist-credentials: false

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Cache Rust build artifacts
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
key: ${{ matrix.target }}

- name: Install cross
uses: taiki-e/install-action@v2
with:
tool: cross

- name: Build binary
run: cross build --release --locked --target ${{ matrix.target }} --bin morph-reth

- name: Package binary
run: |
mkdir -p dist
cp target/${{ matrix.target }}/release/morph-reth dist/
cd dist
tar czf ../${{ matrix.archive }}.tar.gz morph-reth
cd ..
sha256sum ${{ matrix.archive }}.tar.gz > ${{ matrix.archive }}.tar.gz.sha256

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.archive }}
path: |
${{ matrix.archive }}.tar.gz
${{ matrix.archive }}.tar.gz.sha256

draft-release:
name: Draft Release
runs-on: ubuntu-latest
needs: [extract-version, build]
if: ${{ !(github.event_name == 'workflow_dispatch' && inputs.dry_run) }}
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ needs.extract-version.outputs.ref }}
fetch-depth: 0

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
merge-multiple: true
path: artifacts

- name: Generate changelog
id: changelog
run: |
PREVIOUS_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
if [[ -n "$PREVIOUS_TAG" ]]; then
CHANGELOG=$(git log --pretty=format:"- %s" ${PREVIOUS_TAG}..HEAD)
else
CHANGELOG=$(git log -n 20 --pretty=format:"- %s")
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Write to file to avoid escaping issues
echo "$CHANGELOG" > changelog.md

- name: Create draft release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ needs.extract-version.outputs.version }}"
PRERELEASE=""
if [[ "$VERSION" == *"alpha"* ]] || [[ "$VERSION" == *"beta"* ]] || [[ "$VERSION" == *"rc"* ]]; then
PRERELEASE="--prerelease"
fi
gh release create "v${VERSION}" \
--verify-tag \
--draft \
--title "v${VERSION}" \
--notes-file changelog.md \
$PRERELEASE \
artifacts/*
51 changes: 51 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
FROM lukemathwalker/cargo-chef:latest-rust-1 AS chef
WORKDIR /app

# reth-mdbx-sys requires libclang for bindgen
RUN apt-get update && \
apt-get install -y --no-install-recommends libclang-dev pkg-config && \
rm -rf /var/lib/apt/lists/*

# Generate dependency recipe
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json

# Build dependencies + application
FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json

# Build profile, release by default
ARG BUILD_PROFILE=release
ENV BUILD_PROFILE=$BUILD_PROFILE

# Extra Cargo flags
ARG RUSTFLAGS=""
ENV RUSTFLAGS="$RUSTFLAGS"

# Build dependencies (cached layer)
RUN cargo chef cook --profile $BUILD_PROFILE --recipe-path recipe.json

# Build the application
COPY . .
RUN cargo build --profile $BUILD_PROFILE --locked --bin morph-reth

# Copy binary to a fixed location (ARG not resolved in COPY)
RUN cp /app/target/$BUILD_PROFILE/morph-reth /app/morph-reth

# Minimal runtime image
FROM debian:bookworm-slim AS runtime

LABEL org.opencontainers.image.source=https://github.com/morph-l2/morph-reth
LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0"
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 --from=builder /app/morph-reth /usr/local/bin/

EXPOSE 8545 8546 8551 30303 30303/udp

WORKDIR /var/lib/morph-reth
USER morph-reth
ENTRYPOINT ["/usr/local/bin/morph-reth"]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Loading