Skip to content

Commit

Permalink
feat: Add reproducible build profile and Dockerfile (#42)
Browse files Browse the repository at this point in the history
* feat: Add reproducible build profile and Dockerfile

* remove the extra Cargo.toml profiles

* Add comments to the rust flags

* feat: add extra job for the reproducible docker build in the CI (#43)

* feat: add extra job for the reproducible docker build in the CI

* remove the extra Cargo.toml profiles

* add comments to the rust flags and move them into Makefile

* Add comments to the rust flags

* refactor the comments position

* chore: re-use the build logic and setup from the makefile

* remove unnecessary flags

* Revert "remove unnecessary flags"

This reverts commit 1977afb.

* remove static linking of libgcc
  • Loading branch information
MoeMahhouk authored Jan 17, 2025
1 parent 774438f commit 260b67e
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 1 deletion.
63 changes: 62 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ on:
required: false
type: boolean
default: true
build-docker:
description: 'Build Docker'
required: false
type: boolean
default: true
draft-release:
description: 'Draft Release'
required: false
Expand Down Expand Up @@ -79,6 +84,8 @@ jobs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
- uses: actions/checkout@v4 # must install git before checkout and set safe.directory after checkout because of container
with:
fetch-depth: 0

- name: Prepare filename
run: echo "OUTPUT_FILENAME=rbuilder-${VERSION}-${{ matrix.configs.target }}" >> $GITHUB_ENV
Expand All @@ -87,7 +94,7 @@ jobs:
run: |
git config --global --add safe.directory "$(pwd)"
. $HOME/.cargo/env
cargo build --release --target ${{ matrix.configs.target }}
make build-reproducible TARGET=${{ matrix.configs.target }}
./target/${{ matrix.configs.target }}/release/rbuilder version
- name: Upload artifact
Expand All @@ -96,6 +103,60 @@ jobs:
name: ${{ env.OUTPUT_FILENAME }}
path: target/${{ matrix.configs.target }}/release/rbuilder

build-docker:
name: Build and publish Docker image
if: ${{ github.event.inputs.build-docker == 'true' || github.event_name == 'push'}}
needs: extract-version
runs-on: warp-ubuntu-latest-x64-16x
env:
VERSION: ${{ needs.extract-version.outputs.VERSION }}
permissions:
contents: read
packages: write

steps:
- name: Checkout sources
uses: actions/checkout@v4
with:
fetch-depth: 0

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

- name: Docker metadata
uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
labels: org.opencontainers.image.source=${{ github.repositoryUrl }}
tags: |
type=sha
type=semver,pattern={{version}},value=${{ env.VERSION }}
type=semver,pattern={{major}}.{{minor}},value=${{ env.VERSION }}
type=semver,pattern={{major}},value=${{ env.VERSION }}
type=raw,value=latest,enable=${{ !contains(env.VERSION, '-') }}
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64
provenance: false
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BUILD_PROFILE=release
draft-release:
name: Draft release
if: ${{ github.event.inputs.draft-release == 'true' || github.event_name == 'push'}} # when manually triggered or version tagged
Expand Down
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM rust:1.82-bullseye@sha256:c42c8ca762560c182ba30edda0e0d71a8604040af2672370559d7e854653c66d AS builder

ARG BUILD_PROFILE=release
ENV BUILD_PROFILE=$BUILD_PROFILE

RUN apt-get update && apt-get install -y \
libclang-dev=1:11.0-51+nmu5 \
protobuf-compiler=3.12.4-1+deb11u1

# Clone the repository at the specific branch
WORKDIR /app
COPY ./ /app

# Build the project with the reproducible settings
RUN make build-reproducible

RUN mv /app/target/x86_64-unknown-linux-gnu/"${BUILD_PROFILE}"/rbuilder /rbuilder

FROM gcr.io/distroless/cc-debian12:nonroot-6755e21ccd99ddead6edc8106ba03888cbeed41a
COPY --from=builder /rbuilder /rbuilder
ENTRYPOINT [ "/rbuilder" ]
35 changes: 35 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,41 @@ clean: ## Clean up
build: ## Build static binary for x86_64
cargo build --release --target x86_64-unknown-linux-gnu

# Environment variables for reproducible builds
# Initialize RUSTFLAGS
RUST_BUILD_FLAGS =

# Remove build ID from the binary to ensure reproducibility across builds
RUST_BUILD_FLAGS += -C link-arg=-Wl,--build-id=none

# Remove metadata hash from symbol names to ensure reproducible builds
RUST_BUILD_FLAGS += -C metadata=''

# Set timestamp from last git commit for reproducible builds
SOURCE_DATE ?= $(shell git log -1 --pretty=%ct)

# Disable incremental compilation to avoid non-deterministic artifacts
CARGO_INCREMENTAL_VAL = 0

# Set C locale for consistent string handling and sorting
LOCALE_VAL = C

# Set UTC timezone for consistent time handling across builds
TZ_VAL = UTC

# Set the target for the build, default to x86_64
TARGET ?= x86_64-unknown-linux-gnu

.PHONY: build-reproducible
build-reproducible: ## Build reproducible static binary for x86_64
# Set timestamp from last git commit for reproducible builds
SOURCE_DATE_EPOCH=$(SOURCE_DATE) \
RUSTFLAGS="${RUST_BUILD_FLAGS} --remap-path-prefix $$(pwd)=." \
CARGO_INCREMENTAL=${CARGO_INCREMENTAL_VAL} \
LC_ALL=${LOCALE_VAL} \
TZ=${TZ_VAL} \
cargo build --release --locked --target $(TARGET)

.PHONY: docker-image
docker-image: ## Build a rbuilder Docker image
docker build --platform linux/amd64 . -t rbuilder
Expand Down

0 comments on commit 260b67e

Please sign in to comment.