Skip to content

feat: Add reproducible build profile and Dockerfile #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 17, 2025
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
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
Loading