Skip to content

Commit 49f5da8

Browse files
committed
Add reproducibility check
1 parent 7e552b4 commit 49f5da8

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

.github/workflows/repro_check.yml

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Workflow that runs after a merge to master, builds toolchain in 2 different
2+
# directories to check for reproducible builds. This check helps track which
3+
# commits cause reproducibility issues. This check should pass before stable
4+
# releases are made.
5+
6+
name: Reproducibility check
7+
8+
on:
9+
push:
10+
branches:
11+
- master
12+
13+
jobs:
14+
build_and_compare:
15+
runs-on: ubuntu-24.04
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
20+
- name: Build and store toolchains
21+
run: |
22+
# Define build function
23+
build_toolchain() {
24+
local dir_name="$1"
25+
echo "Building in $dir_name..."
26+
27+
mkdir "../$dir_name"
28+
cp -r . "../$dir_name/rust"
29+
pushd "../$dir_name"
30+
31+
# Find source directory
32+
SOURCE_DIR="./rust"
33+
34+
# FIXME: Setting channel to nightly because only nightly builds succeed on CI
35+
$SOURCE_DIR/configure --set rust.channel=nightly
36+
37+
# Build rust till stage 2
38+
$SOURCE_DIR/x.py build --stage 2
39+
40+
# Remove copy of source directory to save space
41+
rm -rf "$SOURCE_DIR"
42+
43+
# Save stage2 directory
44+
STAGE2_DIR=$(find build -name stage2)
45+
cp -r "$STAGE2_DIR" .
46+
echo "Contents of stage2 dir in $dir_name: $(ls stage2)"
47+
48+
# Clean up to save space
49+
rm -rf build
50+
popd
51+
}
52+
53+
# Build both
54+
build_toolchain buildA
55+
build_toolchain buildA_extended
56+
57+
# Compare the two builds
58+
- name: Compare builds
59+
id: compare
60+
run: |
61+
# Ensure the directories exist
62+
if [[ ! -d "../buildA" || ! -d "../buildA_extended" ]]; then
63+
echo "Error: Build directories not found!"
64+
exit 1
65+
fi
66+
mv ../buildA ../buildA_extended .
67+
# Perform a recursive diff between the stage2 directories of both builds
68+
# If there are differences, record the result so we can upload artifacts and then fail later
69+
# The binaries should be identical, so the cause of difference should be analysed and fixed
70+
# appropriately.
71+
if diff -r buildA/stage2 buildA_extended/stage2; then
72+
echo "No differences found."
73+
echo "has_diff=false" >> $GITHUB_OUTPUT
74+
else
75+
echo "Differences found!"
76+
echo "has_diff=true" >> $GITHUB_OUTPUT
77+
fi
78+
79+
# Upload buildA and buildA_extended directories as an artifact (for debugging purposes)
80+
# The artifacts contain the stage2 folder from both builds. The artifact are
81+
# helpful to debug the reproducibility issue when this test fails.
82+
- name: Upload buildA artifact
83+
if: steps.compare.outputs.has_diff == 'true'
84+
uses: actions/upload-artifact@v4
85+
with:
86+
name: buildA
87+
path: buildA
88+
89+
- name: Upload buildA_extended artifact
90+
if: steps.compare.outputs.has_diff == 'true'
91+
uses: actions/upload-artifact@v4
92+
with:
93+
name: buildA_extended
94+
path: buildA_extended
95+
96+
# Fail the job if differences were found between the builds
97+
- name: Fail the job if there are differences
98+
if: steps.compare.outputs.has_diff == 'true'
99+
run: |
100+
echo "Differences found between buildA and buildA_extended, Reproducibility check failed"
101+
exit 1

0 commit comments

Comments
 (0)