Skip to content
Draft
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
183 changes: 183 additions & 0 deletions .github/workflows/repro.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---
name: Reproducible Build Verification
on:
schedule:
- cron: "0 0 * * *" # Daily at midnight UTC
pull_request:
types: [opened, synchronize]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
build-base-image:
name: Build jammy Docker Image
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Build base image
run: |
echo "Building base image for jammy"
docker run --rm -v $(pwd):/build ubuntu:jammy \
bash -c "apt-get update && apt-get install -y debootstrap && debootstrap jammy /build/jammy"
tar -C jammy -c . | docker import - jammy
echo "Verifying jammy base image:"
docker run jammy cat /etc/lsb-release

- name: Build builder image
run: |
echo "Building CL repro jammy:"
docker build -t cl-repro-jammy - < contrib/reprobuild/Dockerfile.jammy

- name: Save Docker image
run: |
mkdir -p docker-images
docker save cl-repro-jammy | gzip > docker-images/cl-repro-jammy.tar.gz

- name: Upload Docker image
uses: actions/upload-artifact@v4
with:
name: docker-images
path: docker-images/
retention-days: 1

build-ubuntu:
name: Build CLN on Ubuntu
runs-on: ubuntu-latest
timeout-minutes: 120
needs: build-base-image
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download Docker image
uses: actions/download-artifact@v4
with:
name: docker-images
path: docker-images/

- name: Load Docker image
run: |
docker load --input docker-images/cl-repro-jammy.tar.gz

- name: Create release directory
run: |
mkdir -p release

- name: Build with jammy
run: |
docker run --rm -v $(pwd):/repo cl-repro-jammy bash -c "git clone /repo . && uv sync --all-extras --all-groups && uv run tools/repro-build.sh --force-mtime=2000-01-01 && cp *.xz /repo/release/"


- name: Generate checksums
run: |
cd release
sha256sum *.xz > SHA256SUMS-ubuntu
cat SHA256SUMS-ubuntu

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ubuntu-artifacts
path: release/
retention-days: 1

build-debian:
name: Build CLN on Debian
runs-on: debian-latest
timeout-minutes: 120
needs: build-base-image
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download Docker image
uses: actions/download-artifact@v4
with:
name: docker-images
path: docker-images/

- name: Load Docker image
run: |
docker load --input docker-images/cl-repro-jammy.tar.gz

- name: Create release directory
run: |
mkdir -p release

- name: Build with jammy
run: |
docker run --rm -v $(pwd):/repo cl-repro-jammy bash -c "git clone /repo . && uv sync --all-extras --all-groups && uv run tools/repro-build.sh --force-mtime=2000-01-01 && cp *.xz /repo/release/"

- name: Generate checksums
run: |
cd release
sha256sum *.xz > SHA256SUMS-debian
cat SHA256SUMS-debian

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: debian-artifacts
path: release/
retention-days: 1

verify-reproducibility:
name: Verify Reproducibility
runs-on: ubuntu-latest
timeout-minutes: 10
needs: [build-ubuntu, build-debian]
if: always()
steps:
- name: Download Ubuntu artifacts
uses: actions/download-artifact@v4
with:
name: ubuntu-artifacts
path: ubuntu-release/

- name: Download Debian artifacts
uses: actions/download-artifact@v4
with:
name: debian-artifacts
path: debian-release/

- name: Compare artifacts
run: |
echo "=== Ubuntu checksums ==="
cat ubuntu-release/SHA256SUMS-ubuntu || echo "Ubuntu checksums not found"
echo ""
echo "=== Debian checksums ==="
cat debian-release/SHA256SUMS-debian || echo "Debian checksums not found"
echo ""
echo "=== Comparing binary reproducibility ==="

# Extract just the hashes and filenames for comparison
if [ -f ubuntu-release/SHA256SUMS-ubuntu ] && [ -f debian-release/SHA256SUMS-debian ]; then
# Get just the hash and filename parts, sort them for comparison
ubuntu_hashes=$(grep -v SHA256SUMS ubuntu-release/SHA256SUMS-ubuntu | sort || true)
debian_hashes=$(grep -v SHA256SUMS debian-release/SHA256SUMS-debian | sort || true)

if [ -z "$ubuntu_hashes" ] || [ -z "$debian_hashes" ]; then
echo "Checksums are empty, builds may have failed"
exit 1
fi

# Compare the hashes
if diff <(echo "$ubuntu_hashes") <(echo "$debian_hashes"); then
echo "✓ Builds are reproducible! Checksums match between Ubuntu and Debian runners."
exit 0
else
echo "✗ Builds are NOT reproducible. Checksums differ between Ubuntu and Debian runners."
exit 1
fi
else
echo "Could not find checksum files from both builds"
exit 1
fi
113 changes: 0 additions & 113 deletions .github/workflows/repro.yml

This file was deleted.

7 changes: 7 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[submodule "daemon/jsmn"]
path = external/jsmn
url = https://github.com/zserge/jsmn
[submodule "libsodium"]
path = external/libsodium
url = https://github.com/jedisct1/libsodium.git
[submodule "external/libbacktrace"]
path = external/libbacktrace
url = https://github.com/ianlancetaylor/libbacktrace.git
Expand All @@ -11,3 +14,7 @@
[submodule "external/gheap"]
path = external/gheap
url = https://github.com/valyala/gheap
[submodule "external/lowdown"]
path = external/lowdown
url = https://github.com/kristapsdz/lowdown.git
ignore = dirty
8 changes: 3 additions & 5 deletions contrib/reprobuild/Dockerfile.focal
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@ RUN apt-get update \
unzip \
wget \
git \
zip

# Ensure correct ownership
RUN chown root:root /etc/sudoers
RUN chown root:root /usr/lib/sudo/sudoers.so
zip \
&& rm -rf /var/cache/apt/archives /var/lib/apt/lists/*.
RUN echo "ALL ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers

# Download and install jq from official repository
RUN wget -O /usr/local/bin/jq https://github.com/jqlang/jq/releases/download/jq-1.6/jq-linux64 \
Expand Down
11 changes: 6 additions & 5 deletions contrib/reprobuild/Dockerfile.jammy
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ RUN apt-get update \
libsodium23 \
libtool \
m4 \
sudo \
unzip \
wget \
jq \
zip

# Ensure correct ownership
RUN chown root:root /etc/sudoers
RUN chown root:root /etc/sudo.conf
RUN chown root:root /usr/libexec/sudo/sudoers.so
RUN printf 'root ALL=(ALL) ALL\n%%sudo ALL=(ALL) ALL\n' > /etc/sudoers && \
chmod 0440 /etc/sudoers

# Since we're running as root, create a sudo wrapper that's a no-op
RUN printf '#!/bin/sh\nexec "$@"\n' > /usr/local/bin/sudo && \
chmod +x /usr/local/bin/sudo

# Install Python3.10 (more reproducible than relying on python3-setuptools)
RUN git clone https://github.com/pyenv/pyenv.git /root/.pyenv && \
Expand Down
Loading