mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-02 16:21:42 +00:00
This pull request introduces workflows and updates to ensure reproducible builds for the Lighthouse project. It adds two GitHub Actions workflows for building and testing reproducible Docker images and binaries, updates the `Makefile` to streamline reproducible build configurations, and modifies the `Dockerfile.reproducible` to align with the new build process. Additionally, it removes the `reproducible` profile from `Cargo.toml`. ### New GitHub Actions Workflows: * [`.github/workflows/docker-reproducible.yml`](diffhunk://#diff-222af23bee616920b04f5b92a83eb5106fce08abd885cd3a3b15b8beb5e789c3R1-R145): Adds a workflow to build and push reproducible multi-architecture Docker images for releases, including support for dry runs without pushing an image. ### Build Configuration Updates: * [`Makefile`](diffhunk://#diff-76ed074a9305c04054cdebb9e9aad2d818052b07091de1f20cad0bbac34ffb52L85-R143): Refactors reproducible build targets, centralizes environment variables for reproducibility, and updates Docker build arguments for `x86_64` and `aarch64` architectures. * [`Dockerfile.reproducible`](diffhunk://#diff-587298ff141278ce3be7c54a559f9f31472cc5b384e285e2105b3dee319ba31dL1-R24): Updates the base Rust image to version 1.86, removes hardcoded reproducibility settings, and delegates build logic to the `Makefile`. * Switch to using jemalloc-sys from Debian repos instead of building it from source. A Debian version is [reproducible](https://tests.reproducible-builds.org/debian/rb-pkg/trixie/amd64/jemalloc.html) which is [hard to achieve](https://github.com/NixOS/nixpkgs/issues/380852) if you build it from source. ### Profile Removal: * [`Cargo.toml`](diffhunk://#diff-2e9d962a08321605940b5a657135052fbcef87b5e360662bb527c96d9a615542L289-L295): Removes the `reproducible` profile, simplifying build configurations and relying on external tooling for reproducibility. Co-Authored-By: Moe Mahhouk <mohammed-mahhouk@hotmail.com> Co-Authored-By: chonghe <44791194+chong-he@users.noreply.github.com> Co-Authored-By: Michael Sproul <michaelsproul@users.noreply.github.com>
177 lines
6.6 KiB
YAML
177 lines
6.6 KiB
YAML
name: docker-reproducible
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- unstable
|
|
- stable
|
|
tags:
|
|
- v*
|
|
workflow_dispatch: # allows manual triggering for testing purposes and skips publishing an image
|
|
|
|
env:
|
|
DOCKER_REPRODUCIBLE_IMAGE_NAME: >-
|
|
${{ github.repository_owner }}/lighthouse-reproducible
|
|
DOCKER_PASSWORD: ${{ secrets.DH_KEY }}
|
|
DOCKER_USERNAME: ${{ secrets.DH_ORG }}
|
|
|
|
jobs:
|
|
extract-version:
|
|
name: extract version
|
|
runs-on: ubuntu-22.04
|
|
steps:
|
|
- name: Extract version
|
|
run: |
|
|
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
|
# It's a tag (e.g., v1.2.3)
|
|
VERSION="${GITHUB_REF#refs/tags/}"
|
|
elif [[ "${{ github.ref }}" == refs/heads/stable ]]; then
|
|
# stable branch -> latest
|
|
VERSION="latest"
|
|
elif [[ "${{ github.ref }}" == refs/heads/unstable ]]; then
|
|
# unstable branch -> latest-unstable
|
|
VERSION="latest-unstable"
|
|
else
|
|
# For manual triggers from other branches and will not publish any image
|
|
VERSION="test-build"
|
|
fi
|
|
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
|
|
id: extract_version
|
|
outputs:
|
|
VERSION: ${{ steps.extract_version.outputs.VERSION }}
|
|
|
|
verify-and-build:
|
|
name: verify reproducibility and build
|
|
needs: extract-version
|
|
strategy:
|
|
matrix:
|
|
arch: [amd64, arm64]
|
|
include:
|
|
- arch: amd64
|
|
rust_target: x86_64-unknown-linux-gnu
|
|
rust_image: >-
|
|
rust:1.88-bullseye@sha256:8e3c421122bf4cd3b2a866af41a4dd52d87ad9e315fd2cb5100e87a7187a9816
|
|
platform: linux/amd64
|
|
runner: ubuntu-22.04
|
|
- arch: arm64
|
|
rust_target: aarch64-unknown-linux-gnu
|
|
rust_image: >-
|
|
rust:1.88-bullseye@sha256:8b22455a7ce2adb1355067638284ee99d21cc516fab63a96c4514beaf370aa94
|
|
platform: linux/arm64
|
|
runner: ubuntu-22.04-arm
|
|
runs-on: ${{ matrix.runner }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
with:
|
|
driver: docker
|
|
|
|
- name: Verify reproducible builds (${{ matrix.arch }})
|
|
run: |
|
|
# Build first image
|
|
docker build -f Dockerfile.reproducible \
|
|
--platform ${{ matrix.platform }} \
|
|
--build-arg RUST_TARGET="${{ matrix.rust_target }}" \
|
|
--build-arg RUST_IMAGE="${{ matrix.rust_image }}" \
|
|
-t lighthouse-verify-1-${{ matrix.arch }} .
|
|
|
|
# Extract binary from first build
|
|
docker create --name extract-1-${{ matrix.arch }} lighthouse-verify-1-${{ matrix.arch }}
|
|
docker cp extract-1-${{ matrix.arch }}:/lighthouse ./lighthouse-1-${{ matrix.arch }}
|
|
docker rm extract-1-${{ matrix.arch }}
|
|
|
|
# Clean state for second build
|
|
docker buildx prune -f
|
|
docker system prune -f
|
|
|
|
# Build second image
|
|
docker build -f Dockerfile.reproducible \
|
|
--platform ${{ matrix.platform }} \
|
|
--build-arg RUST_TARGET="${{ matrix.rust_target }}" \
|
|
--build-arg RUST_IMAGE="${{ matrix.rust_image }}" \
|
|
-t lighthouse-verify-2-${{ matrix.arch }} .
|
|
|
|
# Extract binary from second build
|
|
docker create --name extract-2-${{ matrix.arch }} lighthouse-verify-2-${{ matrix.arch }}
|
|
docker cp extract-2-${{ matrix.arch }}:/lighthouse ./lighthouse-2-${{ matrix.arch }}
|
|
docker rm extract-2-${{ matrix.arch }}
|
|
|
|
# Compare binaries
|
|
echo "=== Comparing binaries ==="
|
|
echo "Build 1 SHA256: $(sha256sum lighthouse-1-${{ matrix.arch }})"
|
|
echo "Build 2 SHA256: $(sha256sum lighthouse-2-${{ matrix.arch }})"
|
|
|
|
if cmp lighthouse-1-${{ matrix.arch }} lighthouse-2-${{ matrix.arch }}; then
|
|
echo "Reproducible build verified for ${{ matrix.arch }}"
|
|
else
|
|
echo "Reproducible build FAILED for ${{ matrix.arch }}"
|
|
echo "BLOCKING RELEASE: Builds are not reproducible!"
|
|
echo "First 10 differences:"
|
|
cmp -l lighthouse-1-${{ matrix.arch }} lighthouse-2-${{ matrix.arch }} | head -10
|
|
exit 1
|
|
fi
|
|
|
|
# Clean up verification artifacts but keep one image for publishing
|
|
rm -f lighthouse-*-${{ matrix.arch }}
|
|
docker rmi lighthouse-verify-1-${{ matrix.arch }} || true
|
|
|
|
# Re-tag the second image for publishing (we verified it's identical to first)
|
|
VERSION=${{ needs.extract-version.outputs.VERSION }}
|
|
FINAL_TAG="${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}"
|
|
docker tag lighthouse-verify-2-${{ matrix.arch }} "$FINAL_TAG"
|
|
|
|
- name: Log in to Docker Hub
|
|
if: ${{ github.event_name != 'workflow_dispatch' }}
|
|
uses: docker/login-action@v3
|
|
with:
|
|
username: ${{ env.DOCKER_USERNAME }}
|
|
password: ${{ env.DOCKER_PASSWORD }}
|
|
|
|
- name: Push verified image (${{ matrix.arch }})
|
|
if: ${{ github.event_name != 'workflow_dispatch' }}
|
|
run: |
|
|
VERSION=${{ needs.extract-version.outputs.VERSION }}
|
|
IMAGE_TAG="${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}"
|
|
docker push "$IMAGE_TAG"
|
|
|
|
- name: Clean up local images
|
|
run: |
|
|
docker rmi lighthouse-verify-2-${{ matrix.arch }} || true
|
|
VERSION=${{ needs.extract-version.outputs.VERSION }}
|
|
docker rmi "${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}:${VERSION}-${{ matrix.arch }}" || true
|
|
|
|
- name: Upload verification artifacts (on failure)
|
|
if: failure()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: verification-failure-${{ matrix.arch }}
|
|
path: |
|
|
lighthouse-*-${{ matrix.arch }}
|
|
|
|
create-manifest:
|
|
name: create multi-arch manifest
|
|
runs-on: ubuntu-22.04
|
|
needs: [extract-version, verify-and-build]
|
|
if: ${{ github.event_name != 'workflow_dispatch' }}
|
|
steps:
|
|
- name: Log in to Docker Hub
|
|
uses: docker/login-action@v3
|
|
with:
|
|
username: ${{ env.DOCKER_USERNAME }}
|
|
password: ${{ env.DOCKER_PASSWORD }}
|
|
|
|
- name: Create and push multi-arch manifest
|
|
run: |
|
|
IMAGE_NAME=${{ env.DOCKER_REPRODUCIBLE_IMAGE_NAME }}
|
|
VERSION=${{ needs.extract-version.outputs.VERSION }}
|
|
|
|
# Create manifest for the version tag
|
|
docker manifest create \
|
|
${IMAGE_NAME}:${VERSION} \
|
|
${IMAGE_NAME}:${VERSION}-amd64 \
|
|
${IMAGE_NAME}:${VERSION}-arm64
|
|
|
|
docker manifest push ${IMAGE_NAME}:${VERSION}
|