Skip to content
Open
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
151 changes: 151 additions & 0 deletions .github/workflows/release.yaml
Copy link
Member

Choose a reason for hiding this comment

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

in case it is helpful for you, here is a draft PR where I am adding reproducible debian packaging to lighthouse

Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
name: Release

on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
draft-release:
default: false
description: "Draft Release"
required: false
type: boolean
build-docker:
default: false
description: "Build Docker"
required: false
type: boolean
build-binary:
default: true
description: "Build Binary"
required: false
type: boolean
features:
default: ''
description: "Binary Compilation Features"
options:
- ''
- 'redact-sensitive'
required: false
type: choice

jobs:
extract-version:
name: Extract version
runs-on: warp-ubuntu-2404-x64-2x
outputs:
VERSION: ${{ steps.extract_version.outputs.VERSION }}
steps:
- name: Extract version
id: extract_version
run: |
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
VERSION="${GITHUB_REF#refs/tags/}"
else
VERSION="$(echo ${GITHUB_SHA} | cut -c1-7)"
fi
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
echo "${VERSION}"

echo "### Version: \`${VERSION}\`" >> $GITHUB_STEP_SUMMARY
echo "| | |" >> $GITHUB_STEP_SUMMARY
echo "| ------------------- | ---------------------- |" >> $GITHUB_STEP_SUMMARY
echo "| \`GITHUB_REF_TYPE\` | \`${GITHUB_REF_TYPE}\` |" >> $GITHUB_STEP_SUMMARY
echo "| \`GITHUB_REF_NAME\` | \`${GITHUB_REF_NAME}\` |" >> $GITHUB_STEP_SUMMARY
echo "| \`GITHUB_REF\` | \`${GITHUB_REF}\` |" >> $GITHUB_STEP_SUMMARY
echo "| \`GITHUB_SHA\` | \`${GITHUB_SHA}\` |" >> $GITHUB_STEP_SUMMARY
echo "| \`VERSION\` | \`${VERSION}\` |" >> $GITHUB_STEP_SUMMARY
echo "| \`FEATURES\` | \`${{ github.event.inputs.features || 'none' }}\` |" >> $GITHUB_STEP_SUMMARY

build-binary:
name: Build binary
needs: extract-version
if: ${{ github.event.inputs.build-binary == 'true' || github.event_name == 'push'}} # when manually triggered or version tagged
runs-on: ${{ matrix.configs.runner }}
permissions:
contents: write
packages: write
strategy:
matrix:
configs:
- target: x86_64-unknown-linux-gnu
runner: warp-ubuntu-latest-x64-32x
profile: reproducible
features:
- ${{ github.event.inputs.features || '' }}

steps:
- uses: actions/checkout@v4

- 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)
docker build \
--build-arg "RUST_TOOLCHAIN=${RUST_TOOLCHAIN}" \
--build-arg "FEATURES=${{ matrix.features }}" \
--build-arg "VERSION=${{ needs.extract-version.outputs.VERSION }}" \
-f Dockerfile.build-deb -t atp:release \
--output type=local,dest=./target .

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

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


draft-release:
name: Draft release
if: ${{ github.event.inputs.draft-release == 'true' || github.event_name == 'push'}} # when manually triggered or version tagged
needs: [extract-version, build-binary]
runs-on: warp-ubuntu-2404-x64-16x
env:
VERSION: ${{ needs.extract-version.outputs.VERSION }}
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4

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

- name: Record artifacts checksums
working-directory: artifacts
run: |
find ./ || true
for file in *; do sha256sum "$file" >> sha256sums.txt; done;
cat sha256sums.txt

- name: Create release draft
uses: softprops/[email protected]
id: create-release-draft
with:
draft: true
files: artifacts/*
generate_release_notes: true
name: ${{ env.VERSION }}
tag_name: ${{ env.VERSION }}

- name: Write Github Step Summary
run: |
echo "---"
echo "### Release Draft: ${{ env.VERSION }}" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.create-release-draft.outputs.url }}" >> $GITHUB_STEP_SUMMARY
28 changes: 28 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ members = [".", "dummy-attestation-server"]

[package]
name = "attested-tls-proxy"
description = "An HTTP attested TLS proxy server and client for secure communication with CVM services"
version = "0.1.0"
edition = "2024"
license = "MIT"
repository = "https://github.com/flashbots/attested-tls-proxy"

[dependencies]
tokio = { version = "1.48.0", features = ["full"] }
Expand Down Expand Up @@ -56,3 +58,29 @@ tdx-quote = { version = "0.0.4", features = ["mock"] }
[features]
default = ["azure"]
azure = ["tss-esapi", "az-tdx-vtpm"]

[package.metadata.deb]
maintainer = "Flashbots Team <[email protected]>"
depends = "$auto"
section = "network"
priority = "optional"
maintainer-scripts = "pkg/debian"
assets = [
[
"target/reproducible/attested-tls-proxy",
"usr/bin/",
"755",
],
[
"LICENSE",
"usr/share/doc/attested-tls-proxy/",
"644",
],
]
systemd-units = { enable = false, start = false, unit-name = "attested-tls-proxy" }

[profile.reproducible]
inherits = "release"
lto = "thin"
panic = "abort"
incremental = false
18 changes: 18 additions & 0 deletions Dockerfile.build-deb
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 \
pkg-config clang libclang-dev \
openssl libssl-dev libtss2-dev \
cmake

WORKDIR /build
COPY . .
RUN make build && make build-deb

FROM scratch AS artifacts
COPY --from=builder /build/target/x86_64-unknown-linux-gnu/ /
112 changes: 112 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Heavily inspired by rbuilder: https://github.com/flashbots/rbuilder/blob/develop/Makefile
.DEFAULT_GOAL := help

GIT_VER ?= $(shell git describe --tags --always --dirty="-dev")
GIT_TAG ?= $(shell git describe --tags --abbrev=0)

FEATURES ?=

##@ Help

.PHONY: help
help: ## Display this help.
@awk 'BEGIN {FS = ":.*##"; printf "Usage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

.PHONY: v
v: ## Show the current version
@echo "Version: ${GIT_VER}"

##@ Build

.PHONY: clean
clean: ## Clean up
cargo clean

# Detect the current architecture
ARCH := $(shell uname -m)

# Determine if we're on x86_64
ifeq ($(ARCH),x86_64)
IS_X86_64 = 1
else
IS_X86_64 = 0
endif

# Set build profile and flags based on architecture
ifeq ($(IS_X86_64),1)
# x86_64: Use reproducible profile with reproducible build flags
BUILD_PROFILE = reproducible
BUILD_TARGET = x86_64-unknown-linux-gnu

# Environment variables for reproducible builds
# Initialize RUSTFLAGS
RUST_BUILD_FLAGS =
# Optimize for modern CPUs
RUST_BUILD_FLAGS += -C target-cpu=x86-64-v3
# 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=''
# Remap paths to ensure reproducible builds
RUST_BUILD_FLAGS += --remap-path-prefix $(shell pwd)=.
# Set timestamp from last git commit for reproducible builds
SOURCE_DATE ?= $(shell git log -1 --pretty=%ct)
# Set C locale for consistent string handling and sorting
LOCALE_VAL = C
# Set UTC timezone for consistent time handling across builds
TZ_VAL = UTC

# Environment setup for reproducible builds
BUILD_ENV = SOURCE_DATE_EPOCH=$(SOURCE_DATE) \
RUSTFLAGS="${RUST_BUILD_FLAGS}" \
LC_ALL=${LOCALE_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
BUILD_TARGET =
RUST_BUILD_FLAGS =
BUILD_ENV =
endif

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

.PHONY: build-dev
build-dev: ## Build (debug version)
cargo build --features "$(FEATURES)"

##@ Debian Packages

.PHONY: install-cargo-deb
install-cargo-deb:
@command -v cargo-deb >/dev/null 2>&1 || cargo install [email protected] --locked

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

##@ Dev

.PHONY: lint
lint: ## Run the linters
cargo fmt -- --check
cargo clippy --workspace --features "$(FEATURES)" -- -D warnings

.PHONY: test
test:
cargo test --verbose --features "$(FEATURES)"

.PHONY: lt
lt: lint test ## Run "lint" and "test"

.PHONY: fmt
fmt: ## Format the code
cargo fmt
cargo fix --allow-staged
cargo clippy --features "$(FEATURES)" --fix --allow-staged
14 changes: 14 additions & 0 deletions scripts/check-reproducibility.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash

# Checks reproducibility by running a package build twice and printing hashes of .deb package
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Im not sure to what extent this really shows that the build is reproducible, but its better than nothing


set -euo pipefail

rm -rf /tmp/repro1 /tmp/repro2
mkdir -p /tmp/repro1 /tmp/repro2

docker build -f Dockerfile.build-deb --no-cache --output type=local,dest=/tmp/repro1 .
docker build -f Dockerfile.build-deb --no-cache --output type=local,dest=/tmp/repro2 .

sha256sum /tmp/repro1/debian/*.deb
sha256sum /tmp/repro2/debian/*.deb