Skip to content

Explore adding a reproducibility test to rust test infrastructure. #139793

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
101 changes: 101 additions & 0 deletions .github/workflows/repro_check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Workflow that runs after a merge to master, builds toolchain in 2 different
# directories to check for reproducible builds. This check helps track which
# commits cause reproducibility issues. This check should pass before stable
# releases are made.

name: Reproducibility check

on:
push:
branches:
- master

jobs:
build_and_compare:
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Build and store toolchains
run: |
# Define build function
build_toolchain() {
local dir_name="$1"
echo "Building in $dir_name..."

mkdir "../$dir_name"
cp -r . "../$dir_name/rust"
pushd "../$dir_name"

# Find source directory
SOURCE_DIR="./rust"

# FIXME: Setting channel to nightly because only nightly builds succeed on CI
$SOURCE_DIR/configure --set rust.channel=nightly

# Build rust till stage 2
$SOURCE_DIR/x.py build --stage 2

# Remove copy of source directory to save space
rm -rf "$SOURCE_DIR"

# Save stage2 directory
STAGE2_DIR=$(find build -name stage2)
cp -r "$STAGE2_DIR" .
echo "Contents of stage2 dir in $dir_name: $(ls stage2)"

# Clean up to save space
rm -rf build
popd
}

# Build both
build_toolchain buildA
build_toolchain buildA_extended

# Compare the two builds
- name: Compare builds
id: compare
run: |
# Ensure the directories exist
if [[ ! -d "../buildA" || ! -d "../buildA_extended" ]]; then
echo "Error: Build directories not found!"
exit 1
fi
mv ../buildA ../buildA_extended .
# Perform a recursive diff between the stage2 directories of both builds
# If there are differences, record the result so we can upload artifacts and then fail later
# The binaries should be identical, so the cause of difference should be analysed and fixed
# appropriately.
if diff -r buildA/stage2 buildA_extended/stage2; then
echo "No differences found."
echo "has_diff=false" >> $GITHUB_OUTPUT
else
echo "Differences found!"
echo "has_diff=true" >> $GITHUB_OUTPUT
fi

# Upload buildA and buildA_extended directories as an artifact (for debugging purposes)
# The artifacts contain the stage2 folder from both builds. The artifact are
# helpful to debug the reproducibility issue when this test fails.
- name: Upload buildA artifact
if: steps.compare.outputs.has_diff == 'true'
uses: actions/upload-artifact@v4
with:
name: buildA
path: buildA

- name: Upload buildA_extended artifact
if: steps.compare.outputs.has_diff == 'true'
uses: actions/upload-artifact@v4
with:
name: buildA_extended
path: buildA_extended

# Fail the job if differences were found between the builds
- name: Fail the job if there are differences
if: steps.compare.outputs.has_diff == 'true'
run: |
echo "Differences found between buildA and buildA_extended, Reproducibility check failed"
exit 1
Loading